mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-08-18 06:55:48 +03:00
Merge with dev
--HG-- branch : dev-css
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
#include <eepp/audio/inputsoundfile.hpp>
|
||||
#include <eepp/system/mutex.hpp>
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <eepp/system/safedatapointer.hpp>
|
||||
#include <eepp/system/scopedbuffer.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -239,7 +239,7 @@ class EE_API Music : public SoundStream
|
||||
std::vector<Int16> mSamples; ///< Temporary buffer of samples
|
||||
Mutex mMutex; ///< Mutex protecting the data
|
||||
Span<Uint64> mLoopSpan; ///< Loop Range Specifier
|
||||
SafeDataPointer mData;
|
||||
ScopedBuffer mData;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -86,7 +86,7 @@ class EE_API FontTrueType : public Font {
|
||||
void* mStreamRec; ///< Pointer to the stream rec instance (it is typeless to avoid exposing implementation details)
|
||||
void* mStroker; ///< Pointer to the stroker (it is typeless to avoid exposing implementation details)
|
||||
int* mRefCount; ///< Reference counter used by implicit sharing
|
||||
SafeDataPointer mMemCopy;
|
||||
mutable ScopedBuffer mMemCopy; ///< If loaded from memory, this is the file copy in memory
|
||||
Font::Info mInfo; ///< Information about the font
|
||||
mutable PageTable mPages; ///< Table containing the glyphs pages by character size
|
||||
mutable std::vector<Uint8> mPixelBuffer; ///< Pixel buffer holding a glyph's pixels before being written to the texture
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef EE_MATH_BASE
|
||||
#define EE_MATH_BASE
|
||||
|
||||
#include <eepp/core.hpp>
|
||||
#include <eepp/math/ease.hpp>
|
||||
|
||||
#endif
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef EE_MATHCINTERPOLATION_H
|
||||
#define EE_MATHCINTERPOLATION_H
|
||||
|
||||
#include <eepp/math/base.hpp>
|
||||
#include <eepp/core.hpp>
|
||||
#include <eepp/math/ease.hpp>
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef EE_MATHCWAYPOINTS_H
|
||||
#define EE_MATHCWAYPOINTS_H
|
||||
|
||||
#include <eepp/math/base.hpp>
|
||||
#include <eepp/core.hpp>
|
||||
#include <eepp/math/ease.hpp>
|
||||
#include <eepp/math/vector2.hpp>
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <vector>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <eepp/system/thread.hpp>
|
||||
#include <eepp/system/mutex.hpp>
|
||||
#include <eepp/system/lock.hpp>
|
||||
#include <eepp/thirdparty/PlusCallback/callback.hpp>
|
||||
#include <eepp/network/uri.hpp>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <list>
|
||||
@@ -26,6 +26,121 @@ namespace EE { namespace Network {
|
||||
/** @brief A HTTP client */
|
||||
class EE_API Http : NonCopyable {
|
||||
public :
|
||||
/** @brief Define a HTTP response */
|
||||
class EE_API Response {
|
||||
public:
|
||||
|
||||
// Types
|
||||
typedef std::map<std::string, std::string> FieldTable;
|
||||
|
||||
/** @brief Enumerate all the valid status codes for a response */
|
||||
enum Status {
|
||||
// 2xx: success
|
||||
Ok = 200, ///< Most common code returned when operation was successful
|
||||
Created = 201, ///< The resource has successfully been created
|
||||
Accepted = 202, ///< The request has been accepted, but will be processed later by the server
|
||||
NoContent = 204, ///< The server didn't send any data in return
|
||||
ResetContent = 205, ///< The server informs the client that it should clear the view (form) that caused the request to be sent
|
||||
PartialContent = 206, ///< The server has sent a part of the resource, as a response to a partial GET request
|
||||
|
||||
// 3xx: redirection
|
||||
MultipleChoices = 300, ///< The requested page can be accessed from several locations
|
||||
MovedPermanently = 301, ///< The requested page has permanently moved to a new location
|
||||
MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location
|
||||
NotModified = 304, ///< For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed
|
||||
|
||||
// 4xx: client error
|
||||
BadRequest = 400, ///< The server couldn't understand the request (syntax error)
|
||||
Unauthorized = 401, ///< The requested page needs an authentification to be accessed
|
||||
Forbidden = 403, ///< The requested page cannot be accessed at all, even with authentification
|
||||
NotFound = 404, ///< The requested page doesn't exist
|
||||
RangeNotSatisfiable = 407, ///< The server can't satisfy the partial GET request (with a "Range" header field)
|
||||
|
||||
// 5xx: server error
|
||||
InternalServerError = 500, ///< The server encountered an unexpected error
|
||||
NotImplemented = 501, ///< The server doesn't implement a requested feature
|
||||
BadGateway = 502, ///< The gateway server has received an error from the source server
|
||||
ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)
|
||||
GatewayTimeout = 504, ///< The gateway server couldn't receive a response from the source server
|
||||
VersionNotSupported = 505, ///< The server doesn't support the requested HTTP version
|
||||
|
||||
// 10xx: Custom codes
|
||||
InvalidResponse = 1000, ///< Response is not a valid HTTP one
|
||||
ConnectionFailed = 1001 ///< Connection with server failed
|
||||
};
|
||||
|
||||
/** @return The status string */
|
||||
static const char * statusToString( const Status& status );
|
||||
|
||||
/** @brief Default constructor
|
||||
** Constructs an empty response. */
|
||||
Response();
|
||||
|
||||
FieldTable getHeaders();
|
||||
|
||||
/** @brief Get the value of a field
|
||||
** If the field @a field is not found in the response header,
|
||||
** the empty string is returned. This function uses
|
||||
** case-insensitive comparisons.
|
||||
** @param field Name of the field to get
|
||||
** @return Value of the field, or empty string if not found */
|
||||
const std::string& getField(const std::string& field) const;
|
||||
|
||||
/** @return If the field is found in the response headers. */
|
||||
bool hasField(const std::string& field) const;
|
||||
|
||||
/** @brief Get the response status code
|
||||
** The status code should be the first thing to be checked
|
||||
** after receiving a response, it defines whether it is a
|
||||
** success, a failure or anything else (see the Status
|
||||
** enumeration).
|
||||
** @return Status code of the response */
|
||||
Status getStatus() const;
|
||||
|
||||
/** @brief Get the response status description */
|
||||
const char * getStatusDescription() const;
|
||||
|
||||
/** @brief Get the major HTTP version number of the response
|
||||
** @return Major HTTP version number
|
||||
** @see GetMinorHttpVersion */
|
||||
unsigned int getMajorHttpVersion() const;
|
||||
|
||||
/** @brief Get the minor HTTP version number of the response
|
||||
** @return Minor HTTP version number
|
||||
** @see GetMajorHttpVersion */
|
||||
unsigned int getMinorHttpVersion() const;
|
||||
|
||||
/** @brief Get the body of the response
|
||||
** The body of a response may contain:
|
||||
** @li the requested page (for GET requests)
|
||||
** @li a response from the server (for POST requests)
|
||||
** @li nothing (for HEAD requests)
|
||||
** @li an error message (in case of an error)
|
||||
** @return The response body */
|
||||
const std::string& getBody() const;
|
||||
private :
|
||||
friend class Http;
|
||||
|
||||
/** @brief Construct the header from a response string
|
||||
** This function is used by Http to build the response
|
||||
** of a request.
|
||||
** @param data Content of the response to parse */
|
||||
void parse(const std::string& data);
|
||||
|
||||
/** @brief Read values passed in the answer header
|
||||
** This function is used by Http to extract values passed
|
||||
** in the response.
|
||||
** @param in String stream containing the header values */
|
||||
void parseFields(std::istream &in);
|
||||
|
||||
// Member data
|
||||
FieldTable mFields; ///< Fields of the header
|
||||
Status mStatus; ///< Status code
|
||||
unsigned int mMajorVersion; ///< Major HTTP version
|
||||
unsigned int mMinorVersion; ///< Minor HTTP version
|
||||
std::string mBody; ///< Body of the response
|
||||
};
|
||||
|
||||
/** @brief Define a HTTP request */
|
||||
class EE_API Request {
|
||||
public :
|
||||
@@ -37,9 +152,24 @@ class EE_API Http : NonCopyable {
|
||||
Put, ///< The PUT method replaces all current representations of the target resource with the request payload.
|
||||
Delete, ///< The DELETE method deletes the specified resource.
|
||||
Options, ///< The OPTIONS method is used to describe the communication options for the target resource.
|
||||
Patch ///< The PATCH method is used to apply partial modifications to a resource.
|
||||
Patch, ///< The PATCH method is used to apply partial modifications to a resource.
|
||||
Connect ///< The CONNECT method starts two-way communications with the requested resource. It can be used to open a tunnel.
|
||||
};
|
||||
|
||||
/** @brief Enumerate the available states for a request */
|
||||
enum Status {
|
||||
Connected, ///< Connected to server.
|
||||
Sent, ///< Request sent to the server.
|
||||
HeaderReceived, ///< Header received.
|
||||
ContentReceived ///< Content received.
|
||||
};
|
||||
|
||||
/** @return Method from a method name string. */
|
||||
static Method methodFromString( std::string methodString );
|
||||
|
||||
/** @return The method string from a method */
|
||||
static std::string methodToString( const Method& method );
|
||||
|
||||
/** @brief Default constructor
|
||||
** This constructor creates a GET request, with the root
|
||||
** URI ("/") and an empty body.
|
||||
@@ -49,8 +179,9 @@ class EE_API Http : NonCopyable {
|
||||
** @param validateCertificate Enables certificate validation for https request
|
||||
** @param validateHostname Enables hostname validation for https request
|
||||
** @param followRedirect Allow follor redirects to the request.
|
||||
** @param compressedResponse Set if the requested response should be compressed ( if available )
|
||||
*/
|
||||
Request(const std::string& uri = "/", Method method = Get, const std::string& body = "", bool validateCertificate = true, bool validateHostname = true, bool followRedirect = true);
|
||||
Request(const std::string& uri = "/", Method method = Get, const std::string& body = "", bool validateCertificate = true, bool validateHostname = true, bool followRedirect = true, bool compressedResponse = false);
|
||||
|
||||
/** @brief Set the value of a field
|
||||
** The field is created if it doesn't exist. The name of
|
||||
@@ -62,6 +193,20 @@ class EE_API Http : NonCopyable {
|
||||
** @param value Value of the field */
|
||||
void setField(const std::string& field, const std::string& value);
|
||||
|
||||
/** @brief Check if the request defines a field
|
||||
** This function uses case-insensitive comparisons.
|
||||
** @param field Name of the field to test
|
||||
** @return True if the field exists, false otherwise */
|
||||
bool hasField(const std::string& field) const;
|
||||
|
||||
/** @brief Get the value of a field
|
||||
** If the field @a field is not found in the response header,
|
||||
** the empty string is returned. This function uses
|
||||
** case-insensitive comparisons.
|
||||
** @param field Name of the field to get
|
||||
** @return Value of the field, or empty string if not found */
|
||||
const std::string& getField(const std::string& field) const;
|
||||
|
||||
/** @brief Set the request method
|
||||
** See the Method enumeration for a complete list of all
|
||||
** the availale methods.
|
||||
@@ -109,141 +254,82 @@ class EE_API Http : NonCopyable {
|
||||
|
||||
/** Enables/Disables follow redirects */
|
||||
void setFollowRedirect( bool follow );
|
||||
private:
|
||||
|
||||
/** @return The maximun number of redirects allowd if follow redirect is enabled. */
|
||||
const unsigned int& getMaxRedirects() const;
|
||||
|
||||
/** Set the maximun number of redirects allowed if follow redirect is enabled. */
|
||||
void setMaxRedirects( unsigned int maxRedirects );
|
||||
|
||||
/** Definition of the current progress callback
|
||||
* @param http The http client
|
||||
* @param request The http request
|
||||
* @param status The status of the progress event
|
||||
* @param totalBytes The total bytes of the document / files ( only available if Content-Length is returned, otherwise is 0 )
|
||||
* @param currentBytes Current received total bytes
|
||||
* @return True if continue the request, false will cancel the current request.
|
||||
*/
|
||||
typedef std::function<bool( const Http& http, const Http::Request& request, const Http::Response& response, const Status& status, std::size_t totalBytes, std::size_t currentBytes )> ProgressCallback;
|
||||
|
||||
/** Sets a progress callback */
|
||||
void setProgressCallback( const ProgressCallback& progressCallback );
|
||||
|
||||
/** Get the progress callback */
|
||||
const ProgressCallback& getProgressCallback() const;
|
||||
|
||||
/** Cancels the current request if being processed */
|
||||
void cancel();
|
||||
|
||||
/** @return True if the current request was cancelled */
|
||||
const bool& isCancelled() const;
|
||||
|
||||
/** @return If requests a compressed response */
|
||||
const bool& isCompressedResponse() const;
|
||||
|
||||
/** Set to request a compressed response from the server
|
||||
** The returned response will be automatically decompressed
|
||||
** by the client.
|
||||
*/
|
||||
void setCompressedResponse(const bool& compressedResponse);
|
||||
|
||||
/** Resumes download if a file is already present */
|
||||
void setContinue(const bool& resume);
|
||||
|
||||
/** @return If must continue a download previously started. */
|
||||
const bool& isContinue() const;
|
||||
|
||||
private:
|
||||
friend class Http;
|
||||
|
||||
/** @brief Prepare the final request to send to the server
|
||||
** This is used internally by Http before sending the
|
||||
** request to the web server.
|
||||
** @return String containing the request, ready to be sent */
|
||||
std::string prepare() const;
|
||||
std::string prepare(const Http& http) const;
|
||||
|
||||
/** @brief Check if the request defines a field
|
||||
** This function uses case-insensitive comparisons.
|
||||
** @param field Name of the field to test
|
||||
** @return True if the field exists, false otherwise */
|
||||
bool hasField(const std::string& field) const;
|
||||
/** Prepares a http tunnel request */
|
||||
std::string prepareTunnel(const Http& http);
|
||||
|
||||
// Types
|
||||
typedef std::map<std::string, std::string> FieldTable;
|
||||
|
||||
// Member data
|
||||
FieldTable mFields; ///< Fields of the header associated to their value
|
||||
Method mMethod; ///< Method to use for the request
|
||||
std::string mUri; ///< Target URI of the request
|
||||
unsigned int mMajorVersion; ///< Major HTTP version
|
||||
unsigned int mMinorVersion; ///< Minor HTTP version
|
||||
std::string mBody; ///< Body of the request
|
||||
bool mValidateCertificate; ///< Validates the SSL certificate in case of an HTTPS request
|
||||
bool mValidateHostname; ///< Validates the hostname in case of an HTTPS request
|
||||
bool mFollowRedirect; ///< Follows redirect response codes
|
||||
unsigned int mRedirectionCount; ///< Number of redirections followed by the request
|
||||
};
|
||||
|
||||
/** @brief Define a HTTP response */
|
||||
class EE_API Response {
|
||||
public:
|
||||
|
||||
// Types
|
||||
typedef std::map<std::string, std::string> FieldTable;
|
||||
|
||||
/** @brief Enumerate all the valid status codes for a response */
|
||||
enum Status {
|
||||
// 2xx: success
|
||||
Ok = 200, ///< Most common code returned when operation was successful
|
||||
Created = 201, ///< The resource has successfully been created
|
||||
Accepted = 202, ///< The request has been accepted, but will be processed later by the server
|
||||
NoContent = 204, ///< The server didn't send any data in return
|
||||
ResetContent = 205, ///< The server informs the client that it should clear the view (form) that caused the request to be sent
|
||||
PartialContent = 206, ///< The server has sent a part of the resource, as a response to a partial GET request
|
||||
|
||||
// 3xx: redirection
|
||||
MultipleChoices = 300, ///< The requested page can be accessed from several locations
|
||||
MovedPermanently = 301, ///< The requested page has permanently moved to a new location
|
||||
MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location
|
||||
NotModified = 304, ///< For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed
|
||||
|
||||
// 4xx: client error
|
||||
BadRequest = 400, ///< The server couldn't understand the request (syntax error)
|
||||
Unauthorized = 401, ///< The requested page needs an authentification to be accessed
|
||||
Forbidden = 403, ///< The requested page cannot be accessed at all, even with authentification
|
||||
NotFound = 404, ///< The requested page doesn't exist
|
||||
RangeNotSatisfiable = 407, ///< The server can't satisfy the partial GET request (with a "Range" header field)
|
||||
|
||||
// 5xx: server error
|
||||
InternalServerError = 500, ///< The server encountered an unexpected error
|
||||
NotImplemented = 501, ///< The server doesn't implement a requested feature
|
||||
BadGateway = 502, ///< The gateway server has received an error from the source server
|
||||
ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)
|
||||
GatewayTimeout = 504, ///< The gateway server couldn't receive a response from the source server
|
||||
VersionNotSupported = 505, ///< The server doesn't support the requested HTTP version
|
||||
|
||||
// 10xx: Custom codes
|
||||
InvalidResponse = 1000, ///< Response is not a valid HTTP one
|
||||
ConnectionFailed = 1001 ///< Connection with server failed
|
||||
};
|
||||
|
||||
/** @brief Default constructor
|
||||
** Constructs an empty response. */
|
||||
Response();
|
||||
|
||||
FieldTable getHeaders();
|
||||
|
||||
/** @brief Get the value of a field
|
||||
** If the field @a field is not found in the response header,
|
||||
** the empty string is returned. This function uses
|
||||
** case-insensitive comparisons.
|
||||
** @param field Name of the field to get
|
||||
** @return Value of the field, or empty string if not found */
|
||||
const std::string& getField(const std::string& field) const;
|
||||
|
||||
/** @brief Get the response status code
|
||||
** The status code should be the first thing to be checked
|
||||
** after receiving a response, it defines whether it is a
|
||||
** success, a failure or anything else (see the Status
|
||||
** enumeration).
|
||||
** @return Status code of the response */
|
||||
Status getStatus() const;
|
||||
|
||||
/** @brief Get the major HTTP version number of the response
|
||||
** @return Major HTTP version number
|
||||
** @see GetMinorHttpVersion */
|
||||
unsigned int getMajorHttpVersion() const;
|
||||
|
||||
/** @brief Get the minor HTTP version number of the response
|
||||
** @return Minor HTTP version number
|
||||
** @see GetMajorHttpVersion */
|
||||
unsigned int getMinorHttpVersion() const;
|
||||
|
||||
/** @brief Get the body of the response
|
||||
** The body of a response may contain:
|
||||
** @li the requested page (for GET requests)
|
||||
** @li a response from the server (for POST requests)
|
||||
** @li nothing (for HEAD requests)
|
||||
** @li an error message (in case of an error)
|
||||
** @return The response body */
|
||||
const std::string& getBody() const;
|
||||
private :
|
||||
friend class Http;
|
||||
|
||||
/** @brief Construct the header from a response string
|
||||
** This function is used by Http to build the response
|
||||
** of a request.
|
||||
** @param data Content of the response to parse */
|
||||
void parse(const std::string& data);
|
||||
|
||||
/** @brief Read values passed in the answer header
|
||||
** This function is used by Http to extract values passed
|
||||
** in the response.
|
||||
** @param in String stream containing the header values */
|
||||
void parseFields(std::istream &in);
|
||||
|
||||
// Member data
|
||||
FieldTable mFields; ///< Fields of the header
|
||||
Status mStatus; ///< Status code
|
||||
unsigned int mMajorVersion; ///< Major HTTP version
|
||||
unsigned int mMinorVersion; ///< Minor HTTP version
|
||||
std::string mBody; ///< Body of the response
|
||||
FieldTable mFields; ///< Fields of the header associated to their value
|
||||
Method mMethod; ///< Method to use for the request
|
||||
std::string mUri; ///< Target URI of the request
|
||||
unsigned int mMajorVersion; ///< Major HTTP version
|
||||
unsigned int mMinorVersion; ///< Minor HTTP version
|
||||
std::string mBody; ///< Body of the request
|
||||
bool mValidateCertificate; ///< Validates the SSL certificate in case of an HTTPS request
|
||||
bool mValidateHostname; ///< Validates the hostname in case of an HTTPS request
|
||||
bool mFollowRedirect; ///< Follows redirect response codes
|
||||
bool mCompressedResponse; ///< Request comrpessed response
|
||||
bool mContinue; ///< Resume download
|
||||
mutable bool mCancel; ///< Cancel state of current request
|
||||
ProgressCallback mProgressCallback; ///< Progress callback
|
||||
unsigned int mMaxRedirections; ///< Maximun number of redirections allowed
|
||||
mutable unsigned int mRedirectionCount; ///< Number of redirections followed by the request
|
||||
URI mProxy; ///< Proxy information
|
||||
};
|
||||
|
||||
/** @brief Default constructor */
|
||||
@@ -258,8 +344,10 @@ class EE_API Http : NonCopyable {
|
||||
** than the standard one, or use an unknown protocol.
|
||||
** @param host Web server to connect to
|
||||
** @param port Port to use for connection
|
||||
** @param useSSL force the SSL usage ( if compiled with the support of it ). If the host starts with https:// it will use it by default. */
|
||||
Http(const std::string& host, unsigned short port = 0, bool useSSL = false);
|
||||
** @param useSSL force the SSL usage ( if compiled with the support of it ). If the host starts with https:// it will use it by default.
|
||||
** @param proxy Set an http proxy for the host connection
|
||||
*/
|
||||
Http(const std::string& host, unsigned short port = 0, bool useSSL = false, URI proxy = URI());
|
||||
|
||||
~Http();
|
||||
|
||||
@@ -273,8 +361,10 @@ class EE_API Http : NonCopyable {
|
||||
** than the standard one, or use an unknown protocol.
|
||||
** @param host Web server to connect to
|
||||
** @param port Port to use for connection
|
||||
** @param useSSL force the SSL usage ( if compiled with the support of it ). If the host starts with https:// it will use it by default. */
|
||||
void setHost(const std::string& host, unsigned short port = 0, bool useSSL = false);
|
||||
** @param useSSL force the SSL usage ( if compiled with the support of it ). If the host starts with https:// it will use it by default.
|
||||
** @param proxy Set an http proxy for the host connection
|
||||
*/
|
||||
void setHost(const std::string& host, unsigned short port = 0, bool useSSL = false, URI proxy = URI());
|
||||
|
||||
/** @brief Send a HTTP request and return the server's response.
|
||||
** You must have a valid host before sending a request (see setHost).
|
||||
@@ -344,6 +434,21 @@ class EE_API Http : NonCopyable {
|
||||
|
||||
/** @return The host port */
|
||||
const unsigned short& getPort() const;
|
||||
|
||||
/** @return If the HTTP client uses SSL/TLS */
|
||||
const bool& isSSL() const;
|
||||
|
||||
/** @return The URI from the schema + hostname + port */
|
||||
URI getURI() const;
|
||||
|
||||
/** Sets the request proxy */
|
||||
void setProxy( const URI& uri );
|
||||
|
||||
/** @return The request proxy */
|
||||
const URI& getProxy() const;
|
||||
|
||||
/** @return Is a proxy is need to be used */
|
||||
bool isProxied() const;
|
||||
private:
|
||||
class AsyncRequest : public Thread {
|
||||
public:
|
||||
@@ -367,14 +472,53 @@ class EE_API Http : NonCopyable {
|
||||
bool mStreamOwned;
|
||||
IOStream * mStream;
|
||||
};
|
||||
|
||||
class HttpConnection {
|
||||
public:
|
||||
HttpConnection();
|
||||
|
||||
HttpConnection( TcpSocket * socket );
|
||||
|
||||
~HttpConnection();
|
||||
|
||||
void setSocket( TcpSocket * socket );
|
||||
|
||||
TcpSocket * getSocket() const;
|
||||
|
||||
void disconnect();
|
||||
|
||||
const bool& isConnected() const;
|
||||
|
||||
void setConnected( const bool& connected );
|
||||
|
||||
const bool& isTunneled() const;
|
||||
|
||||
void setTunneled( const bool& tunneled );
|
||||
|
||||
const bool& isSSL() const;
|
||||
|
||||
void setSSL( const bool& ssl );
|
||||
|
||||
const bool& isKeepAlive() const;
|
||||
|
||||
void setKeepAlive( const bool& isKeepAlive );
|
||||
protected:
|
||||
TcpSocket * mSocket;
|
||||
bool mIsConnected;
|
||||
bool mIsTunneled;
|
||||
bool mIsSSL;
|
||||
bool mIsKeepAlive;
|
||||
};
|
||||
|
||||
friend class AsyncRequest;
|
||||
ThreadLocalPtr<TcpSocket> mConnection; ///< Connection to the host
|
||||
ThreadLocalPtr<HttpConnection> mConnection; ///< Connection to the host
|
||||
IpAddress mHost; ///< Web host address
|
||||
std::string mHostName; ///< Web host name
|
||||
unsigned short mPort; ///< Port used for connection with host
|
||||
std::list<AsyncRequest*> mThreads;
|
||||
Mutex mThreadsMutex;
|
||||
bool mIsSSL;
|
||||
URI mProxy;
|
||||
|
||||
void removeOldThreads();
|
||||
|
||||
|
||||
@@ -48,8 +48,7 @@ class EE_API Socket : NonCopyable {
|
||||
bool isBlocking() const;
|
||||
protected :
|
||||
/** @brief Types of protocols that the socket can use */
|
||||
enum Type
|
||||
{
|
||||
enum Type {
|
||||
Tcp, ///< TCP protocol
|
||||
Udp ///< UDP protocol
|
||||
};
|
||||
|
||||
@@ -36,15 +36,22 @@ class EE_API SSLSocket : public TcpSocket {
|
||||
|
||||
Status receive(Packet& packet);
|
||||
|
||||
Status sslConnect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout = Time::Zero);
|
||||
|
||||
void sslDisconnect();
|
||||
|
||||
Status tcpConnect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout = Time::Zero);
|
||||
|
||||
void tcpDisconnect();
|
||||
|
||||
Status tcpReceive(void* data, std::size_t size, std::size_t& received);
|
||||
|
||||
Status tcpSend(const void* data, std::size_t size, std::size_t& sent);
|
||||
protected:
|
||||
friend class SSLSocketImpl;
|
||||
friend class OpenSSLSocket;
|
||||
friend class MbedTLSSocket;
|
||||
|
||||
Status tcp_receive(void* data, std::size_t size, std::size_t& received);
|
||||
|
||||
Status tcp_send(const void* data, std::size_t size, std::size_t& sent);
|
||||
|
||||
SSLSocketImpl * mImpl;
|
||||
std::string mHostName;
|
||||
bool mValidateCertificate;
|
||||
|
||||
@@ -113,6 +113,14 @@ class EE_API TcpSocket : public Socket {
|
||||
** @see Send */
|
||||
virtual Status receive(Packet& packet);
|
||||
|
||||
/** Set the send timeout. Only callable after connect ( after the socket
|
||||
** has been initialized ). */
|
||||
void setSendTimeout(SocketHandle sock, const Time& timeout);
|
||||
|
||||
/** Set the receive timeout Only callable after connect ( after the socket
|
||||
** has been initialized ). */
|
||||
void setReceiveTimeout(SocketHandle sock, const Time& timeout);
|
||||
|
||||
private:
|
||||
|
||||
friend class TcpListener;
|
||||
|
||||
@@ -98,6 +98,14 @@ class EE_API UdpSocket : public Socket {
|
||||
** @return Status code
|
||||
** @see Send */
|
||||
Status receive(Packet& packet, IpAddress& remoteAddress, unsigned short& remotePort);
|
||||
|
||||
/** Set the send timeout. Only callable after bind ( after the socket
|
||||
** has been initialized ). */
|
||||
void setSendTimeout(SocketHandle sock, const Time& timeout);
|
||||
|
||||
/** Set the receive timeout Only callable after bind ( after the socket
|
||||
** has been initialized ). */
|
||||
void setReceiveTimeout(SocketHandle sock, const Time& timeout);
|
||||
private:
|
||||
// Member data
|
||||
std::vector<char> mBuffer; ///< Temporary buffer holding the received data in Receive(Packet)
|
||||
|
||||
@@ -213,6 +213,9 @@ class EE_API URI {
|
||||
/** Places the single path segments (delimited by slashes) into the given vector. */
|
||||
void getPathSegments(std::vector<std::string>& segments);
|
||||
|
||||
/** @return The last path segment if any */
|
||||
std::string getLastPathSegment();
|
||||
|
||||
/** URI-encodes the given string by escaping reserved and non-ASCII
|
||||
* characters. The encoded string is appended to encodedStr. */
|
||||
static void encode(const std::string& str, const std::string& reserved, std::string& encodedStr);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <eepp/system/packmanager.hpp>
|
||||
#include <eepp/system/threadlocal.hpp>
|
||||
#include <eepp/system/threadlocalptr.hpp>
|
||||
#include <eepp/system/compression.hpp>
|
||||
#include <eepp/system/base64.hpp>
|
||||
#include <eepp/system/md5.hpp>
|
||||
#include <eepp/system/translator.hpp>
|
||||
@@ -32,6 +33,9 @@
|
||||
#include <eepp/system/iostreamfile.hpp>
|
||||
#include <eepp/system/iostreamzip.hpp>
|
||||
#include <eepp/system/iostreampak.hpp>
|
||||
#include <eepp/system/iostreamstring.hpp>
|
||||
#include <eepp/system/iostreaminflate.hpp>
|
||||
#include <eepp/system/iostreamdeflate.hpp>
|
||||
#include <eepp/system/virtualfilesystem.hpp>
|
||||
|
||||
#endif
|
||||
|
||||
55
include/eepp/system/compression.hpp
Normal file
55
include/eepp/system/compression.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef EE_SYSTEM_COMPRESSION_HPP
|
||||
#define EE_SYSTEM_COMPRESSION_HPP
|
||||
|
||||
#include <eepp/config.hpp>
|
||||
#include <eepp/system/iostream.hpp>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
class Compression {
|
||||
public:
|
||||
enum Mode {
|
||||
MODE_DEFLATE,
|
||||
MODE_GZIP
|
||||
};
|
||||
|
||||
enum Status {
|
||||
OK = 0,
|
||||
ERRNO = -1,
|
||||
STREAM_ERROR = -2,
|
||||
DATA_ERROR = -3,
|
||||
MEM_ERROR = -4,
|
||||
BUF_ERROR = -5,
|
||||
VERSION_ERROR = -6
|
||||
};
|
||||
|
||||
struct ZlibConfig {
|
||||
int level= -1;
|
||||
};
|
||||
|
||||
struct GzipConfig {
|
||||
int level = -1;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
Config() {}
|
||||
ZlibConfig zlib;
|
||||
GzipConfig gzip;
|
||||
};
|
||||
|
||||
static Status compress(Uint8* dst, Uint64 dstMaxSize, const Uint8* src, Uint64 srcSize, Mode mode = MODE_DEFLATE, const Config& config = Config());
|
||||
|
||||
static Status compress(IOStream& dst, IOStream& src, Mode mode = MODE_DEFLATE, const Config& config = Config());
|
||||
|
||||
static int getMaxCompressedBufferSize(Uint64 srcSize, Mode mode = MODE_DEFLATE, const Config& config = Config());
|
||||
|
||||
static Status decompress(Uint8* dst, Uint64 dstMaxSize, const Uint8* src, Uint64 srcSize, Mode mode = MODE_DEFLATE);
|
||||
|
||||
static Status decompress(IOStream& dst, IOStream& src, Mode mode = MODE_DEFLATE);
|
||||
|
||||
static std::size_t getModeDefaultChunkSize( const Mode& mode );
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // EE_SYSTEM_COMPRESSION_HPP
|
||||
@@ -52,7 +52,7 @@ class EE_API DirectoryPack : public Pack {
|
||||
bool extractFileToMemory( const std::string& path, std::vector<Uint8>& data );
|
||||
|
||||
/** Extract a file to memory from the pakFile */
|
||||
bool extractFileToMemory( const std::string& path, SafeDataPointer& data );
|
||||
bool extractFileToMemory( const std::string& path, ScopedBuffer& data );
|
||||
|
||||
/** Check if a file exists in the pack file and return the number of the file, otherwise return -1. */
|
||||
Int32 exists( const std::string& path );
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <eepp/core.hpp>
|
||||
#include <eepp/system/safedatapointer.hpp>
|
||||
#include <eepp/system/scopedbuffer.hpp>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
@@ -25,10 +25,10 @@ class EE_API FileSystem {
|
||||
|
||||
/** Copy a file to memory
|
||||
* @param path The file path
|
||||
* @param data A SafeDataPointer to allocate the data to memory
|
||||
* @return True if returned the file to the SafeDataPointer
|
||||
* @param data A ScopedBuffer to allocate the data to memory
|
||||
* @return True if returned the file to the ScopedBuffer
|
||||
*/
|
||||
static bool fileGet( const std::string& path, SafeDataPointer& data );
|
||||
static bool fileGet( const std::string& path, ScopedBuffer& data );
|
||||
|
||||
/** Copy a file to location.
|
||||
* @param src Source File Path
|
||||
@@ -110,6 +110,13 @@ class EE_API FileSystem {
|
||||
|
||||
/** @return Returns free disk space for a given path in bytes */
|
||||
static Int64 getDiskFreeSpace(const std::string& path);
|
||||
|
||||
/** Creates a file name available for the directory path.
|
||||
* @example For file name "file-name-" will search the first available name
|
||||
* in the file system starting from file-name-1, file-name-2, and so on.
|
||||
* @return The file name found, otherwise empty string if error.
|
||||
*/
|
||||
static std::string fileGetNumberedFileNameFromPath( std::string directoryPath, const std::string& fileName, const std::string& separator = ".", const std::string& fileExtension = "" );
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
49
include/eepp/system/iostreamdeflate.hpp
Normal file
49
include/eepp/system/iostreamdeflate.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#ifndef EE_SYSTEM_IOSTREAMDEFLATE_HPP
|
||||
#define EE_SYSTEM_IOSTREAMDEFLATE_HPP
|
||||
|
||||
#include <eepp/system/iostream.hpp>
|
||||
#include <eepp/system/scopedbuffer.hpp>
|
||||
#include <eepp/system/compression.hpp>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
struct LocalStreamData;
|
||||
|
||||
/** @brief Implementation of a deflating stream */
|
||||
class EE_API IOStreamDeflate : public IOStream {
|
||||
public:
|
||||
static IOStreamDeflate * New( IOStream& inOutStream, Compression::Mode mode, const Compression::Config& config = Compression::Config() );
|
||||
|
||||
/** @brief Use a stream as a input or output buffer
|
||||
** @param inOutStream Stream where the results will ve loaded or saved.
|
||||
** It must be used only for reading or writing, can't mix both calls.
|
||||
** @param mode Compression method used
|
||||
** @param config Compression configuration
|
||||
*/
|
||||
IOStreamDeflate( IOStream& inOutStream, Compression::Mode mode, const Compression::Config& config = Compression::Config() );
|
||||
|
||||
virtual ~IOStreamDeflate();
|
||||
|
||||
virtual ios_size read( char * data, ios_size size );
|
||||
|
||||
virtual ios_size write( const char * data, ios_size size );
|
||||
|
||||
virtual ios_size seek( ios_size position );
|
||||
|
||||
virtual ios_size tell();
|
||||
|
||||
virtual ios_size getSize();
|
||||
|
||||
virtual bool isOpen();
|
||||
|
||||
const Compression::Mode& getMode() const;
|
||||
protected:
|
||||
IOStream& mStream;
|
||||
Compression::Mode mMode;
|
||||
ScopedBuffer mBuffer;
|
||||
LocalStreamData * mLocalStream;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // EE_SYSTEM_IOSTREAMDEFLATE_HPP
|
||||
@@ -33,6 +33,8 @@ class EE_API IOStreamFile : public IOStream {
|
||||
/** @brief Synchronizes the buffer associated with the stream to its controlled output sequence.
|
||||
** This effectively means that all unwritten characters in the buffer are written to its controlled output sequence as soon as possible. */
|
||||
void flush();
|
||||
|
||||
void close();
|
||||
protected:
|
||||
std::FILE* mFS;
|
||||
ios_size mSize;
|
||||
|
||||
48
include/eepp/system/iostreaminflate.hpp
Normal file
48
include/eepp/system/iostreaminflate.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef EE_SYSTEM_IOSTREAMINFLATE_HPP
|
||||
#define EE_SYSTEM_IOSTREAMINFLATE_HPP
|
||||
|
||||
#include <eepp/system/iostream.hpp>
|
||||
#include <eepp/system/scopedbuffer.hpp>
|
||||
#include <eepp/system/compression.hpp>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
struct LocalStreamData;
|
||||
|
||||
/** @brief Implementation of a inflating stream */
|
||||
class EE_API IOStreamInflate : public IOStream {
|
||||
public:
|
||||
static IOStreamInflate * New( IOStream& inOutStream, Compression::Mode mode );
|
||||
|
||||
/** @brief Use a stream as a input or output buffer
|
||||
** @param inOutStream Stream where the results will ve loaded or saved.
|
||||
** It must be used only for reading or writing, can't mix both calls.
|
||||
** @param mode Compression/Decompression method used
|
||||
*/
|
||||
IOStreamInflate( IOStream& inOutStream, Compression::Mode mode );
|
||||
|
||||
virtual ~IOStreamInflate();
|
||||
|
||||
virtual ios_size read( char * data, ios_size size );
|
||||
|
||||
virtual ios_size write( const char * data, ios_size size );
|
||||
|
||||
virtual ios_size seek( ios_size position );
|
||||
|
||||
virtual ios_size tell();
|
||||
|
||||
virtual ios_size getSize();
|
||||
|
||||
virtual bool isOpen();
|
||||
|
||||
const Compression::Mode& getMode() const;
|
||||
protected:
|
||||
IOStream& mStream;
|
||||
Compression::Mode mMode;
|
||||
ScopedBuffer mBuffer;
|
||||
LocalStreamData * mLocalStream;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // EE_SYSTEM_IOSTREAMINFLATE_HPP
|
||||
44
include/eepp/system/iostreamstring.hpp
Normal file
44
include/eepp/system/iostreamstring.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef EE_SYSTEM_IOSTREAMSTRING_HPP
|
||||
#define EE_SYSTEM_IOSTREAMSTRING_HPP
|
||||
|
||||
#include <eepp/system/iostream.hpp>
|
||||
#include <cstring>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
/** @brief Implementation of a memory stream file using an std::string as a container */
|
||||
class EE_API IOStreamString : public IOStream {
|
||||
public:
|
||||
IOStreamString();
|
||||
|
||||
virtual ios_size read( char * data, ios_size size );
|
||||
|
||||
virtual ios_size write( const char * data, ios_size size );
|
||||
|
||||
virtual ios_size write( const std::string& string );
|
||||
|
||||
virtual ios_size seek( ios_size position );
|
||||
|
||||
virtual ios_size tell();
|
||||
|
||||
virtual ios_size getSize();
|
||||
|
||||
virtual bool isOpen();
|
||||
|
||||
void clear();
|
||||
|
||||
/** @return Pointer to the current position in the stream */
|
||||
const char * getPositionPointer();
|
||||
|
||||
/** @return The pointer to the beggining of the stream */
|
||||
const char * getStreamPointer() const;
|
||||
|
||||
const std::string& getStream() const;
|
||||
protected:
|
||||
std::string mStream;
|
||||
ios_size mPos;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif // EE_SYSTEM_IOSTREAMSTRING_HPP
|
||||
@@ -2,7 +2,7 @@
|
||||
#define EE_SYSTEMCPACK_HPP
|
||||
|
||||
#include <eepp/system/mutex.hpp>
|
||||
#include <eepp/system/safedatapointer.hpp>
|
||||
#include <eepp/system/scopedbuffer.hpp>
|
||||
#include <eepp/system/iostream.hpp>
|
||||
|
||||
namespace EE { namespace System {
|
||||
@@ -52,7 +52,7 @@ class EE_API Pack : protected Mutex {
|
||||
virtual bool extractFileToMemory( const std::string& path, std::vector<Uint8>& data ) = 0;
|
||||
|
||||
/** Extract a file to memory from the pack file */
|
||||
virtual bool extractFileToMemory( const std::string& path, SafeDataPointer& data ) = 0;
|
||||
virtual bool extractFileToMemory( const std::string& path, ScopedBuffer& data ) = 0;
|
||||
|
||||
/** Check if a file exists in the pack file and return the number of the file, otherwise return -1. */
|
||||
virtual Int32 exists( const std::string& path ) = 0;
|
||||
|
||||
@@ -53,7 +53,7 @@ class EE_API Pak : public Pack {
|
||||
bool extractFileToMemory( const std::string& path, std::vector<Uint8>& data );
|
||||
|
||||
/** Extract a file to memory from the pakFile */
|
||||
bool extractFileToMemory( const std::string& path, SafeDataPointer& data );
|
||||
bool extractFileToMemory( const std::string& path, ScopedBuffer& data );
|
||||
|
||||
/** Check if a file exists in the pakFile and return the number of the file, otherwise return -1. */
|
||||
Int32 exists( const std::string& path );
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
#ifndef EE_SYSTEM_SAFEDATAPOINTER
|
||||
#define EE_SYSTEM_SAFEDATAPOINTER
|
||||
|
||||
#include <eepp/config.hpp>
|
||||
#include <eepp/core/memorymanager.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
/** @brief Keep a pointer and release it in the SafeDataPointer destructor */
|
||||
template <typename T>
|
||||
class TSafeDataPointer {
|
||||
public:
|
||||
TSafeDataPointer();
|
||||
|
||||
TSafeDataPointer( Uint32 size );
|
||||
|
||||
TSafeDataPointer( T * data, Uint32 size );
|
||||
|
||||
/** @brief The destructor deletes the buffer */
|
||||
~TSafeDataPointer();
|
||||
|
||||
void clear();
|
||||
|
||||
/** Pointer to the buffer */
|
||||
T * data;
|
||||
|
||||
/** Buffer size */
|
||||
Uint32 size;
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
TSafeDataPointer<T>::TSafeDataPointer() :
|
||||
data( NULL ),
|
||||
size( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TSafeDataPointer<T>::TSafeDataPointer( Uint32 size ) :
|
||||
data( eeNewArray( T, size ) ),
|
||||
size( size )
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TSafeDataPointer<T>::TSafeDataPointer( T * data, Uint32 size ) :
|
||||
data( data ),
|
||||
size( size )
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TSafeDataPointer<T>::~TSafeDataPointer() {
|
||||
clear();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TSafeDataPointer<T>::clear() {
|
||||
eeSAFE_DELETE_ARRAY( data );
|
||||
}
|
||||
|
||||
typedef TSafeDataPointer<Uint8> SafeDataPointer;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
153
include/eepp/system/scopedbuffer.hpp
Normal file
153
include/eepp/system/scopedbuffer.hpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#ifndef EE_SYSTEM_SCOPEDBUFFER
|
||||
#define EE_SYSTEM_SCOPEDBUFFER
|
||||
|
||||
#include <eepp/config.hpp>
|
||||
#include <eepp/core/memorymanager.hpp>
|
||||
#include <eepp/core/debug.hpp>
|
||||
#include <eepp/core/noncopyable.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
/** @brief Keep a pointer to a buffer and release it when the ScopedBuffer goes out of scope.
|
||||
|
||||
The TScopedBuffer class template stores a pointer to a dynamically allocated array.
|
||||
(Dynamically allocated arrays are allocated with the C++ new[] expression.)
|
||||
The array pointed to is guaranteed to be deleted, either on destruction of the TScopedBuffer,
|
||||
or via an explicit reset.
|
||||
|
||||
The TScopedBuffer template is a simple solution for simple needs.
|
||||
It supplies a basic "resource acquisition is initialization" facility,
|
||||
without shared-ownership or transfer-of-ownership semantics.
|
||||
Both its name and enforcement of semantics (by being NonCopyable) signal its
|
||||
intent to retain ownership solely within the current scope.
|
||||
*/
|
||||
template <typename T>
|
||||
class TScopedBuffer : NonCopyable {
|
||||
public:
|
||||
TScopedBuffer();
|
||||
|
||||
TScopedBuffer( std::size_t length );
|
||||
|
||||
TScopedBuffer( T * data, std::size_t length );
|
||||
|
||||
/** @brief The destructor deletes the buffer */
|
||||
~TScopedBuffer();
|
||||
|
||||
void clear();
|
||||
|
||||
T& operator[]( std::size_t i ) const;
|
||||
|
||||
bool operator()() const;
|
||||
|
||||
T * get() const;
|
||||
|
||||
void swap(TScopedBuffer<T>& b);
|
||||
|
||||
void reset(T * p = 0, const std::size_t& size = 0);
|
||||
|
||||
void reset(const std::size_t& size = 0);
|
||||
|
||||
bool isEmpty() const;
|
||||
|
||||
const std::size_t& size() const;
|
||||
|
||||
const std::size_t& length() const;
|
||||
|
||||
private:
|
||||
/** Pointer to the buffer */
|
||||
T * mData;
|
||||
|
||||
/** Buffer size */
|
||||
std::size_t mSize;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
TScopedBuffer<T>::TScopedBuffer() :
|
||||
mData( NULL ),
|
||||
mSize( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TScopedBuffer<T>::TScopedBuffer( std::size_t length ) :
|
||||
mData( eeNewArray( T, length ) ),
|
||||
mSize( length )
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TScopedBuffer<T>::TScopedBuffer( T * data, std::size_t length ) :
|
||||
mData( data ),
|
||||
mSize( length )
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TScopedBuffer<T>::~TScopedBuffer() {
|
||||
clear();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TScopedBuffer<T>::clear() {
|
||||
eeSAFE_DELETE_ARRAY( mData );
|
||||
mSize = 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& TScopedBuffer<T>::operator[]( std::size_t i ) const {
|
||||
eeASSERT( i < mSize && NULL != mData );
|
||||
return mData[i];
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TScopedBuffer<T>::operator()() const {
|
||||
return NULL != mData;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T * TScopedBuffer<T>::get() const {
|
||||
return mData;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const std::size_t& TScopedBuffer<T>::size() const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const std::size_t& TScopedBuffer<T>::length() const {
|
||||
return mSize;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool TScopedBuffer<T>::isEmpty() const {
|
||||
return mData == NULL;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TScopedBuffer<T>::swap(TScopedBuffer<T>& b) {
|
||||
std::swap(mData, b.mData);
|
||||
std::swap(mSize, b.mSize);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TScopedBuffer<T>::reset(T * p, const std::size_t& size) {
|
||||
eeASSERT( p == 0 || p != mData );
|
||||
clear();
|
||||
mData = p;
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void TScopedBuffer<T>::reset(const std::size_t& size) {
|
||||
clear();
|
||||
mData = eeNewArray( T, ( size ) );
|
||||
mSize = size;
|
||||
}
|
||||
|
||||
typedef TScopedBuffer<Uint8> ScopedBuffer;
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
@@ -51,7 +51,7 @@ class EE_API Zip : public Pack {
|
||||
bool extractFileToMemory( const std::string& path, std::vector<Uint8>& data );
|
||||
|
||||
/** Extract a file to memory from the pakFile */
|
||||
bool extractFileToMemory( const std::string& path, SafeDataPointer& data );
|
||||
bool extractFileToMemory( const std::string& path, ScopedBuffer& data );
|
||||
|
||||
/** Check if a file exists in the pack file and return the number of the file, otherwise return -1. */
|
||||
Int32 exists( const std::string& path );
|
||||
|
||||
111
premake4.lua
111
premake4.lua
@@ -145,8 +145,8 @@ newoption { trigger = "with-static-backend", description = "It will try to compi
|
||||
newoption { trigger = "with-gles2", description = "Compile with GLES2 support" }
|
||||
newoption { trigger = "with-gles1", description = "Compile with GLES1 support" }
|
||||
newoption { trigger = "use-frameworks", description = "In Mac OS X it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link agains SDL2.framework." }
|
||||
newoption {
|
||||
trigger = "with-backend",
|
||||
newoption {
|
||||
trigger = "with-backend",
|
||||
description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.",
|
||||
allowed = {
|
||||
{ "SDL2", "SDL2 (default and recommended)" },
|
||||
@@ -167,21 +167,21 @@ function explode(div,str)
|
||||
end
|
||||
|
||||
function os.get_real()
|
||||
if _OPTIONS.platform == "ios-arm7" or
|
||||
if _OPTIONS.platform == "ios-arm7" or
|
||||
_OPTIONS.platform == "ios-x86" or
|
||||
_OPTIONS.platform == "ios-cross-arm7" or
|
||||
_OPTIONS.platform == "ios-cross-x86" then
|
||||
return "ios"
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "android-arm7" then
|
||||
return "android"
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "mingw32" then
|
||||
return _OPTIONS.platform
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "emscripten" then
|
||||
return _OPTIONS.platform
|
||||
end
|
||||
@@ -229,7 +229,7 @@ end
|
||||
function os_findlib( name )
|
||||
if os.is_real("macosx") and ( is_xcode() or _OPTIONS["use-frameworks"] ) then
|
||||
local path = "/Library/Frameworks/" .. name .. ".framework"
|
||||
|
||||
|
||||
if os.isdir( path ) then
|
||||
return path
|
||||
end
|
||||
@@ -241,12 +241,12 @@ end
|
||||
function get_backend_link_name( name )
|
||||
if os.is_real("macosx") and ( is_xcode() or _OPTIONS["use-frameworks"] ) then
|
||||
local fname = name .. ".framework"
|
||||
|
||||
|
||||
if os_findlib( name ) then -- Search for the framework
|
||||
return fname
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return name
|
||||
end
|
||||
|
||||
@@ -254,7 +254,7 @@ function string.starts(String,Start)
|
||||
if ( _ACTION ) then
|
||||
return string.sub(String,1,string.len(Start))==Start
|
||||
end
|
||||
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
@@ -315,7 +315,7 @@ function build_base_cpp_configuration( package_name )
|
||||
if not os.is("windows") then
|
||||
buildoptions{ "-fPIC" }
|
||||
end
|
||||
|
||||
|
||||
set_ios_config()
|
||||
set_xcode_config()
|
||||
|
||||
@@ -364,7 +364,7 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
includedirs { "include" }
|
||||
|
||||
local extension = "";
|
||||
|
||||
|
||||
if package_name == "eepp" then
|
||||
defines { "EE_EXPORTS" }
|
||||
elseif package_name == "eepp-static" then
|
||||
@@ -384,13 +384,13 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
add_static_links()
|
||||
links { link_list }
|
||||
end
|
||||
|
||||
if os.is("windows") and not is_vs() then
|
||||
|
||||
if os.is("windows") and not is_vs() then
|
||||
if ( true == use_ee_icon ) then
|
||||
linkoptions { "../../bin/assets/icon/ee.res" }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if os.is_real("emscripten") then
|
||||
extension = ".html"
|
||||
|
||||
@@ -403,11 +403,11 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
linkoptions { "--preload-file assets/" }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "ios-cross-arm7" then
|
||||
extension = ".ios"
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "ios-cross-x86" then
|
||||
extension = ".x86.ios"
|
||||
end
|
||||
@@ -440,10 +440,10 @@ function build_link_configuration( package_name, use_ee_icon )
|
||||
fix_shared_lib_linking_path( package_name, "libeepp" )
|
||||
|
||||
targetname ( package_name .. extension )
|
||||
|
||||
|
||||
configuration "windows"
|
||||
add_cross_config_links()
|
||||
|
||||
|
||||
configuration "emscripten"
|
||||
linkoptions{ "-O2 -s TOTAL_MEMORY=67108864 -s ASM_JS=1 -s VERBOSE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s USE_SDL=2 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s FULL_ES3=1 -s \"BINARYEN_TRAP_MODE='clamp'\"" }
|
||||
buildoptions { "-fno-strict-aliasing -O2 -s USE_SDL=2 -s PRECISE_F32=1" }
|
||||
@@ -463,7 +463,7 @@ end
|
||||
function generate_os_links()
|
||||
if os.is_real("linux") then
|
||||
multiple_insert( os_links, { "rt", "pthread", "X11", "openal", "GL", "Xcursor" } )
|
||||
|
||||
|
||||
if _OPTIONS["with-static-eepp"] then
|
||||
table.insert( os_links, "dl" )
|
||||
end
|
||||
@@ -488,28 +488,28 @@ function parse_args()
|
||||
if _OPTIONS["with-gles2"] then
|
||||
defines { "EE_GLES2", "SOIL_GLES2" }
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS["with-gles1"] then
|
||||
defines { "EE_GLES1", "SOIL_GLES1" }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function add_static_links()
|
||||
-- The linking order DOES matter
|
||||
-- Expose the symbols that need one static library AFTER adding that static lib
|
||||
|
||||
|
||||
-- Add static backends
|
||||
if next(static_backends) ~= nil then
|
||||
for _, value in pairs( static_backends ) do
|
||||
linkoptions { value }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS["with-static-freetype"] or not os_findlib("freetype") then
|
||||
print("Enabled static freetype")
|
||||
links { "freetype-static" }
|
||||
end
|
||||
|
||||
|
||||
links { "SOIL2-static",
|
||||
"chipmunk-static",
|
||||
"libzip-static",
|
||||
@@ -523,7 +523,7 @@ function add_static_links()
|
||||
if _OPTIONS["with-ssl"] and not _OPTIONS["with-openssl"] then
|
||||
links { "mbedtls-static" }
|
||||
end
|
||||
|
||||
|
||||
if not os.is_real("haiku") and not os.is_real("ios") and not os.is_real("android") and not os.is_real("emscripten") then
|
||||
links{ "glew-static" }
|
||||
end
|
||||
@@ -544,7 +544,7 @@ function add_sdl2()
|
||||
print("Using SDL2 backend");
|
||||
files { "src/eepp/window/backend/SDL2/*.cpp" }
|
||||
defines { "EE_BACKEND_SDL_ACTIVE", "EE_SDL_VERSION_2" }
|
||||
|
||||
|
||||
if not can_add_static_backend("SDL2") then
|
||||
table.insert( link_list, get_backend_link_name( "SDL2" ) )
|
||||
else
|
||||
@@ -556,7 +556,7 @@ function add_sfml()
|
||||
print("Using SFML backend");
|
||||
files { "src/eepp/window/backend/SFML/*.cpp" }
|
||||
defines { "EE_BACKEND_SFML_ACTIVE" }
|
||||
|
||||
|
||||
if not can_add_static_backend("SFML") then
|
||||
table.insert( link_list, get_backend_link_name( "sfml-system" ) )
|
||||
table.insert( link_list, get_backend_link_name( "sfml-window" ) )
|
||||
@@ -577,13 +577,13 @@ end
|
||||
function set_ios_config()
|
||||
if _OPTIONS.platform == "ios-arm7" or _OPTIONS.platform == "ios-x86" then
|
||||
local err = false
|
||||
|
||||
|
||||
if nil == os.getenv("TOOLCHAINPATH") then
|
||||
print("You must set TOOLCHAINPATH enviroment variable.")
|
||||
print("\tExample: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/")
|
||||
err = true
|
||||
end
|
||||
|
||||
|
||||
if nil == os.getenv("SYSROOTPATH") then
|
||||
print("You must set SYSROOTPATH enviroment variable.")
|
||||
print("\tExample: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk")
|
||||
@@ -595,7 +595,7 @@ function set_ios_config()
|
||||
print("\tExample: 5.0")
|
||||
err = true
|
||||
end
|
||||
|
||||
|
||||
if err then
|
||||
os.exit(1)
|
||||
end
|
||||
@@ -604,14 +604,14 @@ function set_ios_config()
|
||||
local framework_path = sysroot_path .. "/System/Library/Frameworks"
|
||||
local framework_libs_path = framework_path .. "/usr/lib"
|
||||
local sysroot_ver = " -miphoneos-version-min=" .. os.getenv("IOSVERSION") .. " -isysroot " .. sysroot_path
|
||||
|
||||
|
||||
buildoptions { sysroot_ver .. " -I" .. sysroot_path .. "/usr/include" }
|
||||
linkoptions { sysroot_ver }
|
||||
libdirs { framework_libs_path }
|
||||
linkoptions { " -F" .. framework_path .. " -L" .. framework_libs_path .. " -isysroot " .. sysroot_path }
|
||||
includedirs { "src/thirdparty/SDL2/include" }
|
||||
end
|
||||
|
||||
|
||||
if _OPTIONS.platform == "ios-cross-arm7" or _OPTIONS.platform == "ios-cross-x86" then
|
||||
includedirs { "src/thirdparty/SDL2/include" }
|
||||
end
|
||||
@@ -625,7 +625,7 @@ function backend_is( name, libname )
|
||||
if next(backends) == nil then
|
||||
backends = string.explode(_OPTIONS["with-backend"],",")
|
||||
end
|
||||
|
||||
|
||||
local backend_sel = table.contains( backends, name )
|
||||
|
||||
local ret_val = os_findlib( libname ) and backend_sel
|
||||
@@ -641,7 +641,7 @@ function backend_is( name, libname )
|
||||
return ret_val
|
||||
end
|
||||
|
||||
function select_backend()
|
||||
function select_backend()
|
||||
if backend_is("SDL2", "SDL2") then
|
||||
print("Selected SDL2")
|
||||
add_sdl2()
|
||||
@@ -693,10 +693,10 @@ end
|
||||
|
||||
function build_eepp( build_name )
|
||||
includedirs { "include", "src", "src/thirdparty", "include/eepp/thirdparty", "src/thirdparty/freetype2/include", "src/thirdparty/zlib", "src/thirdparty/libogg/include", "src/thirdparty/libvorbis/include", "src/thirdparty/mbedtls/include" }
|
||||
|
||||
|
||||
set_ios_config()
|
||||
set_xcode_config()
|
||||
|
||||
|
||||
add_static_links()
|
||||
|
||||
if is_vs() then
|
||||
@@ -725,6 +725,7 @@ function build_eepp( build_name )
|
||||
"src/eepp/window/platform/null/*.cpp",
|
||||
"src/eepp/network/*.cpp",
|
||||
"src/eepp/network/ssl/*.cpp",
|
||||
"src/eepp/network/http/*.cpp",
|
||||
"src/eepp/scene/*.cpp",
|
||||
"src/eepp/scene/actions/*.cpp",
|
||||
"src/eepp/ui/*.cpp",
|
||||
@@ -736,11 +737,11 @@ function build_eepp( build_name )
|
||||
"src/eepp/maps/*.cpp",
|
||||
"src/eepp/maps/mapeditor/*.cpp"
|
||||
}
|
||||
|
||||
|
||||
check_ssl_support()
|
||||
|
||||
|
||||
select_backend()
|
||||
|
||||
|
||||
if not _OPTIONS["with-static-freetype"] and os_findlib("freetype") then
|
||||
table.insert( link_list, get_backend_link_name( "freetype" ) )
|
||||
end
|
||||
@@ -748,19 +749,19 @@ function build_eepp( build_name )
|
||||
multiple_insert( link_list, os_links )
|
||||
|
||||
links { link_list }
|
||||
|
||||
|
||||
build_link_configuration( build_name )
|
||||
|
||||
configuration "windows"
|
||||
files { "src/eepp/window/platform/win/*.cpp" }
|
||||
add_cross_config_links()
|
||||
|
||||
|
||||
configuration "linux"
|
||||
files { "src/eepp/window/platform/x11/*.cpp" }
|
||||
|
||||
|
||||
configuration "macosx"
|
||||
files { "src/eepp/window/platform/osx/*.cpp" }
|
||||
|
||||
|
||||
configuration "emscripten"
|
||||
if _OPTIONS["force-gles1"] then
|
||||
defines{ "EE_GLES1_DEFAULT" }
|
||||
@@ -776,7 +777,7 @@ function set_targetdir( dir )
|
||||
end
|
||||
|
||||
solution "eepp"
|
||||
|
||||
|
||||
targetdir("./bin/")
|
||||
configurations { "debug", "release" }
|
||||
|
||||
@@ -865,7 +866,7 @@ solution "eepp"
|
||||
files { "src/thirdparty/freetype2/src/**.c" }
|
||||
includedirs { "src/thirdparty/freetype2/include" }
|
||||
build_base_configuration( "freetype" )
|
||||
|
||||
|
||||
project "chipmunk-static"
|
||||
kind "StaticLib"
|
||||
|
||||
@@ -900,15 +901,15 @@ solution "eepp"
|
||||
language "C++"
|
||||
set_targetdir("libs/" .. os.get_real() .. "/thirdparty/")
|
||||
includedirs { "src/thirdparty/efsw/include", "src/thirdparty/efsw/src" }
|
||||
|
||||
|
||||
if os.is("windows") then
|
||||
osfiles = "src/thirdparty/efsw/src/efsw/platform/win/*.cpp"
|
||||
else
|
||||
osfiles = "src/thirdparty/efsw/src/efsw/platform/posix/*.cpp"
|
||||
end
|
||||
|
||||
|
||||
files { "src/thirdparty/efsw/src/efsw/*.cpp", osfiles }
|
||||
|
||||
|
||||
if os.is("windows") then
|
||||
excludes { "src/thirdparty/efsw/src/efsw/WatcherKqueue.cpp", "src/thirdparty/efsw/src/efsw/WatcherFSEvents.cpp", "src/thirdparty/efsw/src/efsw/WatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherKqueue.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherFSEvents.cpp" }
|
||||
elseif os.is("linux") then
|
||||
@@ -918,7 +919,7 @@ solution "eepp"
|
||||
elseif os.is("freebsd") then
|
||||
excludes { "src/thirdparty/efsw/src/efsw/WatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/WatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/WatcherFSEvents.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherFSEvents.cpp" }
|
||||
end
|
||||
|
||||
|
||||
build_base_cpp_configuration( "efsw" )
|
||||
|
||||
project "eepp-main"
|
||||
@@ -932,7 +933,7 @@ solution "eepp"
|
||||
language "C++"
|
||||
set_targetdir("libs/" .. os.get_real() .. "/")
|
||||
build_eepp( "eepp-static" )
|
||||
|
||||
|
||||
project "eepp-shared"
|
||||
kind "SharedLib"
|
||||
language "C++"
|
||||
@@ -1007,20 +1008,20 @@ solution "eepp"
|
||||
language "C++"
|
||||
files { "src/tools/mapeditor/*.cpp" }
|
||||
build_link_configuration( "eepp-MapEditor", true )
|
||||
|
||||
|
||||
project "eepp-uieditor"
|
||||
set_kind()
|
||||
language "C++"
|
||||
includedirs { "src/thirdparty/efsw/include", "src/thirdparty" }
|
||||
|
||||
|
||||
if not os.is("windows") and not os.is("haiku") then
|
||||
links { "pthread" }
|
||||
end
|
||||
|
||||
|
||||
links { "efsw-static", "pugixml-static" }
|
||||
files { "src/tools/uieditor/*.cpp" }
|
||||
build_link_configuration( "eepp-UIEditor", true )
|
||||
|
||||
|
||||
if os.isfile("external_projects.lua") then
|
||||
dofile("external_projects.lua")
|
||||
end
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#define EE_SDL_VERSION_2
|
||||
#define EE_X11_PLATFORM
|
||||
#define EE_DEBUG
|
||||
#define EE_LIBSNDFILE_ENABLED
|
||||
#define EE_MEMORY_MANAGER
|
||||
#define EE_SHADERS_SUPPORTED
|
||||
#define EE_GLEW_AVAILABLE
|
||||
@@ -10,7 +9,6 @@
|
||||
#define EE_BACKEND_SFML_ACTIVE
|
||||
#define EE_BACKEND_SDL2
|
||||
#define EE_GL3_ENABLED
|
||||
#define EE_SHADERS_SUPPORTED
|
||||
#define EE_BACKEND_SDL_ACTIVE
|
||||
#define EE_MBEDTLS
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
|
||||
@@ -143,7 +143,6 @@
|
||||
../../include/eepp/maps/mapobjectlayer.hpp
|
||||
../../include/eepp/maps/tilemap.hpp
|
||||
../../include/eepp/maps/tilemaplayer.hpp
|
||||
../../include/eepp/math/base.hpp
|
||||
../../include/eepp/math/ease.hpp
|
||||
../../include/eepp/math/easing.hpp
|
||||
../../include/eepp/math.hpp
|
||||
@@ -242,16 +241,20 @@
|
||||
../../include/eepp/system/bitop.hpp
|
||||
../../include/eepp/system/clock.hpp
|
||||
../../include/eepp/system/color.hpp
|
||||
../../include/eepp/system/compression.hpp
|
||||
../../include/eepp/system/condition.hpp
|
||||
../../include/eepp/system/container.hpp
|
||||
../../include/eepp/system/directorypack.hpp
|
||||
../../include/eepp/system/filesystem.hpp
|
||||
../../include/eepp/system.hpp
|
||||
../../include/eepp/system/inifile.hpp
|
||||
../../include/eepp/system/iostreamdeflate.hpp
|
||||
../../include/eepp/system/iostreamfile.hpp
|
||||
../../include/eepp/system/iostream.hpp
|
||||
../../include/eepp/system/iostreaminflate.hpp
|
||||
../../include/eepp/system/iostreammemory.hpp
|
||||
../../include/eepp/system/iostreampak.hpp
|
||||
../../include/eepp/system/iostreamstring.hpp
|
||||
../../include/eepp/system/iostreamzip.hpp
|
||||
../../include/eepp/system/lock.hpp
|
||||
../../include/eepp/system/log.hpp
|
||||
@@ -264,7 +267,7 @@
|
||||
../../include/eepp/system/rc4.hpp
|
||||
../../include/eepp/system/resourceloader.hpp
|
||||
../../include/eepp/system/resourcemanager.hpp
|
||||
../../include/eepp/system/safedatapointer.hpp
|
||||
../../include/eepp/system/scopedbuffer.hpp
|
||||
../../include/eepp/system/singleton.hpp
|
||||
../../include/eepp/system/sys.hpp
|
||||
../../include/eepp/system/thread.hpp
|
||||
@@ -588,6 +591,8 @@
|
||||
../../src/eepp/math/transform.cpp
|
||||
../../src/eepp/network/ftp.cpp
|
||||
../../src/eepp/network/http.cpp
|
||||
../../src/eepp/network/http/httpstreamchunked.cpp
|
||||
../../src/eepp/network/http/httpstreamchunked.hpp
|
||||
../../src/eepp/network/ipaddress.cpp
|
||||
../../src/eepp/network/packet.cpp
|
||||
../../src/eepp/network/platform/platformimpl.hpp
|
||||
@@ -667,13 +672,17 @@
|
||||
../../src/eepp/system/base64.cpp
|
||||
../../src/eepp/system/clock.cpp
|
||||
../../src/eepp/system/color.cpp
|
||||
../../src/eepp/system/compression.cpp
|
||||
../../src/eepp/system/condition.cpp
|
||||
../../src/eepp/system/directorypack.cpp
|
||||
../../src/eepp/system/filesystem.cpp
|
||||
../../src/eepp/system/inifile.cpp
|
||||
../../src/eepp/system/iostreamdeflate.cpp
|
||||
../../src/eepp/system/iostreamfile.cpp
|
||||
../../src/eepp/system/iostreaminflate.cpp
|
||||
../../src/eepp/system/iostreammemory.cpp
|
||||
../../src/eepp/system/iostreampak.cpp
|
||||
../../src/eepp/system/iostreamstring.cpp
|
||||
../../src/eepp/system/iostreamzip.cpp
|
||||
../../src/eepp/system/lock.cpp
|
||||
../../src/eepp/system/log.cpp
|
||||
|
||||
@@ -4,10 +4,4 @@
|
||||
../../include/eepp/thirdparty
|
||||
../../src/thirdparty/efsw/include
|
||||
../../src/thirdparty/libvorbis/include
|
||||
../../src/eepp/audio
|
||||
../../include/eepp/audio
|
||||
/usr/include/freetype2/
|
||||
|
||||
../../include/eepp/ui
|
||||
../../src/eepp/ui
|
||||
../../bin/assets/layouts
|
||||
|
||||
@@ -81,7 +81,7 @@ bool Music::openFromStream(IOStream& stream) {
|
||||
|
||||
bool Music::openFromPack(Pack * pack, const std::string & filePackPath) {
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( filePackPath, mData ) )
|
||||
return openFromMemory( reinterpret_cast<const char*> ( mData.data ), mData.size );
|
||||
return openFromMemory( reinterpret_cast<const char*> ( mData.get() ), mData.length() );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <eepp/audio/alcheck.hpp>
|
||||
#include <eepp/core/debug.hpp>
|
||||
#include <eepp/system/pack.hpp>
|
||||
#include <eepp/system/safedatapointer.hpp>
|
||||
#include <eepp/system/scopedbuffer.hpp>
|
||||
#include <eepp/system/pack.hpp>
|
||||
#include <eepp/system/filesystem.hpp>
|
||||
#include <eepp/system/packmanager.hpp>
|
||||
@@ -105,10 +105,10 @@ bool SoundBuffer::loadFromSamples(const Int16* samples, Uint64 sampleCount, unsi
|
||||
|
||||
bool SoundBuffer::loadFromPack(Pack * pack, std::string filePackPath) {
|
||||
bool Ret = false;
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( filePackPath, PData ) )
|
||||
Ret = loadFromMemory( reinterpret_cast<const char*> ( PData.data ), PData.size );
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( filePackPath, buffer ) )
|
||||
Ret = loadFromMemory( reinterpret_cast<const char*> ( buffer.get() ), buffer.length() );
|
||||
|
||||
return Ret;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <eepp/audio/mp3info.hpp>
|
||||
#include <eepp/system/safedatapointer.hpp>
|
||||
#include <eepp/system/scopedbuffer.hpp>
|
||||
|
||||
static size_t drmp3_func_read(void* data, void* ptr, size_t size) {
|
||||
IOStream* stream = static_cast<IOStream*>(data);
|
||||
@@ -73,15 +73,15 @@ Uint64 SoundFileReaderMp3::read(Int16* samples, Uint64 maxCount) {
|
||||
while (count < maxCount) {
|
||||
const int samplesToRead = static_cast<int>(maxCount - count);
|
||||
int frames = samplesToRead / mChannelCount;
|
||||
TSafeDataPointer<float> rSamples( samplesToRead );
|
||||
TScopedBuffer<float> rSamples( samplesToRead );
|
||||
|
||||
long framesRead = drmp3_read_pcm_frames_f32( mMp3, frames, rSamples.data );
|
||||
long framesRead = drmp3_read_pcm_frames_f32( mMp3, frames, rSamples.get() );
|
||||
|
||||
if (framesRead > 0) {
|
||||
long samplesRead = framesRead * mChannelCount;
|
||||
|
||||
for ( int i = 0; i < samplesRead; i++ )
|
||||
samples[i] = rSamples.data[i] * 32768.f;
|
||||
samples[i] = rSamples[i] * 32768.f;
|
||||
|
||||
count += samplesRead;
|
||||
samples += samplesRead;
|
||||
|
||||
@@ -242,7 +242,7 @@ bool FontTrueType::loadFromPack( Pack * pack, std::string filePackPath ) {
|
||||
mMemCopy.clear();
|
||||
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( filePackPath, mMemCopy ) ) {
|
||||
Ret = loadFromMemory( mMemCopy.data, mMemCopy.size );
|
||||
Ret = loadFromMemory( mMemCopy.get(), mMemCopy.length() );
|
||||
}
|
||||
|
||||
return Ret;
|
||||
@@ -367,8 +367,9 @@ Texture* FontTrueType::getTexture(unsigned int characterSize) const {
|
||||
}
|
||||
|
||||
FontTrueType& FontTrueType::operator =(const FontTrueType& right) {
|
||||
FontTrueType temp(right);
|
||||
FontTrueType temp(right.getName());
|
||||
|
||||
temp.mMemCopy.swap(right.mMemCopy);
|
||||
std::swap(mLibrary, temp.mLibrary);
|
||||
std::swap(mFace, temp.mFace);
|
||||
std::swap(mStreamRec, temp.mStreamRec);
|
||||
|
||||
@@ -284,18 +284,18 @@ bool Image::getInfo( const std::string& path, int * width, int * height, int * c
|
||||
Pack * tPack = PackManager::instance()->exists( npath );
|
||||
|
||||
if ( NULL != tPack ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
tPack->extractFileToMemory( npath, PData );
|
||||
tPack->extractFileToMemory( npath, buffer );
|
||||
|
||||
res = 0 != stbi_info_from_memory( PData.data, PData.size, width, height, channels );
|
||||
res = 0 != stbi_info_from_memory( buffer.get(), buffer.length(), width, height, channels );
|
||||
|
||||
if ( !res && svg_test_from_memory( PData.data, PData.size ) ) {
|
||||
SafeDataPointer data( PData.size + 1 );
|
||||
memcpy( data.data, PData.data, PData.size );
|
||||
data.data[PData.size] = '\0';
|
||||
if ( !res && svg_test_from_memory( buffer.get(), buffer.length() ) ) {
|
||||
ScopedBuffer data( buffer.length() + 1 );
|
||||
memcpy( data.get(), buffer.get(), buffer.length() );
|
||||
data[buffer.length()] = '\0';
|
||||
|
||||
NSVGimage * image = nsvgParse( (char*)data.data, "px", 96.0f );
|
||||
NSVGimage * image = nsvgParse( (char*)data.get(), "px", 96.0f );
|
||||
|
||||
if ( NULL != image ) {
|
||||
*width = image->width * imageFormatConfiguration.svgScale();
|
||||
@@ -467,10 +467,10 @@ Image::Image( const Uint8 * imageData, const unsigned int & imageDataSize, const
|
||||
|
||||
mLoadedFromStbi = true;
|
||||
} else if ( svg_test_from_memory( imageData, imageDataSize ) ) {
|
||||
SafeDataPointer data( imageDataSize + 1 );
|
||||
memcpy( data.data, imageData, imageDataSize );
|
||||
data.data[imageDataSize] = '\0';
|
||||
svgLoad( nsvgParse( (char*)data.data, "px", 96.0f ) );
|
||||
ScopedBuffer data( imageDataSize + 1 );
|
||||
memcpy( data.get(), imageData, imageDataSize );
|
||||
data[imageDataSize] = '\0';
|
||||
svgLoad( nsvgParse( (char*)data.get(), "px", 96.0f ) );
|
||||
} else {
|
||||
std::string reason = ".";
|
||||
|
||||
@@ -526,14 +526,14 @@ Image::Image( IOStream & stream, const unsigned int& forceChannels, const Format
|
||||
|
||||
mLoadedFromStbi = true;
|
||||
} else if ( svg_test_from_stream( stream ) ) {
|
||||
SafeDataPointer data( stream.getSize() + 1 );
|
||||
ScopedBuffer data( stream.getSize() + 1 );
|
||||
|
||||
stream.seek( 0 );
|
||||
stream.read( (char*)data.data, data.size - 1 );
|
||||
stream.read( (char*)data.get(), data.length() - 1 );
|
||||
|
||||
data.data[data.size - 1] = '\0';
|
||||
data[data.length() - 1] = '\0';
|
||||
|
||||
svgLoad( nsvgParse( (char*)data.data, "px", 96.0f ) );
|
||||
svgLoad( nsvgParse( (char*)data.get(), "px", 96.0f ) );
|
||||
} else {
|
||||
eePRINTL( "Failed to load image. Reason: %s", stbi_failure_reason() );
|
||||
}
|
||||
@@ -580,12 +580,12 @@ void Image::svgLoad( NSVGimage * image ) {
|
||||
|
||||
void Image::loadFromPack( Pack * Pack, const std::string& FilePackPath ) {
|
||||
if ( NULL != Pack && Pack->isOpen() && -1 != Pack->exists( FilePackPath ) ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
Pack->extractFileToMemory( FilePackPath, PData );
|
||||
Pack->extractFileToMemory( FilePackPath, buffer );
|
||||
|
||||
int w, h, c;
|
||||
Uint8 * data = stbi_load_from_memory( PData.data, PData.size, &w, &h, &c, mChannels );
|
||||
Uint8 * data = stbi_load_from_memory( buffer.get(), buffer.length(), &w, &h, &c, mChannels );
|
||||
|
||||
if ( NULL != data ) {
|
||||
mPixels = data;
|
||||
@@ -598,11 +598,11 @@ void Image::loadFromPack( Pack * Pack, const std::string& FilePackPath ) {
|
||||
mSize = mWidth * mHeight * mChannels;
|
||||
|
||||
mLoadedFromStbi = true;
|
||||
} else if ( svg_test_from_memory( PData.data, PData.size ) ) {
|
||||
SafeDataPointer data( PData.size + 1 );
|
||||
memcpy( data.data, PData.data, PData.size );
|
||||
data.data[PData.size] = '\0';
|
||||
svgLoad( nsvgParse( (char*)data.data, "px", 96.0f ) );
|
||||
} else if ( svg_test_from_memory( buffer.get(), buffer.length() ) ) {
|
||||
ScopedBuffer data( buffer.length() + 1 );
|
||||
memcpy( data.get(), buffer.get(), buffer.length() );
|
||||
data[buffer.length()] = '\0';
|
||||
svgLoad( nsvgParse( (char*)data.get(), "px", 96.0f ) );
|
||||
} else {
|
||||
eePRINTL( "Failed to load image %s. Reason: %s", FilePackPath.c_str(), stbi_failure_reason() );
|
||||
}
|
||||
|
||||
@@ -30,21 +30,21 @@ Shader::Shader( const Uint32& Type, const std::string& Filename ) {
|
||||
mFilename = FileSystem::fileNameFromPath( Filename );
|
||||
|
||||
if ( FileSystem::fileExists( Filename ) ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
FileSystem::fileGet( Filename, PData );
|
||||
FileSystem::fileGet( Filename, buffer );
|
||||
|
||||
setSource( (const char*)PData.data, PData.size );
|
||||
setSource( (const char*)buffer.get(), buffer.length() );
|
||||
} else {
|
||||
std::string tPath = Filename;
|
||||
Pack * tPack = NULL;
|
||||
|
||||
if ( PackManager::instance()->isFallbackToPacksActive() && NULL != ( tPack = PackManager::instance()->exists( tPath ) ) ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
tPack->extractFileToMemory( tPath, PData );
|
||||
tPack->extractFileToMemory( tPath, buffer );
|
||||
|
||||
setSource( reinterpret_cast<char*> ( PData.data ), PData.size );
|
||||
setSource( reinterpret_cast<char*> ( buffer.get() ), buffer.length() );
|
||||
} else {
|
||||
eePRINTL( "Couldn't open shader object: %s", Filename.c_str() );
|
||||
}
|
||||
@@ -62,16 +62,16 @@ Shader::Shader( const Uint32& Type, const char * Data, const Uint32& DataSize )
|
||||
}
|
||||
|
||||
Shader::Shader( const Uint32& Type, Pack * Pack, const std::string& Filename ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
Init( Type );
|
||||
|
||||
mFilename = FileSystem::fileNameFromPath( Filename );
|
||||
|
||||
if ( NULL != Pack && Pack->isOpen() && -1 != Pack->exists( Filename ) ) {
|
||||
Pack->extractFileToMemory( Filename, PData );
|
||||
Pack->extractFileToMemory( Filename, buffer );
|
||||
|
||||
setSource( reinterpret_cast<char*> ( PData.data ), PData.size );
|
||||
setSource( reinterpret_cast<char*> ( buffer.get() ), buffer.length() );
|
||||
}
|
||||
|
||||
compile();
|
||||
|
||||
@@ -193,11 +193,11 @@ void TextureAtlasLoader::loadFromPack( Pack * Pack, const std::string& FilePackP
|
||||
if ( NULL != Pack && Pack->isOpen() && -1 != Pack->exists( FilePackPath ) ) {
|
||||
mPack = Pack;
|
||||
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
Pack->extractFileToMemory( FilePackPath, PData );
|
||||
Pack->extractFileToMemory( FilePackPath, buffer );
|
||||
|
||||
loadFromMemory( reinterpret_cast<const Uint8*> ( PData.data ), PData.size, FilePackPath );
|
||||
loadFromMemory( buffer.get(), buffer.length(), FilePackPath );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -278,11 +278,11 @@ void TextureLoader::loadFromFile() {
|
||||
}
|
||||
|
||||
void TextureLoader::loadFromPack() {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
if ( NULL != mPack && mPack->isOpen() && mPack->extractFileToMemory( mFilepath, PData ) ) {
|
||||
mImagePtr = PData.data;
|
||||
mSize = PData.size;
|
||||
if ( NULL != mPack && mPack->isOpen() && mPack->extractFileToMemory( mFilepath, buffer ) ) {
|
||||
mImagePtr = buffer.get();
|
||||
mSize = buffer.length();
|
||||
|
||||
loadFromMemory();
|
||||
}
|
||||
|
||||
@@ -1072,13 +1072,13 @@ bool TileMap::loadFromFile( const std::string& path ) {
|
||||
|
||||
bool TileMap::loadFromPack( Pack * Pack, const std::string& FilePackPath ) {
|
||||
if ( NULL != Pack && Pack->isOpen() && -1 != Pack->exists( FilePackPath ) ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
Pack->extractFileToMemory( FilePackPath, PData );
|
||||
Pack->extractFileToMemory( FilePackPath, buffer );
|
||||
|
||||
mPath = FilePackPath;
|
||||
|
||||
return loadFromMemory( reinterpret_cast<const char*> ( PData.data ), PData.size );
|
||||
return loadFromMemory( reinterpret_cast<const char*> ( buffer.get() ), buffer.length() );
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
112
src/eepp/network/http/httpstreamchunked.cpp
Normal file
112
src/eepp/network/http/httpstreamchunked.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include <eepp/network/http/httpstreamchunked.hpp>
|
||||
|
||||
namespace EE { namespace Network { namespace Private {
|
||||
|
||||
HttpStreamChunked::HttpStreamChunked(IOStream & mWriteTo) :
|
||||
mWriteTo( mWriteTo ),
|
||||
mChunkNewBuffer(false),
|
||||
mChunkEnded(false)
|
||||
{}
|
||||
|
||||
ios_size HttpStreamChunked::write(const char * data, ios_size size) {
|
||||
ios_size writeTotal = 0;
|
||||
|
||||
// If the chunk reading ended we just add the buffer received as a header
|
||||
// Otherwise we process the buffer data as chunk
|
||||
if ( !mChunkEnded ) {
|
||||
// Keep a chunk buffer until the end of chunk is found
|
||||
mChunkBuffer.append( data, size );
|
||||
|
||||
// If the new chunk starts with \r\n and the last removed chunk
|
||||
// did not contain the trailing \r\n, we remove it to detect
|
||||
// correctly the next length data
|
||||
if ( mChunkNewBuffer ) {
|
||||
if ( mChunkBuffer.substr( 0, 2 ) == "\r\n" ) {
|
||||
mChunkBuffer = mChunkBuffer.substr( 2 );
|
||||
}
|
||||
|
||||
mChunkNewBuffer = false;
|
||||
}
|
||||
|
||||
bool retry;
|
||||
|
||||
do {
|
||||
retry = false;
|
||||
|
||||
// Check for the first \r\n to find the end of the length definition
|
||||
std::string::size_type lenEnd = mChunkBuffer.find_first_of("\r\n");
|
||||
|
||||
if ( lenEnd != std::string::npos ) {
|
||||
std::string::size_type firstCharPos = lenEnd + 2;
|
||||
unsigned long length;
|
||||
|
||||
// Get the length of the chunk
|
||||
bool res = String::fromString( length, mChunkBuffer.substr(0, lenEnd), std::hex );
|
||||
|
||||
// If the length is solved...
|
||||
if ( res ) {
|
||||
// And it's bigger than 0, means that there are more chunks
|
||||
if ( length > 0 ) {
|
||||
// Check if the chunk buffer size at least equals to the length reported
|
||||
if ( mChunkBuffer.size() - firstCharPos >= length ) {
|
||||
// In that case write the chunk to the file buffer
|
||||
writeTotal = mWriteTo.write( &mChunkBuffer[firstCharPos], length );
|
||||
|
||||
// And keep the remaining not completed chunk
|
||||
mChunkBuffer = mChunkBuffer.substr( firstCharPos + length );
|
||||
|
||||
// Check if already have the \r\n of the next length in the buffer
|
||||
if ( !mChunkBuffer.empty() ) {
|
||||
std::size_t pos = 0;
|
||||
|
||||
// Remove al the \r\n remaining
|
||||
while ( pos < mChunkBuffer.size() && 0 == strncmp( &mChunkBuffer[pos], "\r\n", 2 ) ) {
|
||||
pos += 2;
|
||||
}
|
||||
|
||||
if ( pos > 0 ) {
|
||||
// Remove it to be able to read the next length
|
||||
mChunkBuffer = mChunkBuffer.substr( pos );
|
||||
}
|
||||
|
||||
// If still the chunk is not empty it could be another chunk
|
||||
// already received, so we check that retrying
|
||||
if ( !mChunkBuffer.empty() ) {
|
||||
std::string::size_type lenEnd = mChunkBuffer.find_first_of("\r\n");
|
||||
|
||||
if ( lenEnd != std::string::npos ) {
|
||||
bool res = String::fromString( length, mChunkBuffer.substr(0, lenEnd), std::hex );
|
||||
|
||||
if ( res && length > 0 ) {
|
||||
retry = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the next chunk received starts with \r\n it's because
|
||||
// it's part of the chunk size information, so we need to flag it
|
||||
// to remove it
|
||||
mChunkNewBuffer = true;
|
||||
}
|
||||
} else {
|
||||
// If the value is 0 means that the data ended
|
||||
// But after this we can receive extra headers
|
||||
mChunkEnded = true;
|
||||
mChunkBuffer.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( retry );
|
||||
} else {
|
||||
mHeaderBuffer.append( data, size );
|
||||
}
|
||||
|
||||
return writeTotal;
|
||||
}
|
||||
|
||||
const std::string& HttpStreamChunked::getHeaderBuffer() const {
|
||||
return mHeaderBuffer;
|
||||
}
|
||||
|
||||
}}}
|
||||
28
src/eepp/network/http/httpstreamchunked.hpp
Normal file
28
src/eepp/network/http/httpstreamchunked.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef EE_NETWORK_HTTPSTREAMCHUNKED_HPP
|
||||
#define EE_NETWORK_HTTPSTREAMCHUNKED_HPP
|
||||
|
||||
#include <eepp/system/iostreamstring.hpp>
|
||||
#include <eepp/core/string.hpp>
|
||||
|
||||
using namespace EE::System;
|
||||
|
||||
namespace EE { namespace Network { namespace Private {
|
||||
|
||||
class HttpStreamChunked : public IOStreamString {
|
||||
public:
|
||||
HttpStreamChunked( IOStream& mWriteTo );
|
||||
|
||||
ios_size write( const char * data, ios_size size );
|
||||
|
||||
const std::string& getHeaderBuffer() const;
|
||||
protected:
|
||||
IOStream& mWriteTo;
|
||||
std::string mChunkBuffer;
|
||||
std::string mHeaderBuffer;
|
||||
bool mChunkNewBuffer = false;
|
||||
bool mChunkEnded = false;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif // EE_NETWORK_HTTPSTREAMCHUNKED_HPP
|
||||
@@ -57,6 +57,20 @@ Socket::Status SocketImpl::getErrorStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
void SocketImpl::setSendTimeout(SocketHandle sock, const Time& timeout) {
|
||||
struct timeval time;
|
||||
time.tv_sec = static_cast<long>(timeout.asMicroseconds() / 1000000);
|
||||
time.tv_usec = static_cast<long>(timeout.asMicroseconds() % 1000000);
|
||||
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&time, sizeof time);
|
||||
}
|
||||
|
||||
void SocketImpl::setReceiveTimeout(SocketHandle sock, const Time & timeout) {
|
||||
struct timeval time;
|
||||
time.tv_sec = static_cast<long>(timeout.asMicroseconds() / 1000000);
|
||||
time.tv_usec = static_cast<long>(timeout.asMicroseconds() % 1000000);
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&time, sizeof time);
|
||||
}
|
||||
|
||||
}}}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#if defined( EE_PLATFORM_POSIX )
|
||||
|
||||
#include <eepp/system/time.hpp>
|
||||
#include <eepp/network/socket.hpp>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -14,6 +15,8 @@
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace EE::System;
|
||||
|
||||
namespace EE { namespace Network { namespace Private {
|
||||
|
||||
/** @brief Helper class implementing all the non-portable socket stuff; this is the Unix version */
|
||||
@@ -44,6 +47,12 @@ class SocketImpl {
|
||||
/** Get the last socket error status
|
||||
** @return Status corresponding to the last socket error */
|
||||
static Socket::Status getErrorStatus();
|
||||
|
||||
/** Set the send timeout */
|
||||
static void setSendTimeout(SocketHandle sock, const Time& timeout);
|
||||
|
||||
/** Set the receive timeout */
|
||||
static void setReceiveTimeout(SocketHandle sock, const Time& timeout);
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
@@ -42,6 +42,16 @@ Socket::Status SocketImpl::getErrorStatus() {
|
||||
}
|
||||
}
|
||||
|
||||
void SocketImpl::setSendTimeout(SocketHandle sock, const Time& timeout) {
|
||||
DWORD time = timeout.asMilliseconds();
|
||||
setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&time, sizeof time);
|
||||
}
|
||||
|
||||
void SocketImpl::setReceiveTimeout(SocketHandle sock, const Time & timeout) {
|
||||
DWORD time = timeout.asMilliseconds();
|
||||
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&time, sizeof time);
|
||||
}
|
||||
|
||||
/** Windows needs some initialization and cleanup to get
|
||||
** sockets working properly... so let's create a class that will do it automatically */
|
||||
struct SocketInitializer
|
||||
|
||||
@@ -47,6 +47,12 @@ class SocketImpl {
|
||||
/** Get the last socket error status
|
||||
** @return Status corresponding to the last socket error */
|
||||
static Socket::Status getErrorStatus();
|
||||
|
||||
/** Set the send timeout */
|
||||
static void setSendTimeout(SocketHandle sock, const Time& timeout);
|
||||
|
||||
/** Set the receive timeout */
|
||||
static void setReceiveTimeout(SocketHandle sock, const Time& timeout);
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
@@ -14,7 +14,7 @@ bool MbedTLSSocket::init() {
|
||||
mbedtls_x509_crt_init(&sCACert);
|
||||
|
||||
//! Load the certificates and config
|
||||
SafeDataPointer data;
|
||||
ScopedBuffer data;
|
||||
|
||||
if ( FileSystem::fileExists( SSLSocket::CertificatesPath ) ) {
|
||||
FileSystem::fileGet( SSLSocket::CertificatesPath, data );
|
||||
@@ -28,12 +28,12 @@ bool MbedTLSSocket::init() {
|
||||
}
|
||||
}
|
||||
|
||||
if ( data.size > 0 ) {
|
||||
SafeDataPointer dataZeroEnded( data.size + 1 );
|
||||
memcpy( dataZeroEnded.data, data.data, data.size );
|
||||
dataZeroEnded.data[ data.size ] = '\0';
|
||||
if ( data.length() > 0 ) {
|
||||
ScopedBuffer dataZeroEnded( data.length() + 1 );
|
||||
memcpy( dataZeroEnded.get(), data.get(), data.length() );
|
||||
dataZeroEnded[ data.length() ] = '\0';
|
||||
|
||||
int err = mbedtls_x509_crt_parse( &sCACert, (const unsigned char*)dataZeroEnded.data, dataZeroEnded.size );
|
||||
int err = mbedtls_x509_crt_parse( &sCACert, (const unsigned char*)dataZeroEnded.get(), dataZeroEnded.length() );
|
||||
|
||||
if ( err != 0 ) {
|
||||
char errStr[ 1024 ];
|
||||
@@ -72,7 +72,7 @@ int MbedTLSSocket::bio_send(void *ctx, const unsigned char *buf, size_t len) {
|
||||
MbedTLSSocket *sp = (MbedTLSSocket *)ctx;
|
||||
|
||||
size_t sent;
|
||||
Socket::Status err = sp->mSSLSocket->tcp_send((const void*)buf, len, sent);
|
||||
Socket::Status err = sp->mSSLSocket->tcpSend((const void*)buf, len, sent);
|
||||
|
||||
if (err != Socket::Done) {
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
@@ -90,7 +90,7 @@ int MbedTLSSocket::bio_recv(void *ctx, unsigned char *buf, size_t len) {
|
||||
MbedTLSSocket *sp = (MbedTLSSocket *)ctx;
|
||||
|
||||
size_t got;
|
||||
Socket::Status err = sp->mSSLSocket->tcp_receive(buf, len, got);
|
||||
Socket::Status err = sp->mSSLSocket->tcpReceive(buf, len, got);
|
||||
|
||||
if (err != Socket::Done) {
|
||||
return MBEDTLS_ERR_SSL_INTERNAL_ERROR;
|
||||
|
||||
@@ -152,13 +152,13 @@ bool OpenSSLSocket::init() {
|
||||
|
||||
//! Load the certificates and config
|
||||
if ( FileSystem::fileExists( SSLSocket::CertificatesPath ) ) {
|
||||
SafeDataPointer data;
|
||||
ScopedBuffer data;
|
||||
FileSystem::fileGet( SSLSocket::CertificatesPath, data );
|
||||
|
||||
if ( data.size > 0 ) {
|
||||
if ( data.length() > 0 ) {
|
||||
BIO* mem = BIO_new(BIO_s_mem());
|
||||
|
||||
BIO_puts( mem, (const char*) data.data );
|
||||
BIO_puts( mem, (const char*) data.get() );
|
||||
|
||||
while( true ) {
|
||||
X509 * cert = PEM_read_bio_X509(mem, NULL, 0, NULL);
|
||||
|
||||
@@ -134,16 +134,17 @@ SSLSocket::~SSLSocket() {
|
||||
Socket::Status SSLSocket::connect( const IpAddress& remoteAddress, unsigned short remotePort, Time timeout ) {
|
||||
Status status = Socket::Disconnected;
|
||||
|
||||
if ( ( status = TcpSocket::connect( remoteAddress, remotePort, timeout ) ) == Socket::Done ) {
|
||||
status = mImpl->connect( remoteAddress, remotePort, timeout );
|
||||
if ( ( status = tcpConnect( remoteAddress, remotePort, timeout ) ) == Socket::Done ) {
|
||||
status = sslConnect( remoteAddress, remotePort, timeout );
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void SSLSocket::disconnect() {
|
||||
mImpl->disconnect();
|
||||
TcpSocket::disconnect();
|
||||
sslDisconnect();
|
||||
|
||||
tcpDisconnect();
|
||||
}
|
||||
|
||||
Socket::Status SSLSocket::send(const void* data, std::size_t size) {
|
||||
@@ -162,11 +163,27 @@ Socket::Status SSLSocket::receive(Packet& packet) {
|
||||
return TcpSocket::receive( packet );
|
||||
}
|
||||
|
||||
Socket::Status SSLSocket::tcp_receive(void * data, std::size_t size, std::size_t & received) {
|
||||
Socket::Status SSLSocket::sslConnect(const IpAddress & remoteAddress, unsigned short remotePort, Time timeout) {
|
||||
return mImpl->connect( remoteAddress, remotePort, timeout );
|
||||
}
|
||||
|
||||
void SSLSocket::sslDisconnect() {
|
||||
mImpl->disconnect();
|
||||
}
|
||||
|
||||
Socket::Status SSLSocket::tcpConnect(const IpAddress & remoteAddress, unsigned short remotePort, Time timeout) {
|
||||
return TcpSocket::connect( remoteAddress, remotePort, timeout );
|
||||
}
|
||||
|
||||
void SSLSocket::tcpDisconnect() {
|
||||
TcpSocket::disconnect();
|
||||
}
|
||||
|
||||
Socket::Status SSLSocket::tcpReceive(void * data, std::size_t size, std::size_t & received) {
|
||||
return TcpSocket::receive( data, size, received );
|
||||
}
|
||||
|
||||
Socket::Status SSLSocket::tcp_send(const void * data, std::size_t size, std::size_t & sent) {
|
||||
Socket::Status SSLSocket::tcpSend(const void * data, std::size_t size, std::size_t & sent) {
|
||||
return TcpSocket::send( data, size, sent );
|
||||
}
|
||||
|
||||
|
||||
@@ -316,6 +316,18 @@ Socket::Status TcpSocket::receive(Packet& packet) {
|
||||
return Done;
|
||||
}
|
||||
|
||||
void TcpSocket::setSendTimeout(SocketHandle sock, const Time& timeout) {
|
||||
if (getHandle() != Private::SocketImpl::invalidSocket()) {
|
||||
Private::SocketImpl::setSendTimeout(getHandle(), timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void TcpSocket::setReceiveTimeout(SocketHandle sock, const Time& timeout) {
|
||||
if (getHandle() != Private::SocketImpl::invalidSocket()) {
|
||||
Private::SocketImpl::setReceiveTimeout(getHandle(), timeout);
|
||||
}
|
||||
}
|
||||
|
||||
TcpSocket::PendingPacket::PendingPacket() :
|
||||
Size (0),
|
||||
SizeReceived(0),
|
||||
|
||||
@@ -61,8 +61,7 @@ Socket::Status UdpSocket::send(const void* data, std::size_t size, const IpAddre
|
||||
create();
|
||||
|
||||
// Make sure that all the data will fit in one datagram
|
||||
if (size > MaxDatagramSize)
|
||||
{
|
||||
if (size > MaxDatagramSize) {
|
||||
eePRINTL( "Cannot send data over the network (the number of bytes to send is greater than UdpSocket::MaxDatagramSize)" );
|
||||
return Error;
|
||||
}
|
||||
@@ -143,5 +142,16 @@ Socket::Status UdpSocket::receive(Packet& packet, IpAddress& remoteAddress, unsi
|
||||
return status;
|
||||
}
|
||||
|
||||
void UdpSocket::setSendTimeout(SocketHandle sock, const Time& timeout) {
|
||||
if (getHandle() != Private::SocketImpl::invalidSocket()) {
|
||||
Private::SocketImpl::setSendTimeout(getHandle(), timeout);
|
||||
}
|
||||
}
|
||||
|
||||
void UdpSocket::setReceiveTimeout(SocketHandle sock, const Time& timeout) {
|
||||
if (getHandle() != Private::SocketImpl::invalidSocket()) {
|
||||
Private::SocketImpl::setReceiveTimeout(getHandle(), timeout);
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -411,6 +411,17 @@ void URI::getPathSegments(std::vector<std::string>& segments) {
|
||||
getPathSegments(mPath, segments);
|
||||
}
|
||||
|
||||
std::string URI::getLastPathSegment() {
|
||||
std::vector<std::string> segments;
|
||||
getPathSegments( segments );
|
||||
|
||||
if ( !segments.empty() ) {
|
||||
return segments[ segments.size() - 1 ];
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
void URI::getPathSegments(const std::string& path, std::vector<std::string>& segments) {
|
||||
std::string::const_iterator it = path.begin();
|
||||
std::string::const_iterator end = path.end();
|
||||
|
||||
167
src/eepp/system/compression.cpp
Normal file
167
src/eepp/system/compression.cpp
Normal file
@@ -0,0 +1,167 @@
|
||||
#include <eepp/system/compression.hpp>
|
||||
#include <eepp/system/scopedbuffer.hpp>
|
||||
#include <eepp/system/iostreammemory.hpp>
|
||||
#include <eepp/core/debug.hpp>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
#define DEFLATE_CHUNK_SIZE (16384)
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
Compression::Status Compression::compress(Uint8* dst, Uint64 dstMaxSize, const Uint8* src, Uint64 srcSize, Mode mode, const Config& config) {
|
||||
IOStreamMemory srcMem( (const char*)src, srcSize );
|
||||
IOStreamMemory dstMem( (char*)dst, dstMaxSize );
|
||||
return compress( dstMem, srcMem, mode, config );
|
||||
}
|
||||
|
||||
Compression::Status Compression::compress(IOStream& dst, IOStream& src, Compression::Mode mode, const Config& config) {
|
||||
switch (mode) {
|
||||
case MODE_DEFLATE:
|
||||
case MODE_GZIP:
|
||||
{
|
||||
int ret, flush;
|
||||
ios_size have;
|
||||
z_stream strm = {};
|
||||
char in[DEFLATE_CHUNK_SIZE];
|
||||
char out[DEFLATE_CHUNK_SIZE];
|
||||
int level = mode == MODE_DEFLATE ? config.zlib.level : config.gzip.level;
|
||||
int windowBits = mode == Compression::MODE_DEFLATE ? MAX_WBITS : MAX_WBITS | 16;
|
||||
|
||||
ret = deflateInit2(&strm, level, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
|
||||
if (ret != Z_OK)
|
||||
return (Status)ret;
|
||||
|
||||
src.seek(0);
|
||||
|
||||
do {
|
||||
strm.avail_in = src.read(in, DEFLATE_CHUNK_SIZE);
|
||||
if ( strm.avail_in == 0 ) {
|
||||
deflateEnd(&strm);
|
||||
return Status::ERRNO;
|
||||
}
|
||||
|
||||
flush = src.tell() == src.getSize() ? Z_FINISH : Z_NO_FLUSH;
|
||||
strm.next_in = (unsigned char*)in;
|
||||
|
||||
do {
|
||||
strm.avail_out = DEFLATE_CHUNK_SIZE;
|
||||
strm.next_out = (unsigned char*)out;
|
||||
|
||||
ret = deflate(&strm, flush);
|
||||
|
||||
if ( ret == Z_STREAM_ERROR )
|
||||
return Status::STREAM_ERROR;
|
||||
|
||||
have = DEFLATE_CHUNK_SIZE - strm.avail_out;
|
||||
|
||||
if ( dst.write(out, have) != have ) {
|
||||
deflateEnd(&strm);
|
||||
|
||||
return Status::ERRNO;
|
||||
}
|
||||
} while (strm.avail_out == 0);
|
||||
|
||||
if (strm.avail_in != 0)
|
||||
return Status::DATA_ERROR;
|
||||
} while (flush != Z_FINISH);
|
||||
}
|
||||
}
|
||||
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
int Compression::getMaxCompressedBufferSize(Uint64 srcSize, Mode mode, const Config&) {
|
||||
switch (mode) {
|
||||
case MODE_DEFLATE:
|
||||
case MODE_GZIP:
|
||||
{
|
||||
int windowBits = mode == MODE_DEFLATE ? MAX_WBITS : MAX_WBITS | 16;
|
||||
|
||||
z_stream strm = {};
|
||||
int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
|
||||
if (err != Z_OK)
|
||||
return -1;
|
||||
int aout = deflateBound(&strm, srcSize);
|
||||
deflateEnd(&strm);
|
||||
return aout;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
Compression::Status Compression::decompress(Uint8* dst, Uint64 dstMaxSize, const Uint8 * src, Uint64 srcSize, Mode mode) {
|
||||
IOStreamMemory srcMem( (const char*)src, srcSize );
|
||||
IOStreamMemory dstMem( (char*)dst, dstMaxSize );
|
||||
return decompress( dstMem, srcMem, mode );
|
||||
}
|
||||
|
||||
Compression::Status Compression::decompress(IOStream& dst, IOStream& src, Mode mode) {
|
||||
switch (mode) {
|
||||
case MODE_DEFLATE:
|
||||
case MODE_GZIP:
|
||||
{
|
||||
ScopedBuffer buffer( DEFLATE_CHUNK_SIZE );
|
||||
ScopedBuffer bufferDst( DEFLATE_CHUNK_SIZE );
|
||||
|
||||
src.seek( 0 );
|
||||
|
||||
int windowBits = mode == Compression::MODE_DEFLATE ? MAX_WBITS : MAX_WBITS | 16;
|
||||
|
||||
z_stream strm = {};
|
||||
strm.next_in = buffer.get();
|
||||
|
||||
int err = inflateInit2(&strm, windowBits);
|
||||
if (err != Z_OK)
|
||||
return (Status)err;
|
||||
|
||||
int zlibStatus;
|
||||
int bytesRead;
|
||||
unsigned int have;
|
||||
Uint32 totalSize = src.getSize();
|
||||
Uint32 totalRead = 0;
|
||||
|
||||
while ( totalRead < totalSize ) {
|
||||
bytesRead = src.read( (char*)buffer.get(), buffer.length() );
|
||||
|
||||
strm.avail_in = bytesRead;
|
||||
strm.next_in = buffer.get();
|
||||
|
||||
do {
|
||||
strm.avail_out = bufferDst.length();
|
||||
strm.next_out = bufferDst.get();
|
||||
zlibStatus = inflate(&strm, Z_NO_FLUSH);
|
||||
|
||||
switch (zlibStatus) {
|
||||
case Z_OK:
|
||||
case Z_STREAM_END:
|
||||
case Z_BUF_ERROR:
|
||||
break;
|
||||
default:
|
||||
inflateEnd(&strm);
|
||||
return (Status)zlibStatus;
|
||||
}
|
||||
|
||||
have = bufferDst.length()- strm.avail_out;
|
||||
|
||||
dst.write( (const char*)bufferDst.get(), have );
|
||||
} while (strm.avail_out == 0);
|
||||
|
||||
totalRead += bytesRead;
|
||||
}
|
||||
|
||||
inflateEnd(&strm);
|
||||
|
||||
return Status::OK;
|
||||
}
|
||||
}
|
||||
|
||||
return Status::ERRNO;
|
||||
}
|
||||
|
||||
std::size_t Compression::getModeDefaultChunkSize(const Mode&) {
|
||||
return DEFLATE_CHUNK_SIZE;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -88,7 +88,7 @@ bool DirectoryPack::extractFileToMemory( const std::string& path, std::vector<Ui
|
||||
return FileSystem::fileGet( mPath + path, data );
|
||||
}
|
||||
|
||||
bool DirectoryPack::extractFileToMemory( const std::string& path, SafeDataPointer& data ) {
|
||||
bool DirectoryPack::extractFileToMemory( const std::string& path, ScopedBuffer& data ) {
|
||||
return FileSystem::fileGet( mPath + path, data );
|
||||
}
|
||||
|
||||
|
||||
@@ -47,16 +47,13 @@ std::string FileSystem::getOSSlash() {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool FileSystem::fileGet( const std::string& path, SafeDataPointer& data ) {
|
||||
bool FileSystem::fileGet( const std::string& path, ScopedBuffer& data ) {
|
||||
if ( fileExists( path ) ) {
|
||||
IOStreamFile fs ( path );
|
||||
|
||||
eeSAFE_DELETE( data.data );
|
||||
data.reset( fileSize( path ) );
|
||||
|
||||
data.size = fileSize( path );
|
||||
data.data = eeNewArray( Uint8, ( data.size ) );
|
||||
|
||||
fs.read( reinterpret_cast<char*> ( data.data ), data.size );
|
||||
fs.read( reinterpret_cast<char*> ( data.get() ), data.length() );
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -88,10 +85,8 @@ bool FileSystem::fileCopy( const std::string& src, const std::string& dst ) {
|
||||
Int64 allocate = ( size < chunksize ) ? size : chunksize;
|
||||
Int64 copysize = 0;
|
||||
|
||||
SafeDataPointer data;
|
||||
data.size = (Uint32)allocate;
|
||||
data.data = eeNewArray( Uint8, ( data.size ) );
|
||||
char * buff = (char*)data.data;
|
||||
TScopedBuffer<char> data( allocate );
|
||||
char * buff = data.get();
|
||||
|
||||
IOStreamFile in( src, "rb" );
|
||||
IOStreamFile out( dst, "wb" );
|
||||
@@ -105,7 +100,7 @@ bool FileSystem::fileCopy( const std::string& src, const std::string& dst ) {
|
||||
}
|
||||
|
||||
in.read ( &buff[0], copysize );
|
||||
out.write ( (const char*)&buff[0], copysize );
|
||||
out.write ( &buff[0], copysize );
|
||||
|
||||
size_left -= copysize;
|
||||
} while ( size_left > 0 );
|
||||
@@ -580,4 +575,24 @@ Int64 FileSystem::getDiskFreeSpace(const std::string& path) {
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string FileSystem::fileGetNumberedFileNameFromPath(std::string directoryPath, const std::string& fileName, const std::string& separator, const std::string& fileExtension) {
|
||||
Uint32 fileNum = 1;
|
||||
std::string fileNumName;
|
||||
|
||||
if ( FileSystem::isDirectory( directoryPath ) ) {
|
||||
dirPathAddSlashAtEnd( directoryPath );
|
||||
|
||||
while ( fileNum < 10000 ) {
|
||||
fileNumName = String::format( std::string( "%s" + separator + "%d%s" ).c_str(), fileName.c_str(), fileNum, fileExtension.empty() ? "" : std::string( "." + fileExtension ).c_str() );
|
||||
|
||||
if ( !FileSystem::fileExists( directoryPath + fileNumName ) )
|
||||
return fileNumName;
|
||||
|
||||
fileNum++;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -56,11 +56,11 @@ IniFile::IniFile( IOStream& stream, const bool& shouldReadFile ) :
|
||||
|
||||
bool IniFile::loadFromPack( Pack * Pack, std::string iniPackPath ) {
|
||||
if ( NULL != Pack && Pack->isOpen() && -1 != Pack->exists( iniPackPath ) ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
Pack->extractFileToMemory( iniPackPath, PData );
|
||||
Pack->extractFileToMemory( iniPackPath, buffer );
|
||||
|
||||
return loadFromMemory( PData.data, PData.size );
|
||||
return loadFromMemory( buffer.get(), buffer.length() );
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
193
src/eepp/system/iostreamdeflate.cpp
Normal file
193
src/eepp/system/iostreamdeflate.cpp
Normal file
@@ -0,0 +1,193 @@
|
||||
#include <eepp/system/iostreamdeflate.hpp>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
struct LocalStreamData {
|
||||
z_stream strm;
|
||||
int state;
|
||||
bool writedStream;
|
||||
};
|
||||
|
||||
IOStreamDeflate * IOStreamDeflate::New(IOStream& inOutStream, Compression::Mode mode, const Compression::Config& config) {
|
||||
return eeNew( IOStreamDeflate, ( inOutStream, mode ) );
|
||||
}
|
||||
|
||||
IOStreamDeflate::IOStreamDeflate(IOStream& inOutStream, Compression::Mode mode, const Compression::Config& config) :
|
||||
mStream(inOutStream),
|
||||
mMode(mode),
|
||||
mBuffer(Compression::getModeDefaultChunkSize(mode)),
|
||||
mLocalStream(eeNew(LocalStreamData,()))
|
||||
{
|
||||
int windowBits = mode == Compression::MODE_DEFLATE ? MAX_WBITS : MAX_WBITS | 16;
|
||||
int level = mode == Compression::MODE_DEFLATE ? config.zlib.level : config.gzip.level;
|
||||
|
||||
mLocalStream->strm = z_stream{};
|
||||
mLocalStream->writedStream = false;
|
||||
|
||||
mLocalStream->state = deflateInit2(&mLocalStream->strm, level, Z_DEFLATED, windowBits, 8, Z_DEFAULT_STRATEGY);
|
||||
}
|
||||
|
||||
IOStreamDeflate::~IOStreamDeflate() {
|
||||
if (mStream.isOpen() && mLocalStream->writedStream) {
|
||||
z_stream& zstr = mLocalStream->strm;
|
||||
|
||||
if (zstr.next_out) {
|
||||
int rc = deflate(&zstr, Z_FINISH);
|
||||
|
||||
if (rc != Z_OK && rc != Z_STREAM_END) return;
|
||||
|
||||
mStream.write((char*)mBuffer.get(), mBuffer.length() - zstr.avail_out);
|
||||
|
||||
if (!mStream.isOpen()) return;
|
||||
|
||||
zstr.next_out = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_out = mBuffer.length();
|
||||
|
||||
while (rc != Z_STREAM_END) {
|
||||
rc = deflate(&zstr, Z_FINISH);
|
||||
|
||||
if (rc != Z_OK && rc != Z_STREAM_END) return;
|
||||
|
||||
mStream.write((char*)mBuffer.get(), mBuffer.length() - zstr.avail_out);
|
||||
|
||||
if (!mStream.isOpen()) return;
|
||||
|
||||
zstr.next_out = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_out = mBuffer.length();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deflateEnd( &mLocalStream->strm );
|
||||
|
||||
eeSAFE_DELETE( mLocalStream );
|
||||
}
|
||||
|
||||
ios_size IOStreamDeflate::read(char * buffer, ios_size length) {
|
||||
if ( mLocalStream->state != Z_OK || !mStream.isOpen() )
|
||||
return 0;
|
||||
|
||||
z_stream& zstr = mLocalStream->strm;
|
||||
|
||||
bool eof = false;
|
||||
|
||||
if (zstr.avail_in == 0) {
|
||||
ios_size n = 0;
|
||||
|
||||
if ( mStream.isOpen()) {
|
||||
n = mStream.read((char*)mBuffer.get(), mBuffer.length());
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
zstr.next_in = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_in = n;
|
||||
} else {
|
||||
zstr.next_in = NULL;
|
||||
zstr.avail_in = 0;
|
||||
eof = true;
|
||||
}
|
||||
}
|
||||
|
||||
zstr.next_out = (unsigned char*) buffer;
|
||||
zstr.avail_out = length;
|
||||
|
||||
for (;;) {
|
||||
int rc = deflate(&zstr, eof ? Z_FINISH : Z_NO_FLUSH);
|
||||
|
||||
if (eof && rc == Z_STREAM_END) {
|
||||
return length - zstr.avail_out;
|
||||
}
|
||||
|
||||
if (rc != Z_OK)
|
||||
return 0;
|
||||
|
||||
if (zstr.avail_out == 0)
|
||||
return static_cast<int>(length);
|
||||
|
||||
if (zstr.avail_in == 0) {
|
||||
ios_size n = 0;
|
||||
|
||||
if (mStream.isOpen()) {
|
||||
n = mStream.read((char*)mBuffer.get(), mBuffer.length());
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
zstr.next_in = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_in = n;
|
||||
} else {
|
||||
zstr.next_in = NULL;
|
||||
zstr.avail_in = 0;
|
||||
eof = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ios_size IOStreamDeflate::write(const char * buffer, ios_size length) {
|
||||
mLocalStream->writedStream = true;
|
||||
|
||||
if ( mLocalStream->state != Z_OK || !mStream.isOpen() || length == 0 )
|
||||
return 0;
|
||||
|
||||
z_stream& zstr = mLocalStream->strm;
|
||||
|
||||
zstr.next_in = (unsigned char*) buffer;
|
||||
zstr.avail_in = length;
|
||||
zstr.next_out = mBuffer.get();
|
||||
zstr.avail_out = mBuffer.length();
|
||||
|
||||
for (;;) {
|
||||
int rc = deflate(&zstr, Z_NO_FLUSH);
|
||||
|
||||
if (rc != Z_OK)
|
||||
return 0;
|
||||
|
||||
if (zstr.avail_out == 0) {
|
||||
ios_size ret = mStream.write( (const char*)mBuffer.get(), mBuffer.length());
|
||||
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
zstr.next_out = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_out = mBuffer.length();
|
||||
}
|
||||
|
||||
if (zstr.avail_in == 0) {
|
||||
ios_size ret = mStream.write( (const char*)mBuffer.get(), mBuffer.length() - zstr.avail_out);
|
||||
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
zstr.next_out = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_out = mBuffer.length();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
ios_size IOStreamDeflate::seek(ios_size position) {
|
||||
return mStream.seek( position );
|
||||
}
|
||||
|
||||
ios_size IOStreamDeflate::tell() {
|
||||
return mStream.tell();
|
||||
}
|
||||
|
||||
ios_size IOStreamDeflate::getSize() {
|
||||
return mStream.getSize();
|
||||
}
|
||||
|
||||
bool IOStreamDeflate::isOpen() {
|
||||
return mStream.isOpen();
|
||||
}
|
||||
|
||||
const Compression::Mode& IOStreamDeflate::getMode() const {
|
||||
return mMode;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -15,9 +15,7 @@ IOStreamFile::IOStreamFile( const std::string& path, const char * modes ) :
|
||||
}
|
||||
|
||||
IOStreamFile::~IOStreamFile() {
|
||||
if ( isOpen() ) {
|
||||
std::fclose(mFS);
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
ios_size IOStreamFile::read( char * data, ios_size size ) {
|
||||
@@ -80,4 +78,12 @@ void IOStreamFile::flush() {
|
||||
std::fflush( mFS );
|
||||
}
|
||||
|
||||
void IOStreamFile::close() {
|
||||
if ( isOpen() ) {
|
||||
std::fclose(mFS);
|
||||
|
||||
mFS = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
165
src/eepp/system/iostreaminflate.cpp
Normal file
165
src/eepp/system/iostreaminflate.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
#include <eepp/system/iostreaminflate.hpp>
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
struct LocalStreamData {
|
||||
z_stream strm;
|
||||
int state;
|
||||
};
|
||||
|
||||
IOStreamInflate * IOStreamInflate::New(IOStream& inOutStream, Compression::Mode mode) {
|
||||
return eeNew( IOStreamInflate, ( inOutStream, mode ) );
|
||||
}
|
||||
|
||||
IOStreamInflate::IOStreamInflate(IOStream& inOutStream, Compression::Mode mode) :
|
||||
mStream(inOutStream),
|
||||
mMode(mode),
|
||||
mBuffer(Compression::getModeDefaultChunkSize(mode)),
|
||||
mLocalStream(eeNew(LocalStreamData,()))
|
||||
{
|
||||
int windowBits = mode == Compression::MODE_DEFLATE ? MAX_WBITS : MAX_WBITS | 16;
|
||||
|
||||
mLocalStream->strm = z_stream{};
|
||||
|
||||
mLocalStream->state = inflateInit2(&mLocalStream->strm, windowBits);
|
||||
}
|
||||
|
||||
IOStreamInflate::~IOStreamInflate() {
|
||||
inflateEnd( &mLocalStream->strm );
|
||||
|
||||
eeSAFE_DELETE( mLocalStream );
|
||||
}
|
||||
|
||||
ios_size IOStreamInflate::read(char * buffer, ios_size length) {
|
||||
if ( mLocalStream->state != Z_OK || !mStream.isOpen() )
|
||||
return 0;
|
||||
|
||||
z_stream& zstr = mLocalStream->strm;
|
||||
|
||||
if (zstr.avail_in == 0) {
|
||||
ios_size n = 0;
|
||||
|
||||
if ( mStream.isOpen()) {
|
||||
n = mStream.read((char*)mBuffer.get(), mBuffer.length());
|
||||
}
|
||||
|
||||
zstr.next_in = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_in = n;
|
||||
}
|
||||
|
||||
zstr.next_out = (unsigned char*) buffer;
|
||||
zstr.avail_out = length;
|
||||
|
||||
for (;;) {
|
||||
int rc = inflate(&zstr, Z_NO_FLUSH);
|
||||
|
||||
if (rc == Z_DATA_ERROR) {
|
||||
if (zstr.avail_in == 0) {
|
||||
if (mStream.isOpen())
|
||||
rc = Z_OK;
|
||||
else
|
||||
rc = Z_STREAM_END;
|
||||
}
|
||||
}
|
||||
|
||||
if (rc == Z_STREAM_END) {
|
||||
return length - zstr.avail_out;
|
||||
}
|
||||
|
||||
if (rc != Z_OK)
|
||||
return 0;
|
||||
|
||||
if (zstr.avail_out == 0)
|
||||
return static_cast<int>(length);
|
||||
|
||||
if (zstr.avail_in == 0) {
|
||||
ios_size n = 0;
|
||||
|
||||
if (mStream.isOpen()) {
|
||||
n = mStream.read((char*)mBuffer.get(), mBuffer.length());
|
||||
}
|
||||
|
||||
if (n > 0) {
|
||||
zstr.next_in = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_in = n;
|
||||
} else {
|
||||
return length - zstr.avail_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ios_size IOStreamInflate::write(const char * buffer, ios_size length) {
|
||||
if ( mLocalStream->state != Z_OK || !mStream.isOpen() || length == 0 )
|
||||
return 0;
|
||||
|
||||
z_stream& zstr = mLocalStream->strm;
|
||||
|
||||
zstr.next_in = (unsigned char*) buffer;
|
||||
zstr.avail_in = length;
|
||||
zstr.next_out = mBuffer.get();
|
||||
zstr.avail_out = mBuffer.length();
|
||||
|
||||
for (;;) {
|
||||
int rc = inflate(&zstr, Z_NO_FLUSH);
|
||||
|
||||
if (rc == Z_STREAM_END) {
|
||||
length = mStream.write( (const char*)mBuffer.get(), mBuffer.length() - zstr.avail_out);
|
||||
|
||||
mLocalStream->state = rc;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc != Z_OK)
|
||||
return 0;
|
||||
|
||||
if (zstr.avail_out == 0) {
|
||||
ios_size ret = mStream.write( (const char*)mBuffer.get(), mBuffer.length());
|
||||
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
zstr.next_out = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_out = mBuffer.length();
|
||||
}
|
||||
|
||||
if (zstr.avail_in == 0) {
|
||||
ios_size ret = mStream.write( (const char*)mBuffer.get(), mBuffer.length() - zstr.avail_out);
|
||||
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
zstr.next_out = (unsigned char*) mBuffer.get();
|
||||
zstr.avail_out = mBuffer.length();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
ios_size IOStreamInflate::seek(ios_size position) {
|
||||
return mStream.seek( position );
|
||||
}
|
||||
|
||||
ios_size IOStreamInflate::tell() {
|
||||
return mStream.tell();
|
||||
}
|
||||
|
||||
ios_size IOStreamInflate::getSize() {
|
||||
return mStream.getSize();
|
||||
}
|
||||
|
||||
bool IOStreamInflate::isOpen() {
|
||||
return mStream.isOpen() && mLocalStream->state != Z_STREAM_END;
|
||||
}
|
||||
|
||||
const Compression::Mode& IOStreamInflate::getMode() const {
|
||||
return mMode;
|
||||
}
|
||||
|
||||
}}
|
||||
68
src/eepp/system/iostreamstring.cpp
Normal file
68
src/eepp/system/iostreamstring.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include <eepp/system/iostreamstring.hpp>
|
||||
#include <cstring>
|
||||
|
||||
namespace EE { namespace System {
|
||||
|
||||
IOStreamString::IOStreamString() :
|
||||
mPos(0)
|
||||
{}
|
||||
|
||||
ios_size IOStreamString::read(char * data, ios_size size) {
|
||||
Int64 endPosition = mPos + size;
|
||||
Int64 count = endPosition <= getSize() ? size : getSize() - mPos;
|
||||
|
||||
if ( count > 0 ) {
|
||||
memcpy( data, &mStream[mPos], static_cast<std::size_t>( count ) );
|
||||
mPos += count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
ios_size IOStreamString::write(const char * data, ios_size size) {
|
||||
mStream.insert( mPos, data, size );
|
||||
|
||||
mPos += size;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
ios_size IOStreamString::write(const std::string& string) {
|
||||
return write( string.c_str(), string.size() );
|
||||
}
|
||||
|
||||
ios_size IOStreamString::seek(ios_size position) {
|
||||
mPos = ( position < getSize() ) ? position : getSize();
|
||||
return mPos;
|
||||
}
|
||||
|
||||
ios_size IOStreamString::tell() {
|
||||
return getSize();
|
||||
}
|
||||
|
||||
ios_size IOStreamString::getSize() {
|
||||
return mStream.size();
|
||||
}
|
||||
|
||||
bool IOStreamString::isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void IOStreamString::clear() {
|
||||
mStream.clear();
|
||||
mPos = 0;
|
||||
}
|
||||
|
||||
const char* IOStreamString::getPositionPointer() {
|
||||
return &mStream[mPos];
|
||||
}
|
||||
|
||||
const char* IOStreamString::getStreamPointer() const {
|
||||
return mStream.c_str();
|
||||
}
|
||||
|
||||
const std::string& IOStreamString::getStream() const {
|
||||
return mStream;
|
||||
}
|
||||
|
||||
}}
|
||||
@@ -58,8 +58,8 @@ ios_size IOStreamZip::seek( ios_size position ) {
|
||||
mFile = zip_fopen_index( mZip, zs.index, 0 );
|
||||
|
||||
if ( 0 != position ) {
|
||||
SafeDataPointer ptr( position );
|
||||
read( (char*)ptr.data, position );
|
||||
ScopedBuffer ptr( position );
|
||||
read( (char*)ptr.get(), position );
|
||||
}
|
||||
|
||||
mPos = position;
|
||||
|
||||
@@ -133,10 +133,10 @@ bool Pak::extractFile( const std::string& path , const std::string& dest ) {
|
||||
Int32 Pos = exists( path );
|
||||
|
||||
if ( Pos != -1 ) {
|
||||
SafeDataPointer data;
|
||||
ScopedBuffer data;
|
||||
|
||||
if ( extractFileToMemory( path, data ) ) {
|
||||
FileSystem::fileWrite( path, data.data, data.size );
|
||||
FileSystem::fileWrite( path, data.get(), data.length() );
|
||||
}
|
||||
|
||||
Ret = true;
|
||||
@@ -173,7 +173,7 @@ bool Pak::extractFileToMemory( const std::string& path, std::vector<Uint8>& data
|
||||
return Ret;
|
||||
}
|
||||
|
||||
bool Pak::extractFileToMemory( const std::string& path, SafeDataPointer& data ) {
|
||||
bool Pak::extractFileToMemory( const std::string& path, ScopedBuffer& data ) {
|
||||
if ( NULL == mPak.fs || !mPak.fs->isOpen() ) {
|
||||
return false;
|
||||
}
|
||||
@@ -185,11 +185,10 @@ bool Pak::extractFileToMemory( const std::string& path, SafeDataPointer& data )
|
||||
Int32 Pos = exists( path );
|
||||
|
||||
if ( Pos != -1 ) {
|
||||
data.size = mPakFiles[Pos].file_length;
|
||||
data.data = eeNewArray( Uint8, ( data.size ) );
|
||||
data.reset( mPakFiles[Pos].file_length );
|
||||
|
||||
mPak.fs->seek( mPakFiles[Pos].file_position );
|
||||
mPak.fs->read( reinterpret_cast<char*> ( data.data ), mPakFiles[Pos].file_length );
|
||||
mPak.fs->read( reinterpret_cast<char*> ( data.get() ), data.length() );
|
||||
|
||||
Ret = true;
|
||||
}
|
||||
@@ -279,11 +278,11 @@ bool Pak::addFile( const std::string& path, const std::string& inpack ) {
|
||||
if ( path.size() > 56 )
|
||||
return false;
|
||||
|
||||
SafeDataPointer file;
|
||||
ScopedBuffer file;
|
||||
|
||||
FileSystem::fileGet( path, file );
|
||||
|
||||
return addFile( file.data, file.size, inpack );
|
||||
return addFile( file.get(), file.length(), inpack );
|
||||
}
|
||||
|
||||
bool Pak::addFiles( std::map<std::string, std::string> paths ) {
|
||||
|
||||
@@ -72,13 +72,13 @@ bool RC4::encryptFile( const std::string& SourceFile, const std::string& DestFil
|
||||
if ( !FileSystem::fileExists( SourceFile ) )
|
||||
return false;
|
||||
|
||||
SafeDataPointer data;
|
||||
ScopedBuffer data;
|
||||
|
||||
FileSystem::fileGet( SourceFile, data );
|
||||
|
||||
encryptByte( data.data, data.size );
|
||||
encryptByte( data.get(), data.length() );
|
||||
|
||||
FileSystem::fileWrite( DestFile, data.data, data.size );
|
||||
FileSystem::fileWrite( DestFile, data.get(), data.length() );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -114,11 +114,11 @@ void Translator::loadFromStream( IOStream& stream, std::string lang ) {
|
||||
return;
|
||||
|
||||
ios_size bufferSize = stream.getSize();
|
||||
SafeDataPointer safeDataPointer( bufferSize );
|
||||
stream.read( reinterpret_cast<char*>( safeDataPointer.data ), safeDataPointer.size );
|
||||
TScopedBuffer<char> scopedBuffer( bufferSize );
|
||||
stream.read( scopedBuffer.get(), scopedBuffer.length() );
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_buffer( safeDataPointer.data, safeDataPointer.size );
|
||||
pugi::xml_parse_result result = doc.load_buffer( scopedBuffer.get(), scopedBuffer.length() );
|
||||
|
||||
if ( result ) {
|
||||
loadNodes( doc.first_child(), lang );
|
||||
@@ -130,12 +130,12 @@ void Translator::loadFromStream( IOStream& stream, std::string lang ) {
|
||||
}
|
||||
|
||||
void Translator::loadFromPack( Pack * pack, const std::string& FilePackPath, std::string lang ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( FilePackPath, PData ) ) {
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( FilePackPath, buffer ) ) {
|
||||
lang = lang.size() == 2 ? lang : FileSystem::fileRemoveExtension( FileSystem::fileNameFromPath( FilePackPath ) );
|
||||
|
||||
loadFromMemory( PData.data, PData.size, lang );
|
||||
loadFromMemory( buffer.get(), buffer.length(), lang );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,11 +80,11 @@ bool Zip::close() {
|
||||
}
|
||||
|
||||
bool Zip::addFile( const std::string& path, const std::string& inpack ) {
|
||||
SafeDataPointer file;
|
||||
ScopedBuffer file;
|
||||
|
||||
FileSystem::fileGet( path, file );
|
||||
|
||||
return addFile( file.data, file.size, inpack );
|
||||
return addFile( file.get(), file.length(), inpack );
|
||||
}
|
||||
|
||||
bool Zip::addFile( const Uint8 * data, const Uint32& dataSize, const std::string& inpack ) {
|
||||
@@ -148,12 +148,12 @@ bool Zip::extractFile( const std::string& path , const std::string& dest ) {
|
||||
|
||||
bool Ret;
|
||||
|
||||
SafeDataPointer data;
|
||||
ScopedBuffer data;
|
||||
|
||||
Ret = extractFileToMemory( path, data );
|
||||
|
||||
if ( Ret )
|
||||
FileSystem::fileWrite( dest, data.data, data.size );
|
||||
FileSystem::fileWrite( dest, data.get(), data.length() );
|
||||
|
||||
unlock();
|
||||
|
||||
@@ -194,7 +194,7 @@ bool Zip::extractFileToMemory( const std::string& path, std::vector<Uint8>& data
|
||||
return Ret;
|
||||
}
|
||||
|
||||
bool Zip::extractFileToMemory( const std::string& path, SafeDataPointer& data ) {
|
||||
bool Zip::extractFileToMemory( const std::string& path, ScopedBuffer& data ) {
|
||||
lock();
|
||||
|
||||
bool Ret = false;
|
||||
@@ -210,10 +210,9 @@ bool Zip::extractFileToMemory( const std::string& path, SafeDataPointer& data )
|
||||
struct zip_file * zf = zip_fopen_index( mZip, zs.index, 0 );
|
||||
|
||||
if ( NULL != zf ) {
|
||||
data.size = (Uint32)zs.size;
|
||||
data.data = eeNewArray( Uint8, ( data.size ) );
|
||||
data.reset( zs.size );
|
||||
|
||||
Result = (Int32)zip_fread( zf, (void*)data.data, data.size );
|
||||
Result = (Int32)zip_fread( zf, (void*)data.get(), data.length() );
|
||||
|
||||
zip_fclose(zf);
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ bool StyleSheetParser::loadFromPack( Pack * pack, std::string filePackPath ) {
|
||||
|
||||
bool Ret = false;
|
||||
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( filePackPath, PData ) ) {
|
||||
Ret = loadFromMemory( PData.data, PData.size );
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( filePackPath, buffer ) ) {
|
||||
Ret = loadFromMemory( buffer.get(), buffer.length() );
|
||||
}
|
||||
|
||||
return Ret;
|
||||
|
||||
@@ -259,7 +259,7 @@ void UIMenu::insert( UINode * Control, const Uint32& Index ) {
|
||||
|
||||
bool UIMenu::isSubMenu( Node * Ctrl ) {
|
||||
for ( Uint32 i = 0; i < mItems.size(); i++ ) {
|
||||
if ( mItems[i]->isType( UI_TYPE_MENUSUBMENU ) ) {
|
||||
if ( NULL != mItems[i] && mItems[i]->isType( UI_TYPE_MENUSUBMENU ) ) {
|
||||
UIMenuSubMenu * tMenu = reinterpret_cast<UIMenuSubMenu*> ( mItems[i] );
|
||||
|
||||
if ( tMenu->getSubMenu() == Ctrl )
|
||||
|
||||
@@ -209,11 +209,11 @@ UIWidget * UISceneNode::loadLayoutFromStream( IOStream& stream, Node * parent )
|
||||
return NULL;
|
||||
|
||||
ios_size bufferSize = stream.getSize();
|
||||
SafeDataPointer safeDataPointer( eeNewArray( Uint8, bufferSize ), bufferSize );
|
||||
stream.read( reinterpret_cast<char*>( safeDataPointer.data ), safeDataPointer.size );
|
||||
TScopedBuffer<char> scopedBuffer( bufferSize );
|
||||
stream.read( scopedBuffer.get(), scopedBuffer.length() );
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_buffer( safeDataPointer.data, safeDataPointer.size );
|
||||
pugi::xml_parse_result result = doc.load_buffer( scopedBuffer.get(), scopedBuffer.length() );
|
||||
|
||||
if ( result ) {
|
||||
return loadLayoutNodes( doc.first_child(), NULL != parent ? parent : this );
|
||||
@@ -227,10 +227,10 @@ UIWidget * UISceneNode::loadLayoutFromStream( IOStream& stream, Node * parent )
|
||||
}
|
||||
|
||||
UIWidget * UISceneNode::loadLayoutFromPack( Pack * pack, const std::string& FilePackPath, Node * parent ) {
|
||||
SafeDataPointer PData;
|
||||
ScopedBuffer buffer;
|
||||
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( FilePackPath, PData ) ) {
|
||||
return loadLayoutFromMemory( PData.data, PData.size, parent );
|
||||
if ( pack->isOpen() && pack->extractFileToMemory( FilePackPath, buffer ) ) {
|
||||
return loadLayoutFromMemory( buffer.get(), buffer.length(), parent );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -38,7 +38,7 @@ CursorX11::CursorX11( const std::string& path, const Vector2i& hotspot, const st
|
||||
|
||||
CursorX11::~CursorX11() {
|
||||
if ( None != mCursor )
|
||||
XFreeCursor( getPlatform()->GetDisplay(), mCursor );
|
||||
XFreeCursor( getPlatform()->getDisplay(), mCursor );
|
||||
}
|
||||
|
||||
void CursorX11::create() {
|
||||
@@ -65,11 +65,11 @@ void CursorX11::create() {
|
||||
image->xhot = mHotSpot.x;
|
||||
image->yhot = mHotSpot.y;
|
||||
|
||||
getPlatform()->Lock();
|
||||
getPlatform()->lock();
|
||||
|
||||
mCursor = XcursorImageLoadCursor( getPlatform()->GetDisplay(), image );
|
||||
mCursor = XcursorImageLoadCursor( getPlatform()->getDisplay(), image );
|
||||
|
||||
getPlatform()->Unlock();
|
||||
getPlatform()->unlock();
|
||||
|
||||
XcursorImageDestroy( image );
|
||||
}
|
||||
|
||||
@@ -40,18 +40,18 @@ X11Impl::~X11Impl() {
|
||||
}
|
||||
|
||||
void X11Impl::minimizeWindow() {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XIconifyWindow( mDisplay, mX11Window, 0 );
|
||||
|
||||
XFlush( mDisplay );
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void X11Impl::maximizeWindow() {
|
||||
// coded by Rafał Maj, idea from Måns Rullgård http://tinyurl.com/68mvk3
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XEvent xev;
|
||||
Atom wm_state = XAtom( "_NET_WM_STATE" );
|
||||
@@ -71,11 +71,11 @@ void X11Impl::maximizeWindow() {
|
||||
|
||||
XFlush(mDisplay);
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool X11Impl::isWindowMaximized() {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
//bool minimized = false;
|
||||
bool maximizedhorz = false;
|
||||
@@ -117,7 +117,7 @@ bool X11Impl::isWindowMaximized() {
|
||||
|
||||
XFlush(mDisplay);
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
|
||||
if( maximizedhorz && maximizedvert ) {
|
||||
return true;
|
||||
@@ -127,45 +127,45 @@ bool X11Impl::isWindowMaximized() {
|
||||
}
|
||||
|
||||
void X11Impl::hideWindow() {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XUnmapWindow( mDisplay, mX11Window );
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void X11Impl::raiseWindow() {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XRaiseWindow( mDisplay, mX11Window );
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void X11Impl::showWindow() {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XMapRaised( mDisplay, mX11Window );
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void X11Impl::moveWindow( int left, int top ) {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XMoveWindow( mDisplay, mX11Window, left, top );
|
||||
|
||||
XFlush( mDisplay );
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void X11Impl::setContext( eeWindowContex Context ) {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
glXMakeCurrent( mDisplay, mX11Window, Context );
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
Vector2i X11Impl::getPosition() {
|
||||
@@ -181,20 +181,20 @@ void X11Impl::showMouseCursor() {
|
||||
if ( !mCursorHidden )
|
||||
return;
|
||||
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XDefineCursor( mDisplay, mMainWindow, mCursorCurrent );
|
||||
|
||||
mCursorHidden = false;
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void X11Impl::hideMouseCursor() {
|
||||
if ( mCursorHidden )
|
||||
return;
|
||||
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
if ( mCursorInvisible == None ) {
|
||||
unsigned long gcmask;
|
||||
@@ -225,7 +225,7 @@ void X11Impl::hideMouseCursor() {
|
||||
|
||||
mCursorHidden = true;
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
Cursor * X11Impl::createMouseCursor( Texture * tex, const Vector2i& hotspot, const std::string& name ) {
|
||||
@@ -244,21 +244,21 @@ void X11Impl::setMouseCursor( Cursor * cursor ) {
|
||||
mCursorCurrent = reinterpret_cast<CursorX11*>( cursor )->GetCursor();
|
||||
|
||||
if ( !mCursorHidden ) {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XDefineCursor( mDisplay, mMainWindow, mCursorCurrent );
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void X11Impl::restoreCursor() {
|
||||
if ( !mCursorHidden ) {
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
XDefineCursor( mDisplay, mMainWindow, mCursorCurrent );
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
} else {
|
||||
hideMouseCursor();
|
||||
}
|
||||
@@ -287,7 +287,7 @@ void X11Impl::setSystemMouseCursor( Cursor::SysType syscursor ) {
|
||||
XFreeCursor( mDisplay, mCursorSystemLast );
|
||||
}
|
||||
|
||||
Lock();
|
||||
lock();
|
||||
|
||||
mCursorCurrent = XCreateFontCursor( mDisplay, cursor_shape );
|
||||
mCursorSystemLast = mCursorCurrent;
|
||||
@@ -296,19 +296,19 @@ void X11Impl::setSystemMouseCursor( Cursor::SysType syscursor ) {
|
||||
XDefineCursor( mDisplay, mMainWindow, mCursorCurrent );
|
||||
}
|
||||
|
||||
Unlock();
|
||||
unlock();
|
||||
}
|
||||
|
||||
eeWindowHandle X11Impl::GetDisplay() const {
|
||||
eeWindowHandle X11Impl::getDisplay() const {
|
||||
return mDisplay;
|
||||
}
|
||||
|
||||
void X11Impl::Lock() {
|
||||
void X11Impl::lock() {
|
||||
if ( NULL != mLock )
|
||||
mLock();
|
||||
}
|
||||
|
||||
void X11Impl::Unlock() {
|
||||
void X11Impl::unlock() {
|
||||
if ( NULL != mUnlock )
|
||||
mUnlock();
|
||||
}
|
||||
|
||||
@@ -54,11 +54,11 @@ class X11Impl : public PlatformImpl {
|
||||
|
||||
void restoreCursor();
|
||||
|
||||
eeWindowHandle GetDisplay() const;
|
||||
eeWindowHandle getDisplay() const;
|
||||
|
||||
void Lock();
|
||||
void lock();
|
||||
|
||||
void Unlock();
|
||||
void unlock();
|
||||
|
||||
eeWindowContex getWindowContext();
|
||||
protected:
|
||||
|
||||
@@ -1,26 +1,50 @@
|
||||
#include <eepp/ee.hpp>
|
||||
#include <args/args.hxx>
|
||||
|
||||
// Prints the response headers
|
||||
void printResponseHeaders( Http::Response& response ) {
|
||||
Http::Response::FieldTable headers = response.getHeaders();
|
||||
|
||||
std::cout << "HTTP/" << response.getMajorHttpVersion() << "." << response.getMinorHttpVersion() << " " << response.getStatus() << " " << Http::Response::statusToString( response.getStatus() ) << std::endl;
|
||||
|
||||
for ( auto&& head : headers ) {
|
||||
std::cout << head.first << ": " << head.second << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
args::ArgumentParser parser("HTTP request program example");
|
||||
args::HelpFlag help(parser, "help", "Display this help menu", {'h', "help"});
|
||||
args::ValueFlag<std::string> output(parser, "file", "Write to file instead of stdout", {'o', "output"} );
|
||||
args::Positional<std::string> url(parser, "url", "The url to request");
|
||||
args::Flag verbose(parser, "verbose", "Prints the request response headers", {'v',"verbose"} );
|
||||
args::Flag resume(parser, "continue", "Resume getting a partially-downloaded file", {'c',"continue"});
|
||||
args::Flag compressed(parser, "compressed", "Request compressed response", {"compressed"});
|
||||
args::ValueFlag<std::string> postData(parser, "data", "HTTP POST data", {'d', "data"});
|
||||
args::ValueFlagList<std::string> headers(parser, "header", "Pass custom header(s) to server", {'H', "header"});
|
||||
args::Flag includeHead(parser, "include", "Include protocol response headers in the output", {'i',"include"});
|
||||
args::Flag insecure(parser, "insecure", "Allow insecure server connections when using SSL", {'k',"insecure"});
|
||||
args::Flag location(parser, "location", "Follow redirects", {'L',"location"});
|
||||
args::ValueFlag<unsigned int> maxRedirs(parser, "max-redirs", "Maximum number of redirects allowed", {"max-redirs"});
|
||||
args::ValueFlag<std::string> output(parser, "file", "Write to file instead of stdout", {'o', "output"});
|
||||
args::ValueFlag<std::string> proxy(parser, "proxy", "[protocol://]host[:port] Use this proxy", {'x', "proxy"});
|
||||
args::Flag progress(parser, "progress", "Show current progress of a download", {'p',"progress"});
|
||||
args::Flag verbose(parser, "verbose", "Make the operation more talkative", {'v',"verbose"});
|
||||
args::ValueFlag<std::string> requestMethod(parser, "request", "Specify request command to use", {'X', "request"});
|
||||
args::Positional<std::string> url(parser, "URL", "The URL to request");
|
||||
|
||||
try {
|
||||
parser.ParseCLI(argc, argv);
|
||||
} catch (const args::Help&) {
|
||||
std::cout << parser;
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
} catch (const args::ParseError& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << parser;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
} catch (args::ValidationError& e) {
|
||||
std::cerr << e.what() << std::endl;
|
||||
std::cerr << parser;
|
||||
return 1;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
{
|
||||
@@ -36,10 +60,7 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
http.setHost("http://en.wikipedia.org");
|
||||
}
|
||||
|
||||
// Prepare a request to get the wikipedia main page
|
||||
request.setUri("/wiki/Main_Page");
|
||||
|
||||
// Creates an async http request
|
||||
// Creates an async http request and set the path requested
|
||||
Http::Request asyncRequest( "/wiki/" + Version::getCodename() );
|
||||
|
||||
http.sendAsyncRequest([]( const Http& http, Http::Request& request, Http::Response& response ) {
|
||||
@@ -52,19 +73,83 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
}
|
||||
}, asyncRequest, Seconds( 5 ) );
|
||||
} else {
|
||||
// If the user provided the URI, creates an instance of URI to parse it.
|
||||
// If the user provided the URL, creates an instance of URI to parse it.
|
||||
URI uri( url.Get() );
|
||||
|
||||
// If no scheme provided asume HTTP
|
||||
if ( uri.getScheme().empty() ) {
|
||||
uri = URI( "http://" + url.Get() );
|
||||
}
|
||||
|
||||
// Allow insecure connections if requested
|
||||
if ( insecure ) {
|
||||
request.setValidateCertificate(false);
|
||||
request.setValidateHostname(false);
|
||||
}
|
||||
|
||||
// Set the host and port from the URI
|
||||
http.setHost( uri.getHost(), uri.getPort() );
|
||||
|
||||
// Set the path and query parts for the request
|
||||
request.setUri( uri.getPathEtc() );
|
||||
|
||||
// Set the headers
|
||||
for ( const std::string& header : args::get(headers) ) {
|
||||
std::string::size_type pos = header.find_first_of( ':' );
|
||||
if ( std::string::npos != pos ) {
|
||||
std::string key( header.substr( 0, pos ) );
|
||||
std::string val( String::trim( header.substr( pos + 1 ) ) );
|
||||
request.setField(key, val);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the request method
|
||||
if ( requestMethod ) {
|
||||
request.setMethod( Http::Request::methodFromString( requestMethod.Get() ) );
|
||||
}
|
||||
|
||||
// Set the post data / body
|
||||
if ( postData ) {
|
||||
request.setBody( postData.Get() );
|
||||
}
|
||||
|
||||
// If progress requested print a progress on screen
|
||||
if ( progress ) {
|
||||
request.setProgressCallback( []( const Http&, const Http::Request&, const Http::Response&, const Http::Request::Status& status, size_t totalBytes, size_t currentBytes ) {
|
||||
if ( status == Http::Request::ContentReceived ) {
|
||||
std::cout << "\rDownloaded " << FileSystem::sizeToString( currentBytes ).c_str() << " of " << FileSystem::sizeToString( totalBytes ).c_str() << " ";
|
||||
std::cout << std::flush;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
// Set follow redirect
|
||||
request.setFollowRedirect(location.Get());
|
||||
|
||||
// Set the maximun number of redirects
|
||||
if ( maxRedirs ) {
|
||||
request.setMaxRedirects(maxRedirs.Get());
|
||||
}
|
||||
|
||||
// Set the proxy for the request
|
||||
char * http_proxy = getenv( "http_proxy" );
|
||||
if ( !proxy && NULL != http_proxy ) {
|
||||
http.setProxy( URI( http_proxy ) );
|
||||
} else if ( proxy ) {
|
||||
http.setProxy( URI( proxy.Get() ) );
|
||||
}
|
||||
|
||||
// Request a compressed response
|
||||
if ( compressed ) {
|
||||
request.setCompressedResponse( true );
|
||||
}
|
||||
|
||||
// Resume existing download
|
||||
if ( resume ) {
|
||||
request.setContinue( true );
|
||||
}
|
||||
|
||||
if ( !output ) {
|
||||
// Send the request
|
||||
Http::Response response = http.sendRequest(request);
|
||||
@@ -72,25 +157,44 @@ EE_MAIN_FUNC int main (int argc, char * argv []) {
|
||||
// Check the status code and display the result
|
||||
Http::Response::Status status = response.getStatus();
|
||||
|
||||
if ( includeHead )
|
||||
printResponseHeaders(response);
|
||||
|
||||
if ( status == Http::Response::Ok ) {
|
||||
if ( verbose ) {
|
||||
Http::Response::FieldTable headers = response.getHeaders();
|
||||
|
||||
std::cout << "Headers: " << std::endl;
|
||||
|
||||
for ( auto&& head : headers ) {
|
||||
std::cout << "\t" << head.first << ": " << head.second << std::endl;
|
||||
}
|
||||
|
||||
std::cout << std::endl << "Body: " << std::endl;
|
||||
}
|
||||
|
||||
std::cout << response.getBody() << std::endl;
|
||||
std::cout << response.getBody();
|
||||
} else {
|
||||
std::cout << "Error " << status << std::endl;
|
||||
std::cout << "Error " << status << std::endl << response.getStatusDescription() << std::endl;
|
||||
std::cout << response.getBody();
|
||||
}
|
||||
} else {
|
||||
http.downloadRequest(request, output.Get(), Seconds(5));
|
||||
std::string path( output.Get() );
|
||||
|
||||
// If output path is a directory guess a file name
|
||||
if ( FileSystem::isDirectory( path ) ) {
|
||||
FileSystem::dirPathAddSlashAtEnd( path );
|
||||
|
||||
std::string lastPathSegment = uri.getLastPathSegment();
|
||||
|
||||
// If there's a path end segment
|
||||
if ( !lastPathSegment.empty() ) {
|
||||
|
||||
// Save with the path end segment name
|
||||
if ( !FileSystem::fileExists( path + lastPathSegment ) ) {
|
||||
path += lastPathSegment;
|
||||
} else {
|
||||
path += FileSystem::fileGetNumberedFileNameFromPath( path, lastPathSegment );
|
||||
}
|
||||
} else {
|
||||
// Create a file name if no name found
|
||||
path += FileSystem::fileGetNumberedFileNameFromPath( path, "eepp-network-file", "-" );
|
||||
}
|
||||
}
|
||||
|
||||
// Download the request response into a file
|
||||
Http::Response response = http.downloadRequest(request, path, Seconds(5));
|
||||
|
||||
if ( includeHead )
|
||||
printResponseHeaders(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user