Commit e1c9d4df authored by Tien-Thinh Nguyen's avatar Tien-Thinh Nguyen

Code cleanup

parent c63a4711
...@@ -69,7 +69,8 @@ void SMContextsCollectionApi::setupRoutes() { ...@@ -69,7 +69,8 @@ void SMContextsCollectionApi::setupRoutes() {
using namespace Pistache::Rest; using namespace Pistache::Rest;
Routes::Post( Routes::Post(
*router, base + smf_cfg.sbi_api_version + NSMF_PDU_SESSION_SM_CONTEXT_CREATE_URL, *router,
base + smf_cfg.sbi_api_version + NSMF_PDU_SESSION_SM_CONTEXT_CREATE_URL,
Routes::bind(&SMContextsCollectionApi::post_sm_contexts_handler, this)); Routes::bind(&SMContextsCollectionApi::post_sm_contexts_handler, this));
// Default handler, called when a route is not found // Default handler, called when a route is not found
......
...@@ -180,8 +180,8 @@ void IndividualSMContextApiImpl::update_sm_context( ...@@ -180,8 +180,8 @@ void IndividualSMContextApiImpl::update_sm_context(
* TS 23.502 */ * TS 23.502 */
// TODO: Existing PDU session, step 3, SUPI, DNN, S-NSSAIs, SM Context ID, AMF // TODO: Existing PDU session, step 3, SUPI, DNN, S-NSSAIs, SM Context ID, AMF
// ID, Request Type, N1 SM Container (PDU Session Establishment Request), User // ID, Request Type, N1 SM Container (PDU Session Establishment Request), User
// location, Access Type, RAT Type, PEI step 15. (SM Context ID -> SCID, N2 SM, // location, Access Type, RAT Type, PEI step 15. (SM Context ID -> SCID, N2
// Request Type)(Initial Request) // SM, Request Type)(Initial Request)
// TODO: verify why Request Type is not define in smContextUpdateData // TODO: verify why Request Type is not define in smContextUpdateData
/* AMF-initiated with a release indication to request the release of the PDU /* AMF-initiated with a release indication to request the release of the PDU
* Session (step 3.d, section 4.3.4.2@3GPP TS 23.502)*/ * Session (step 3.d, section 4.3.4.2@3GPP TS 23.502)*/
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
#include "IndividualSubscriptionDocumentApiImpl.h" #include "IndividualSubscriptionDocumentApiImpl.h"
namespace oai { namespace oai {
......
...@@ -38,7 +38,6 @@ ...@@ -38,7 +38,6 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
#ifndef NF_STATUS_NOTIFY_API_IMPL_H_ #ifndef NF_STATUS_NOTIFY_API_IMPL_H_
#define NF_STATUS_NOTIFY_API_IMPL_H_ #define NF_STATUS_NOTIFY_API_IMPL_H_
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
#include "PDUSessionsCollectionApiImpl.h" #include "PDUSessionsCollectionApiImpl.h"
namespace oai { namespace oai {
......
...@@ -225,7 +225,8 @@ void smf_http2_server::start() { ...@@ -225,7 +225,8 @@ void smf_http2_server::start() {
return; return;
} }
} else if (method.compare("release") == 0) { // smContextReleaseData } else if (
method.compare("release") == 0) { // smContextReleaseData
Logger::smf_api_server().info( Logger::smf_api_server().info(
"Handle Release SM Context Request from AMF"); "Handle Release SM Context Request from AMF");
...@@ -293,7 +294,8 @@ void smf_http2_server::create_sm_contexts_handler( ...@@ -293,7 +294,8 @@ void smf_http2_server::create_sm_contexts_handler(
// set api root to be used as location header in HTTP response // set api root to be used as location header in HTTP response
sm_context_req_msg.set_api_root( sm_context_req_msg.set_api_root(
// m_address + ":" + std::to_string(m_port) + // m_address + ":" + std::to_string(m_port) +
NSMF_PDU_SESSION_BASE + smf_cfg.sbi_api_version + NSMF_PDU_SESSION_SM_CONTEXT_CREATE_URL); NSMF_PDU_SESSION_BASE + smf_cfg.sbi_api_version +
NSMF_PDU_SESSION_SM_CONTEXT_CREATE_URL);
// supi // supi
supi_t supi = {.length = 0}; supi_t supi = {.length = 0};
...@@ -474,8 +476,8 @@ void smf_http2_server::update_sm_context_handler( ...@@ -474,8 +476,8 @@ void smf_http2_server::update_sm_context_handler(
* TS 23.502 */ * TS 23.502 */
// TODO: Existing PDU session, step 3, SUPI, DNN, S-NSSAIs, SM Context ID, AMF // TODO: Existing PDU session, step 3, SUPI, DNN, S-NSSAIs, SM Context ID, AMF
// ID, Request Type, N1 SM Container (PDU Session Establishment Request), User // ID, Request Type, N1 SM Container (PDU Session Establishment Request), User
// location, Access Type, RAT Type, PEI step 15. (SM Context ID -> SCID, N2 SM, // location, Access Type, RAT Type, PEI step 15. (SM Context ID -> SCID, N2
// Request Type)(Initial Request) // SM, Request Type)(Initial Request)
// TODO: verify why Request Type is not define in smContextUpdateData // TODO: verify why Request Type is not define in smContextUpdateData
/* AMF-initiated with a release indication to request the release of the PDU /* AMF-initiated with a release indication to request the release of the PDU
* Session (step 3.d, section 4.3.4.2@3GPP TS 23.502)*/ * Session (step 3.d, section 4.3.4.2@3GPP TS 23.502)*/
......
...@@ -45,7 +45,7 @@ typedef struct plmn_s { ...@@ -45,7 +45,7 @@ typedef struct plmn_s {
#define INVALID_TMSI \ #define INVALID_TMSI \
UINT32_MAX /*!< \brief The network shall not allocate a TMSI with all 32 \ UINT32_MAX /*!< \brief The network shall not allocate a TMSI with all 32 \
bits equal to 1 (this is because the TMSI must be stored in \ bits equal to 1 (this is because the TMSI must be stored in \
the SIM, and the SIM uses 4 octets with all bits \ the SIM, and the SIM uses 4 octets with all bits \
equal to 1 to indicate that no valid TMSI is \ equal to 1 to indicate that no valid TMSI is \
available). */ available). */
......
...@@ -110,14 +110,14 @@ enum class n2_sm_info_type_e { ...@@ -110,14 +110,14 @@ enum class n2_sm_info_type_e {
PDU_RES_NTY_REL = 10, // PDU Session Resource Notify Released Transfer PDU_RES_NTY_REL = 10, // PDU Session Resource Notify Released Transfer
PDU_RES_MOD_IND = 11, // PDU Session Resource Modify Indication Transfer PDU_RES_MOD_IND = 11, // PDU Session Resource Modify Indication Transfer
PDU_RES_MOD_CFM = 12, // PDU Session Resource Modify Confirm Transfer PDU_RES_MOD_CFM = 12, // PDU Session Resource Modify Confirm Transfer
PATH_SWITCH_REQ = 13, // Path Switch Request Transfer PATH_SWITCH_REQ = 13, // Path Switch Request Transfer
PATH_SWITCH_SETUP_FAIL = 14, // Path Switch Request Setup Failed Transfer PATH_SWITCH_SETUP_FAIL = 14, // Path Switch Request Setup Failed Transfer
PATH_SWITCH_REQ_ACK = 15, // Path Switch Request Acknowledge Transfer PATH_SWITCH_REQ_ACK = 15, // Path Switch Request Acknowledge Transfer
PATH_SWITCH_REQ_FAIL = 16, // Path Switch Request Unsuccessful Transfer PATH_SWITCH_REQ_FAIL = 16, // Path Switch Request Unsuccessful Transfer
HANDOVER_REQUIRED = 17, // Handover Required Transfer HANDOVER_REQUIRED = 17, // Handover Required Transfer
HANDOVER_CMD = 18, // Handover Command Transfer HANDOVER_CMD = 18, // Handover Command Transfer
HANDOVER_PREP_FAIL = 19, // Handover Preparation Unsuccessful Transfer HANDOVER_PREP_FAIL = 19, // Handover Preparation Unsuccessful Transfer
HANDOVER_REQ_ACK = 20, // Handover Request Acknowledge Transfer HANDOVER_REQ_ACK = 20, // Handover Request Acknowledge Transfer
HANDOVER_RES_ALLOC_FAIL = HANDOVER_RES_ALLOC_FAIL =
21, // Handover Resource Allocation Unsuccessful Transfer 21, // Handover Resource Allocation Unsuccessful Transfer
SECONDARY_RAT_USAGE = 22 // Secondary RAT Data Usage Report Transfer SECONDARY_RAT_USAGE = 22 // Secondary RAT Data Usage Report Transfer
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
* contributor license agreements. See the NOTICE file distributed with * contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. * this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under * The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file * the OAI Public License, Version 1.1 (the "License"); you may not use this
* except in compliance with the License. *file except in compliance with the License. You may obtain a copy of the
* You may obtain a copy of the License at *License at
* *
* http://www.openairinterface.org/?page_id=698 * http://www.openairinterface.org/?page_id=698
* *
...@@ -41,67 +41,50 @@ class endpoint { ...@@ -41,67 +41,50 @@ class endpoint {
struct sockaddr_storage addr_storage; struct sockaddr_storage addr_storage;
socklen_t addr_storage_len; socklen_t addr_storage_len;
endpoint() endpoint()
: : addr_storage(), addr_storage_len(sizeof(struct sockaddr_storage)){};
addr_storage(), endpoint(const endpoint& e)
addr_storage_len(sizeof(struct sockaddr_storage)) { : addr_storage(e.addr_storage), addr_storage_len(e.addr_storage_len){};
} endpoint(const struct sockaddr_storage& addr, const socklen_t len)
; : addr_storage(addr), addr_storage_len(len){};
endpoint(const endpoint &e) endpoint(const struct in_addr& addr, const uint16_t port) {
: struct sockaddr_in* addr_in = (struct sockaddr_in*) &addr_storage;
addr_storage(e.addr_storage), addr_in->sin_family = AF_INET;
addr_storage_len(e.addr_storage_len) { addr_in->sin_port = htons(port);
} addr_in->sin_addr.s_addr = addr.s_addr;
;
endpoint(const struct sockaddr_storage &addr, const socklen_t len)
:
addr_storage(addr),
addr_storage_len(len) {
}
;
endpoint(const struct in_addr &addr, const uint16_t port) {
struct sockaddr_in *addr_in = (struct sockaddr_in*) &addr_storage;
addr_in->sin_family = AF_INET;
addr_in->sin_port = htons(port);
addr_in->sin_addr.s_addr = addr.s_addr;
addr_storage_len = sizeof(struct sockaddr_in); addr_storage_len = sizeof(struct sockaddr_in);
} };
;
endpoint(const struct in6_addr &addr6, const uint16_t port) { endpoint(const struct in6_addr& addr6, const uint16_t port) {
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6*) &addr_storage; struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*) &addr_storage;
addr_in6->sin6_family = AF_INET6; addr_in6->sin6_family = AF_INET6;
addr_in6->sin6_port = htons(port); addr_in6->sin6_port = htons(port);
addr_in6->sin6_flowinfo = 0; addr_in6->sin6_flowinfo = 0;
memcpy(&addr_in6->sin6_addr, &addr6, sizeof(struct in6_addr)); memcpy(&addr_in6->sin6_addr, &addr6, sizeof(struct in6_addr));
addr_in6->sin6_scope_id = 0; addr_in6->sin6_scope_id = 0;
addr_storage_len = sizeof(struct sockaddr_in6); addr_storage_len = sizeof(struct sockaddr_in6);
} };
;
uint16_t port() const { uint16_t port() const {
return ntohs(((struct sockaddr_in*) &addr_storage)->sin_port); return ntohs(((struct sockaddr_in*) &addr_storage)->sin_port);
} }
sa_family_t family() const { sa_family_t family() const { return addr_storage.ss_family; }
return addr_storage.ss_family;
}
std::string toString() const { std::string toString() const {
std::string str; std::string str;
if (addr_storage.ss_family == AF_INET) { if (addr_storage.ss_family == AF_INET) {
struct sockaddr_in *addr_in = (struct sockaddr_in*) &addr_storage; struct sockaddr_in* addr_in = (struct sockaddr_in*) &addr_storage;
str.append(conv::toString(addr_in->sin_addr)); str.append(conv::toString(addr_in->sin_addr));
str.append(":").append(std::to_string(ntohs(addr_in->sin_port))); str.append(":").append(std::to_string(ntohs(addr_in->sin_port)));
} else if (addr_storage.ss_family == AF_INET6) { } else if (addr_storage.ss_family == AF_INET6) {
struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6*) &addr_storage; struct sockaddr_in6* addr_in6 = (struct sockaddr_in6*) &addr_storage;
str.append(conv::toString(addr_in6->sin6_addr)); str.append(conv::toString(addr_in6->sin6_addr));
str.append(":").append(std::to_string(ntohs(addr_in6->sin6_port))); str.append(":").append(std::to_string(ntohs(addr_in6->sin6_port)));
} }
return str; return str;
} }
}; };
#endif #endif
...@@ -21,144 +21,104 @@ ...@@ -21,144 +21,104 @@
#include <stdexcept> #include <stdexcept>
#include <vector> #include <vector>
//#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error", "critical", "off" }; //#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info", "warning", "error",
#define SPDLOG_LEVEL_NAMES { "trace", "debug", "info ", "start", "warn ", "error", "off " }; //"critical", "off" };
#define SPDLOG_LEVEL_NAMES \
{"trace", "debug", "info ", "start", "warn ", "error", "off "};
#define SPDLOG_ENABLE_SYSLOG #define SPDLOG_ENABLE_SYSLOG
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
class LoggerException : public std::runtime_error { class LoggerException : public std::runtime_error {
public: public:
explicit LoggerException(const char *m) explicit LoggerException(const char* m) : std::runtime_error(m) {}
: explicit LoggerException(const std::string& m) : std::runtime_error(m) {}
std::runtime_error(m) {
}
explicit LoggerException(const std::string &m)
:
std::runtime_error(m) {
}
}; };
class _Logger { class _Logger {
public: public:
_Logger(const char *category, std::vector<spdlog::sink_ptr> &sinks, _Logger(
const char *pattern); const char* category, std::vector<spdlog::sink_ptr>& sinks,
const char* pattern);
void trace(const char *format, ...);
void trace(const std::string &format, ...); void trace(const char* format, ...);
void debug(const char *format, ...); void trace(const std::string& format, ...);
void debug(const std::string &format, ...); void debug(const char* format, ...);
void info(const char *format, ...); void debug(const std::string& format, ...);
void info(const std::string &format, ...); void info(const char* format, ...);
void startup(const char *format, ...); void info(const std::string& format, ...);
void startup(const std::string &format, ...); void startup(const char* format, ...);
void warn(const char *format, ...); void startup(const std::string& format, ...);
void warn(const std::string &format, ...); void warn(const char* format, ...);
void error(const char *format, ...); void warn(const std::string& format, ...);
void error(const std::string &format, ...); void error(const char* format, ...);
void error(const std::string& format, ...);
private: private:
_Logger(); _Logger();
enum _LogType { enum _LogType { _ltTrace, _ltDebug, _ltInfo, _ltStartup, _ltWarn, _ltError };
_ltTrace,
_ltDebug,
_ltInfo,
_ltStartup,
_ltWarn,
_ltError
};
void log(_LogType lt, const char *format, va_list &args); void log(_LogType lt, const char* format, va_list& args);
spdlog::logger m_log; spdlog::logger m_log;
}; };
class Logger { class Logger {
public: public:
static void init(
static void init(const char *app, const bool log_stdout, const char* app, const bool log_stdout, const bool log_rot_file) {
const bool log_rot_file) {
singleton()._init(app, log_stdout, log_rot_file); singleton()._init(app, log_stdout, log_rot_file);
} }
static void init(const std::string &app, const bool log_stdout, static void init(
const bool log_rot_file) { const std::string& app, const bool log_stdout, const bool log_rot_file) {
init(app.c_str(), log_stdout, log_rot_file); init(app.c_str(), log_stdout, log_rot_file);
} }
static _Logger& async_cmd() { static _Logger& async_cmd() { return *singleton().m_async_cmd; }
return *singleton().m_async_cmd; static _Logger& itti() { return *singleton().m_itti; }
} static _Logger& smf_app() { return *singleton().m_smf_app; }
static _Logger& itti() { static _Logger& system() { return *singleton().m_system; }
return *singleton().m_itti; static _Logger& udp() { return *singleton().m_udp; }
} static _Logger& pfcp() { return *singleton().m_pfcp; }
static _Logger& smf_app() { static _Logger& pfcp_switch() { return *singleton().m_pfcp_switch; }
return *singleton().m_smf_app;
}
static _Logger& system() {
return *singleton().m_system;
}
static _Logger& udp() {
return *singleton().m_udp;
}
static _Logger& pfcp() {
return *singleton().m_pfcp;
}
static _Logger& pfcp_switch() {
return *singleton().m_pfcp_switch;
}
static _Logger& smf_n1() { static _Logger& smf_n1() { return *singleton().m_smf_n1; }
return *singleton().m_smf_n1; static _Logger& smf_n2() { return *singleton().m_smf_n2; }
} static _Logger& smf_n4() { return *singleton().m_smf_n4; }
static _Logger& smf_n2() { static _Logger& smf_n10() { return *singleton().m_smf_n10; }
return *singleton().m_smf_n2; static _Logger& smf_n11() { return *singleton().m_smf_n11; }
} static _Logger& smf_api_server() { return *singleton().m_smf_api_server; }
static _Logger& smf_n4() {
return *singleton().m_smf_n4;
}
static _Logger& smf_n10() {
return *singleton().m_smf_n10;
}
static _Logger& smf_n11() {
return *singleton().m_smf_n11;
}
static _Logger& smf_api_server() {
return *singleton().m_smf_api_server;
}
private: private:
static Logger *m_singleton; static Logger* m_singleton;
static Logger& singleton() { static Logger& singleton() {
if (!m_singleton) if (!m_singleton) m_singleton = new Logger();
m_singleton = new Logger();
return *m_singleton; return *m_singleton;
} }
Logger() { Logger() {}
} ~Logger() {}
~Logger() {
}
void _init(const char *app, const bool log_stdout, const bool log_rot_file); void _init(const char* app, const bool log_stdout, const bool log_rot_file);
std::vector<spdlog::sink_ptr> m_sinks; std::vector<spdlog::sink_ptr> m_sinks;
std::string m_pattern; std::string m_pattern;
_Logger *m_async_cmd; _Logger* m_async_cmd;
_Logger *m_itti; _Logger* m_itti;
_Logger *m_smf_app; _Logger* m_smf_app;
_Logger *m_system; _Logger* m_system;
_Logger *m_udp; _Logger* m_udp;
_Logger *m_pfcp; _Logger* m_pfcp;
_Logger *m_pfcp_switch; _Logger* m_pfcp_switch;
_Logger *m_smf_n1; _Logger* m_smf_n1;
_Logger *m_smf_n2; _Logger* m_smf_n2;
_Logger *m_smf_n4; _Logger* m_smf_n4;
_Logger *m_smf_n10; _Logger* m_smf_n10;
_Logger *m_smf_n11; _Logger* m_smf_n11;
_Logger *m_smf_api_server; _Logger* m_smf_api_server;
}; };
#endif // __LOGGER_H #endif // __LOGGER_H
...@@ -34,9 +34,9 @@ ...@@ -34,9 +34,9 @@
class stream_serializable { class stream_serializable {
public: public:
virtual void dump_to(std::ostream &os) = 0; virtual void dump_to(std::ostream& os) = 0;
virtual void load_from(std::istream &is) = 0; virtual void load_from(std::istream& is) = 0;
//virtual ~serializable() = 0; // virtual ~serializable() = 0;
}; };
#endif /* FILE_SERIALIZABLE_HPP_SEEN */ #endif /* FILE_SERIALIZABLE_HPP_SEEN */
...@@ -148,7 +148,6 @@ void xgpp_conv::pco_core_to_nas( ...@@ -148,7 +148,6 @@ void xgpp_conv::pco_core_to_nas(
void xgpp_conv::sm_context_create_data_from_openapi( void xgpp_conv::sm_context_create_data_from_openapi(
const oai::smf_server::model::SmContextMessage& scd, const oai::smf_server::model::SmContextMessage& scd,
smf::pdu_session_create_sm_context_request& pcr) { smf::pdu_session_create_sm_context_request& pcr) {
Logger::smf_app().debug( Logger::smf_app().debug(
"Convert SmContextMessage (OpenAPI) to " "Convert SmContextMessage (OpenAPI) to "
"pdu_session_create_sm_context_request"); "pdu_session_create_sm_context_request");
...@@ -156,7 +155,7 @@ void xgpp_conv::sm_context_create_data_from_openapi( ...@@ -156,7 +155,7 @@ void xgpp_conv::sm_context_create_data_from_openapi(
oai::smf_server::model::SmContextCreateData context_data = scd.getJsonData(); oai::smf_server::model::SmContextCreateData context_data = scd.getJsonData();
std::string n1_sm_msg = scd.getBinaryDataN1SmMessage(); std::string n1_sm_msg = scd.getBinaryDataN1SmMessage();
//N1 SM Message // N1 SM Message
pcr.set_n1_sm_message(n1_sm_msg); pcr.set_n1_sm_message(n1_sm_msg);
Logger::smf_app().debug("N1 SM message: %s", n1_sm_msg.c_str()); Logger::smf_app().debug("N1 SM message: %s", n1_sm_msg.c_str());
......
...@@ -20,65 +20,70 @@ ...@@ -20,65 +20,70 @@
static int bsafeShouldExit = 1; static int bsafeShouldExit = 1;
char * strcpy (char *dst, const char *src); char* strcpy(char* dst, const char* src);
char * strcat (char *dst, const char *src); char* strcat(char* dst, const char* src);
char * strcpy (char *dst, const char *src) { char* strcpy(char* dst, const char* src) {
(void) dst; (void) dst;
(void) src; (void) src;
fprintf (stderr, "bsafe error: strcpy() is not safe, use bstrcpy instead.\n"); fprintf(stderr, "bsafe error: strcpy() is not safe, use bstrcpy instead.\n");
if (bsafeShouldExit) exit (-1); if (bsafeShouldExit) exit(-1);
return NULL; return NULL;
} }
char * strcat (char *dst, const char *src) { char* strcat(char* dst, const char* src) {
(void) dst; (void) dst;
(void) src; (void) src;
fprintf (stderr, "bsafe error: strcat() is not safe, use bstrcat instead.\n"); fprintf(stderr, "bsafe error: strcat() is not safe, use bstrcat instead.\n");
if (bsafeShouldExit) exit (-1); if (bsafeShouldExit) exit(-1);
return NULL; return NULL;
} }
#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310)) #if !defined(__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
char * (gets) (char * buf) { char*(gets)(char* buf) {
(void) buf; (void) buf;
fprintf (stderr, "bsafe error: gets() is not safe, use bgets.\n"); fprintf(stderr, "bsafe error: gets() is not safe, use bgets.\n");
if (bsafeShouldExit) exit (-1); if (bsafeShouldExit) exit(-1);
return NULL; return NULL;
} }
#endif #endif
char * (strncpy) (char *dst, const char *src, size_t n) { char*(strncpy)(char* dst, const char* src, size_t n) {
(void) dst; (void) dst;
(void) src; (void) src;
(void) n; (void) n;
fprintf (stderr, "bsafe error: strncpy() is not safe, use bmidstr instead.\n"); fprintf(stderr, "bsafe error: strncpy() is not safe, use bmidstr instead.\n");
//if (bsafeShouldExit) exit (-1); // if (bsafeShouldExit) exit (-1);
return NULL; return NULL;
} }
char * (strncat) (char *dst, const char *src, size_t n) { char*(strncat)(char* dst, const char* src, size_t n) {
(void) dst; (void) dst;
(void) src; (void) src;
(void) n; (void) n;
fprintf (stderr, "bsafe error: strncat() is not safe, use bstrcat then btrunc\n\tor cstr2tbstr, btrunc then bstrcat instead.\n"); fprintf(
if (bsafeShouldExit) exit (-1); stderr,
return NULL; "bsafe error: strncat() is not safe, use bstrcat then btrunc\n\tor "
"cstr2tbstr, btrunc then bstrcat instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
} }
char * (strtok) (char *s1, const char *s2) { char*(strtok)(char* s1, const char* s2) {
(void) s1; (void) s1;
(void) s2; (void) s2;
fprintf (stderr, "bsafe error: strtok() is not safe, use bsplit or bsplits instead.\n"); fprintf(
if (bsafeShouldExit) exit (-1); stderr,
return NULL; "bsafe error: strtok() is not safe, use bsplit or bsplits instead.\n");
if (bsafeShouldExit) exit(-1);
return NULL;
} }
/* /*
//TODO: temporary solution for Release mode //TODO: temporary solution for Release mode
char * (strdup) (const char *s) { char * (strdup) (const char *s) {
(void) s; (void) s;
fprintf (stderr, "bsafe error: strdup() is not safe, use bstrcpy.\n"); fprintf (stderr, "bsafe error: strdup() is not safe, use bstrcpy.\n");
if (bsafeShouldExit) exit (-1); if (bsafeShouldExit) exit (-1);
return NULL; return NULL;
} }
*/ */
/* /*
* This source file is part of the bstring string library. This code was * This source file is part of the bstring string library. This code was
* written by Paul Hsieh in 2002-2004, and is covered by the BSD open source * written by Paul Hsieh in 2002-2004, and is covered by the BSD open source
* license. Refer to the accompanying documentation for details on usage and * license. Refer to the accompanying documentation for details on usage and
* license. * license.
*/ */
...@@ -21,20 +21,20 @@ ...@@ -21,20 +21,20 @@
extern "C" { extern "C" {
#endif #endif
#if !defined (__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310)) #if !defined(__GNUC__) && (!defined(_MSC_VER) || (_MSC_VER <= 1310))
/* This is caught in the linker, so its not necessary for gcc. */ /* This is caught in the linker, so its not necessary for gcc. */
extern char * (gets) (char * buf); extern char*(gets)(char* buf);
#endif #endif
extern char * (strncpy) (char *dst, const char *src, size_t n); extern char*(strncpy)(char* dst, const char* src, size_t n);
extern char * (strncat) (char *dst, const char *src, size_t n); extern char*(strncat)(char* dst, const char* src, size_t n);
extern char * (strtok) (char *s1, const char *s2); extern char*(strtok)(char* s1, const char* s2);
//extern char * (strdup) (const char *s); // extern char * (strdup) (const char *s);
#undef strcpy #undef strcpy
#undef strcat #undef strcat
#define strcpy(a,b) bsafe_strcpy(a,b) #define strcpy(a, b) bsafe_strcpy(a, b)
#define strcat(a,b) bsafe_strcat(a,b) #define strcat(a, b) bsafe_strcat(a, b)
#ifdef __cplusplus #ifdef __cplusplus
} }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -11,8 +11,8 @@ ...@@ -11,8 +11,8 @@
* This file is the C++ wrapper for the bstring functions. * This file is the C++ wrapper for the bstring functions.
*/ */
#if defined (_MSC_VER) #if defined(_MSC_VER)
# define _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS
#endif #endif
#include <stdio.h> #include <stdio.h>
...@@ -27,35 +27,35 @@ ...@@ -27,35 +27,35 @@
#endif #endif
#ifndef bstr__alloc #ifndef bstr__alloc
#define bstr__alloc(x) malloc (x) #define bstr__alloc(x) malloc(x)
#endif #endif
#ifndef bstr__free #ifndef bstr__free
#define bstr__free(p) free (p) #define bstr__free(p) free(p)
#endif #endif
#ifndef bstr__realloc #ifndef bstr__realloc
#define bstr__realloc(p,x) realloc ((p), (x)) #define bstr__realloc(p, x) realloc((p), (x))
#endif #endif
#ifndef bstr__memcpy #ifndef bstr__memcpy
#define bstr__memcpy(d,s,l) memcpy ((d), (s), (l)) #define bstr__memcpy(d, s, l) memcpy((d), (s), (l))
#endif #endif
#ifndef bstr__memmove #ifndef bstr__memmove
#define bstr__memmove(d,s,l) memmove ((d), (s), (l)) #define bstr__memmove(d, s, l) memmove((d), (s), (l))
#endif #endif
#ifndef bstr__memset #ifndef bstr__memset
#define bstr__memset(d,c,l) memset ((d), (c), (l)) #define bstr__memset(d, c, l) memset((d), (c), (l))
#endif #endif
#ifndef bstr__memcmp #ifndef bstr__memcmp
#define bstr__memcmp(d,c,l) memcmp ((d), (c), (l)) #define bstr__memcmp(d, c, l) memcmp((d), (c), (l))
#endif #endif
#ifndef bstr__memchr #ifndef bstr__memchr
#define bstr__memchr(s,c,l) memchr ((s), (c), (l)) #define bstr__memchr(s, c, l) memchr((s), (c), (l))
#endif #endif
#if defined(BSTRLIB_CAN_USE_IOSTREAM) #if defined(BSTRLIB_CAN_USE_IOSTREAM)
...@@ -66,490 +66,502 @@ namespace Bstrlib { ...@@ -66,490 +66,502 @@ namespace Bstrlib {
// Constructors. // Constructors.
CBString::CBString () { CBString::CBString() {
slen = 0; slen = 0;
mlen = 8; mlen = 8;
data = (unsigned char *) bstr__alloc (mlen); data = (unsigned char*) bstr__alloc(mlen);
if (!data) { if (!data) {
mlen = 0; mlen = 0;
bstringThrow ("Failure in default constructor"); bstringThrow("Failure in default constructor");
} else { } else {
data[0] = '\0'; data[0] = '\0';
} }
} }
CBString::CBString (const void * blk, int len) { CBString::CBString(const void* blk, int len) {
data = NULL; data = NULL;
if (len >= 0) { if (len >= 0) {
mlen = len + 1; mlen = len + 1;
slen = len; slen = len;
data = (unsigned char *) bstr__alloc (mlen); data = (unsigned char*) bstr__alloc(mlen);
} }
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in block constructor"); bstringThrow("Failure in block constructor");
} else { } else {
if (slen > 0) bstr__memcpy (data, blk, slen); if (slen > 0) bstr__memcpy(data, blk, slen);
data[slen] = '\0'; data[slen] = '\0';
} }
} }
CBString::CBString (char c, int len) { CBString::CBString(char c, int len) {
data = NULL; data = NULL;
if (len >= 0) { if (len >= 0) {
mlen = len + 1; mlen = len + 1;
slen = len; slen = len;
data = (unsigned char *) bstr__alloc (mlen); data = (unsigned char*) bstr__alloc(mlen);
} }
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in repeat(char) constructor"); bstringThrow("Failure in repeat(char) constructor");
} else { } else {
if (slen > 0) bstr__memset (data, c, slen); if (slen > 0) bstr__memset(data, c, slen);
data[slen] = '\0'; data[slen] = '\0';
} }
} }
CBString::CBString (char c) { CBString::CBString(char c) {
mlen = 2; mlen = 2;
slen = 1; slen = 1;
if (NULL == (data = (unsigned char *) bstr__alloc (mlen))) { if (NULL == (data = (unsigned char*) bstr__alloc(mlen))) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in (char) constructor"); bstringThrow("Failure in (char) constructor");
} else { } else {
data[0] = (unsigned char) c; data[0] = (unsigned char) c;
data[1] = '\0'; data[1] = '\0';
} }
} }
CBString::CBString (unsigned char c) { CBString::CBString(unsigned char c) {
mlen = 2; mlen = 2;
slen = 1; slen = 1;
if (NULL == (data = (unsigned char *) bstr__alloc (mlen))) { if (NULL == (data = (unsigned char*) bstr__alloc(mlen))) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in (char) constructor"); bstringThrow("Failure in (char) constructor");
} else { } else {
data[0] = c; data[0] = c;
data[1] = '\0'; data[1] = '\0';
} }
} }
CBString::CBString (const char *s) { CBString::CBString(const char* s) {
if (s) { if (s) {
size_t sslen = strlen (s); size_t sslen = strlen(s);
if (sslen >= INT_MAX) bstringThrow ("Failure in (char *) constructor, string too large") if (sslen >= INT_MAX)
slen = (int) sslen; bstringThrow("Failure in (char *) constructor, string too large") slen =
mlen = slen + 1; (int) sslen;
if (NULL != (data = (unsigned char *) bstr__alloc (mlen))) { mlen = slen + 1;
bstr__memcpy (data, s, mlen); if (NULL != (data = (unsigned char*) bstr__alloc(mlen))) {
return; bstr__memcpy(data, s, mlen);
} return;
} }
data = NULL; }
bstringThrow ("Failure in (char *) constructor"); data = NULL;
} bstringThrow("Failure in (char *) constructor");
}
CBString::CBString (int len, const char *s) {
if (s) { CBString::CBString(int len, const char* s) {
size_t sslen = strlen (s); if (s) {
if (sslen >= INT_MAX) bstringThrow ("Failure in (char *) constructor, string too large") size_t sslen = strlen(s);
slen = (int) sslen; if (sslen >= INT_MAX)
mlen = slen + 1; bstringThrow("Failure in (char *) constructor, string too large") slen =
if (mlen < len) mlen = len; (int) sslen;
if (NULL != (data = (unsigned char *) bstr__alloc (mlen))) { mlen = slen + 1;
bstr__memcpy (data, s, slen + 1); if (mlen < len) mlen = len;
return; if (NULL != (data = (unsigned char*) bstr__alloc(mlen))) {
} bstr__memcpy(data, s, slen + 1);
} return;
data = NULL; }
bstringThrow ("Failure in (int len, char *) constructor"); }
} data = NULL;
bstringThrow("Failure in (int len, char *) constructor");
CBString::CBString (const CBString& b) { }
slen = b.slen;
mlen = slen + 1; CBString::CBString(const CBString& b) {
data = NULL; slen = b.slen;
if (mlen > 0) data = (unsigned char *) bstr__alloc (mlen); mlen = slen + 1;
if (!data) { data = NULL;
bstringThrow ("Failure in (CBString) constructor"); if (mlen > 0) data = (unsigned char*) bstr__alloc(mlen);
} else { if (!data) {
bstr__memcpy (data, b.data, slen); bstringThrow("Failure in (CBString) constructor");
data[slen] = '\0'; } else {
} bstr__memcpy(data, b.data, slen);
} data[slen] = '\0';
}
CBString::CBString (const tagbstring& x) { }
slen = x.slen;
mlen = slen + 1; CBString::CBString(const tagbstring& x) {
data = NULL; slen = x.slen;
if (slen >= 0 && x.data != NULL) data = (unsigned char *) bstr__alloc (mlen); mlen = slen + 1;
if (!data) { data = NULL;
bstringThrow ("Failure in (tagbstring) constructor"); if (slen >= 0 && x.data != NULL) data = (unsigned char*) bstr__alloc(mlen);
} else { if (!data) {
bstr__memcpy (data, x.data, slen); bstringThrow("Failure in (tagbstring) constructor");
data[slen] = '\0'; } else {
} bstr__memcpy(data, x.data, slen);
data[slen] = '\0';
}
} }
// Destructor. // Destructor.
CBString::~CBString () { CBString::~CBString() {
if (data != NULL) { if (data != NULL) {
bstr__free (data); bstr__free(data);
data = NULL; data = NULL;
} }
mlen = 0; mlen = 0;
slen = -__LINE__; slen = -__LINE__;
} }
// = operator. // = operator.
const CBString& CBString::operator = (char c) { const CBString& CBString::operator=(char c) {
if (mlen <= 0) bstringThrow ("Write protection error"); if (mlen <= 0) bstringThrow("Write protection error");
if (2 >= mlen) alloc (2); if (2 >= mlen) alloc(2);
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in =(char) operator"); bstringThrow("Failure in =(char) operator");
} else { } else {
slen = 1; slen = 1;
data[0] = (unsigned char) c; data[0] = (unsigned char) c;
data[1] = '\0'; data[1] = '\0';
} }
return *this; return *this;
} }
const CBString& CBString::operator = (unsigned char c) { const CBString& CBString::operator=(unsigned char c) {
if (mlen <= 0) bstringThrow ("Write protection error"); if (mlen <= 0) bstringThrow("Write protection error");
if (2 >= mlen) alloc (2); if (2 >= mlen) alloc(2);
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in =(char) operator"); bstringThrow("Failure in =(char) operator");
} else { } else {
slen = 1; slen = 1;
data[0] = c; data[0] = c;
data[1] = '\0'; data[1] = '\0';
} }
return *this; return *this;
} }
const CBString& CBString::operator = (const char *s) { const CBString& CBString::operator=(const char* s) {
size_t tmpSlen; size_t tmpSlen;
if (mlen <= 0) bstringThrow ("Write protection error"); if (mlen <= 0) bstringThrow("Write protection error");
if (NULL == s) s = ""; if (NULL == s) s = "";
if ((tmpSlen = strlen (s)) >= (size_t) mlen) { if ((tmpSlen = strlen(s)) >= (size_t) mlen) {
if (tmpSlen >= INT_MAX-1) bstringThrow ("Failure in =(const char *) operator, string too large"); if (tmpSlen >= INT_MAX - 1)
alloc ((int) tmpSlen); bstringThrow("Failure in =(const char *) operator, string too large");
} alloc((int) tmpSlen);
}
if (data) {
slen = (int) tmpSlen; if (data) {
bstr__memcpy (data, s, tmpSlen + 1); slen = (int) tmpSlen;
} else { bstr__memcpy(data, s, tmpSlen + 1);
mlen = slen = 0; } else {
bstringThrow ("Failure in =(const char *) operator"); mlen = slen = 0;
} bstringThrow("Failure in =(const char *) operator");
return *this; }
} return *this;
}
const CBString& CBString::operator = (const CBString& b) {
if (mlen <= 0) bstringThrow ("Write protection error"); const CBString& CBString::operator=(const CBString& b) {
if (b.slen >= mlen) alloc (b.slen); if (mlen <= 0) bstringThrow("Write protection error");
if (b.slen >= mlen) alloc(b.slen);
slen = b.slen;
if (!data) { slen = b.slen;
mlen = slen = 0; if (!data) {
bstringThrow ("Failure in =(CBString) operator"); mlen = slen = 0;
} else { bstringThrow("Failure in =(CBString) operator");
bstr__memcpy (data, b.data, slen); } else {
data[slen] = '\0'; bstr__memcpy(data, b.data, slen);
} data[slen] = '\0';
return *this; }
} return *this;
}
const CBString& CBString::operator = (const tagbstring& x) {
if (mlen <= 0) bstringThrow ("Write protection error"); const CBString& CBString::operator=(const tagbstring& x) {
if (x.slen < 0) bstringThrow ("Failure in =(tagbstring) operator, badly formed tagbstring"); if (mlen <= 0) bstringThrow("Write protection error");
if (x.slen >= mlen) alloc (x.slen); if (x.slen < 0)
bstringThrow("Failure in =(tagbstring) operator, badly formed tagbstring");
slen = x.slen; if (x.slen >= mlen) alloc(x.slen);
if (!data) {
mlen = slen = 0; slen = x.slen;
bstringThrow ("Failure in =(tagbstring) operator"); if (!data) {
} else { mlen = slen = 0;
bstr__memcpy (data, x.data, slen); bstringThrow("Failure in =(tagbstring) operator");
data[slen] = '\0'; } else {
} bstr__memcpy(data, x.data, slen);
return *this; data[slen] = '\0';
} }
return *this;
const CBString& CBString::operator += (const CBString& b) { }
if (BSTR_ERR == bconcat (this, (bstring) &b)) {
bstringThrow ("Failure in concatenate"); const CBString& CBString::operator+=(const CBString& b) {
} if (BSTR_ERR == bconcat(this, (bstring) &b)) {
return *this; bstringThrow("Failure in concatenate");
} }
return *this;
const CBString& CBString::operator += (const char *s) { }
char * d;
int i, l; const CBString& CBString::operator+=(const char* s) {
char* d;
if (mlen <= 0) bstringThrow ("Write protection error"); int i, l;
/* Optimistically concatenate directly */ if (mlen <= 0) bstringThrow("Write protection error");
l = mlen - slen;
d = (char *) &data[slen]; /* Optimistically concatenate directly */
for (i=0; i < l; i++) { l = mlen - slen;
if ((*d++ = *s++) == '\0') { d = (char*) &data[slen];
slen += i; for (i = 0; i < l; i++) {
return *this; if ((*d++ = *s++) == '\0') {
} slen += i;
} return *this;
slen += i; }
}
if (BSTR_ERR == bcatcstr (this, s)) { slen += i;
bstringThrow ("Failure in concatenate");
} if (BSTR_ERR == bcatcstr(this, s)) {
return *this; bstringThrow("Failure in concatenate");
} }
return *this;
const CBString& CBString::operator += (char c) { }
if (BSTR_ERR == bconchar (this, c)) {
bstringThrow ("Failure in concatenate"); const CBString& CBString::operator+=(char c) {
} if (BSTR_ERR == bconchar(this, c)) {
return *this; bstringThrow("Failure in concatenate");
} }
return *this;
const CBString& CBString::operator += (unsigned char c) { }
if (BSTR_ERR == bconchar (this, (char) c)) {
bstringThrow ("Failure in concatenate"); const CBString& CBString::operator+=(unsigned char c) {
} if (BSTR_ERR == bconchar(this, (char) c)) {
return *this; bstringThrow("Failure in concatenate");
}
return *this;
} }
const CBString& CBString::operator += (const tagbstring& x) { const CBString& CBString::operator+=(const tagbstring& x) {
if (mlen <= 0) bstringThrow ("Write protection error"); if (mlen <= 0) bstringThrow("Write protection error");
if (x.slen < 0) bstringThrow ("Failure in +=(tagbstring) operator, badly formed tagbstring"); if (x.slen < 0)
alloc (x.slen + slen + 1); bstringThrow("Failure in +=(tagbstring) operator, badly formed tagbstring");
alloc(x.slen + slen + 1);
if (!data) {
mlen = slen = 0; if (!data) {
bstringThrow ("Failure in +=(tagbstring) operator"); mlen = slen = 0;
} else { bstringThrow("Failure in +=(tagbstring) operator");
bstr__memcpy (data + slen, x.data, x.slen); } else {
slen += x.slen; bstr__memcpy(data + slen, x.data, x.slen);
data[slen] = '\0'; slen += x.slen;
} data[slen] = '\0';
return *this; }
return *this;
} }
const CBString CBString::operator + (char c) const { const CBString CBString::operator+(char c) const {
CBString retval (*this); CBString retval(*this);
retval += c; retval += c;
return retval; return retval;
} }
const CBString CBString::operator + (unsigned char c) const { const CBString CBString::operator+(unsigned char c) const {
CBString retval (*this); CBString retval(*this);
retval += c; retval += c;
return retval; return retval;
} }
const CBString CBString::operator + (const CBString& b) const { const CBString CBString::operator+(const CBString& b) const {
CBString retval (*this); CBString retval(*this);
retval += b; retval += b;
return retval; return retval;
} }
const CBString CBString::operator + (const char *s) const { const CBString CBString::operator+(const char* s) const {
if (s == NULL) bstringThrow ("Failure in + (char *) operator, NULL"); if (s == NULL) bstringThrow("Failure in + (char *) operator, NULL");
CBString retval (*this); CBString retval(*this);
retval += s; retval += s;
return retval; return retval;
} }
const CBString CBString::operator + (const unsigned char *s) const { const CBString CBString::operator+(const unsigned char* s) const {
if (s == NULL) bstringThrow ("Failure in + (unsigned char *) operator, NULL"); if (s == NULL) bstringThrow("Failure in + (unsigned char *) operator, NULL");
CBString retval (*this); CBString retval(*this);
retval += (const char *) s; retval += (const char*) s;
return retval; return retval;
} }
const CBString CBString::operator + (const tagbstring& x) const { const CBString CBString::operator+(const tagbstring& x) const {
if (x.slen < 0) bstringThrow ("Failure in + (tagbstring) operator, badly formed tagbstring"); if (x.slen < 0)
CBString retval (*this); bstringThrow("Failure in + (tagbstring) operator, badly formed tagbstring");
retval += x; CBString retval(*this);
return retval; retval += x;
return retval;
} }
bool CBString::operator == (const CBString& b) const { bool CBString::operator==(const CBString& b) const {
int retval; int retval;
if (BSTR_ERR == (retval = biseq ((bstring)this, (bstring)&b))) { if (BSTR_ERR == (retval = biseq((bstring) this, (bstring) &b))) {
bstringThrow ("Failure in compare (==)"); bstringThrow("Failure in compare (==)");
} }
return retval > 0; return retval > 0;
} }
bool CBString::operator == (const char * s) const { bool CBString::operator==(const char* s) const {
int retval; int retval;
if (NULL == s) { if (NULL == s) {
bstringThrow ("Failure in compare (== NULL)"); bstringThrow("Failure in compare (== NULL)");
} }
if (BSTR_ERR == (retval = biseqcstr ((bstring) this, s))) { if (BSTR_ERR == (retval = biseqcstr((bstring) this, s))) {
bstringThrow ("Failure in compare (==)"); bstringThrow("Failure in compare (==)");
} }
return retval > 0; return retval > 0;
} }
bool CBString::operator == (const unsigned char * s) const { bool CBString::operator==(const unsigned char* s) const {
int retval; int retval;
if (NULL == s) { if (NULL == s) {
bstringThrow ("Failure in compare (== NULL)"); bstringThrow("Failure in compare (== NULL)");
} }
if (BSTR_ERR == (retval = biseqcstr ((bstring) this, (const char *) s))) { if (BSTR_ERR == (retval = biseqcstr((bstring) this, (const char*) s))) {
bstringThrow ("Failure in compare (==)"); bstringThrow("Failure in compare (==)");
} }
return retval > 0; return retval > 0;
} }
bool CBString::operator != (const CBString& b) const { bool CBString::operator!=(const CBString& b) const {
return ! ((*this) == b); return !((*this) == b);
} }
bool CBString::operator != (const char * s) const { bool CBString::operator!=(const char* s) const {
return ! ((*this) == s); return !((*this) == s);
} }
bool CBString::operator != (const unsigned char * s) const { bool CBString::operator!=(const unsigned char* s) const {
return ! ((*this) == s); return !((*this) == s);
} }
bool CBString::operator < (const CBString& b) const { bool CBString::operator<(const CBString& b) const {
int retval; int retval;
if (SHRT_MIN == (retval = bstrcmp ((bstring) this, (bstring)&b))) { if (SHRT_MIN == (retval = bstrcmp((bstring) this, (bstring) &b))) {
bstringThrow ("Failure in compare (<)"); bstringThrow("Failure in compare (<)");
} }
return retval < 0; return retval < 0;
} }
bool CBString::operator < (const char * s) const { bool CBString::operator<(const char* s) const {
if (s == NULL) { if (s == NULL) {
bstringThrow ("Failure in compare (<)"); bstringThrow("Failure in compare (<)");
} }
return strcmp ((const char *)this->data, s) < 0; return strcmp((const char*) this->data, s) < 0;
} }
bool CBString::operator < (const unsigned char * s) const { bool CBString::operator<(const unsigned char* s) const {
if (s == NULL) { if (s == NULL) {
bstringThrow ("Failure in compare (<)"); bstringThrow("Failure in compare (<)");
} }
return strcmp ((const char *)this->data, (const char *)s) < 0; return strcmp((const char*) this->data, (const char*) s) < 0;
} }
bool CBString::operator <= (const CBString& b) const { bool CBString::operator<=(const CBString& b) const {
int retval; int retval;
if (SHRT_MIN == (retval = bstrcmp ((bstring) this, (bstring)&b))) { if (SHRT_MIN == (retval = bstrcmp((bstring) this, (bstring) &b))) {
bstringThrow ("Failure in compare (<=)"); bstringThrow("Failure in compare (<=)");
} }
return retval <= 0; return retval <= 0;
} }
bool CBString::operator <= (const char * s) const { bool CBString::operator<=(const char* s) const {
if (s == NULL) { if (s == NULL) {
bstringThrow ("Failure in compare (<=)"); bstringThrow("Failure in compare (<=)");
} }
return strcmp ((const char *)this->data, s) <= 0; return strcmp((const char*) this->data, s) <= 0;
} }
bool CBString::operator <= (const unsigned char * s) const { bool CBString::operator<=(const unsigned char* s) const {
if (s == NULL) { if (s == NULL) {
bstringThrow ("Failure in compare (<=)"); bstringThrow("Failure in compare (<=)");
} }
return strcmp ((const char *)this->data, (const char *)s) <= 0; return strcmp((const char*) this->data, (const char*) s) <= 0;
} }
bool CBString::operator > (const CBString& b) const { bool CBString::operator>(const CBString& b) const {
return ! ((*this) <= b); return !((*this) <= b);
} }
bool CBString::operator > (const char * s) const { bool CBString::operator>(const char* s) const {
return ! ((*this) <= s); return !((*this) <= s);
} }
bool CBString::operator > (const unsigned char * s) const { bool CBString::operator>(const unsigned char* s) const {
return ! ((*this) <= s); return !((*this) <= s);
} }
bool CBString::operator >= (const CBString& b) const { bool CBString::operator>=(const CBString& b) const {
return ! ((*this) < b); return !((*this) < b);
} }
bool CBString::operator >= (const char * s) const { bool CBString::operator>=(const char* s) const {
return ! ((*this) < s); return !((*this) < s);
} }
bool CBString::operator >= (const unsigned char * s) const { bool CBString::operator>=(const unsigned char* s) const {
return ! ((*this) < s); return !((*this) < s);
} }
CBString::operator double () const { CBString::operator double() const {
double d = 0; double d = 0;
if (1 != sscanf ((const char *)this->data, "%lf", &d)) { if (1 != sscanf((const char*) this->data, "%lf", &d)) {
bstringThrow ("Unable to convert to a double"); bstringThrow("Unable to convert to a double");
} }
return d; return d;
} }
CBString::operator float () const { CBString::operator float() const {
float d = 0; float d = 0;
if (1 != sscanf ((const char *)this->data, "%f", &d)) { if (1 != sscanf((const char*) this->data, "%f", &d)) {
bstringThrow ("Unable to convert to a float"); bstringThrow("Unable to convert to a float");
} }
return d; return d;
} }
CBString::operator int () const { CBString::operator int() const {
int d = 0; int d = 0;
if (1 != sscanf ((const char *)this->data, "%d", &d)) { if (1 != sscanf((const char*) this->data, "%d", &d)) {
bstringThrow ("Unable to convert to an int"); bstringThrow("Unable to convert to an int");
} }
return d; return d;
} }
CBString::operator unsigned int () const { CBString::operator unsigned int() const {
unsigned int d = 0; unsigned int d = 0;
if (1 != sscanf ((const char *)this->data, "%u", &d)) { if (1 != sscanf((const char*) this->data, "%u", &d)) {
bstringThrow ("Unable to convert to an unsigned int"); bstringThrow("Unable to convert to an unsigned int");
} }
return d; return d;
} }
#ifdef __TURBOC__ #ifdef __TURBOC__
# ifndef BSTRLIB_NOVSNP #ifndef BSTRLIB_NOVSNP
# define BSTRLIB_NOVSNP #define BSTRLIB_NOVSNP
# endif #endif
#endif #endif
/* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */ /* Give WATCOM C/C++, MSVC some latitude for their non-support of vsnprintf */
#if defined(__WATCOMC__) || defined(_MSC_VER) #if defined(__WATCOMC__) || defined(_MSC_VER)
#define exvsnprintf(r,b,n,f,a) {r = _vsnprintf (b,n,f,a);} #define exvsnprintf(r, b, n, f, a) \
{ r = _vsnprintf(b, n, f, a); }
#else #else
#ifdef BSTRLIB_NOVSNP #ifdef BSTRLIB_NOVSNP
/* This is just a hack. If you are using a system without a vsnprintf, it is /* This is just a hack. If you are using a system without a vsnprintf, it is
not recommended that bformat be used at all. */ not recommended that bformat be used at all. */
#define exvsnprintf(r,b,n,f,a) {vsprintf (b,f,a); r = -1;} #define exvsnprintf(r, b, n, f, a) \
{ \
vsprintf(b, f, a); \
r = -1; \
}
#define START_VSNBUFF (256) #define START_VSNBUFF (256)
#else #else
#if defined (__GNUC__) && !defined (__PPC__) #if defined(__GNUC__) && !defined(__PPC__)
/* Something is making gcc complain about this prototype not being here, so /* Something is making gcc complain about this prototype not being here, so
I've just gone ahead and put it in. */ I've just gone ahead and put it in. */
extern "C" { extern "C" {
extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg); extern int vsnprintf(char* buf, size_t count, const char* format, va_list arg);
} }
#endif #endif
#define exvsnprintf(r,b,n,f,a) {r = vsnprintf (b,n,f,a);} #define exvsnprintf(r, b, n, f, a) \
{ r = vsnprintf(b, n, f, a); }
#endif #endif
#endif #endif
...@@ -559,1163 +571,1175 @@ extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg); ...@@ -559,1163 +571,1175 @@ extern int vsnprintf (char *buf, size_t count, const char *format, va_list arg);
/* /*
* Yeah I'd like to just call a vformat function or something, but because of * Yeah I'd like to just call a vformat function or something, but because of
* the ANSI specified brokeness of the va_* macros, it is actually not * the ANSI specified brokeness of the va_* macros, it is actually not
* possible to do this correctly. * possible to do this correctly.
*/ */
void CBString::format (const char * fmt, ...) { void CBString::format(const char* fmt, ...) {
bstring b; bstring b;
va_list arglist; va_list arglist;
int r, n; int r, n;
if (mlen <= 0) bstringThrow ("Write protection error"); if (mlen <= 0) bstringThrow("Write protection error");
if (fmt == NULL) { if (fmt == NULL) {
*this = "<NULL>"; *this = "<NULL>";
bstringThrow ("CBString::format (NULL, ...) is erroneous."); bstringThrow("CBString::format (NULL, ...) is erroneous.");
} else { } else {
if ((b = bfromcstr("")) == NULL) {
if ((b = bfromcstr ("")) == NULL) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::format out of memory."); bstringThrow("CBString::format out of memory.");
#else #else
*this = "<NULL>"; *this = "<NULL>";
#endif #endif
} else { } else {
if ((n = (int) (2 * (strlen) (fmt))) < START_VSNBUFF) n = START_VSNBUFF; if ((n = (int) (2 * (strlen)(fmt))) < START_VSNBUFF) n = START_VSNBUFF;
for (;;) { for (;;) {
if (BSTR_OK != balloc (b, n + 2)) { if (BSTR_OK != balloc(b, n + 2)) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::format out of memory."); bstringThrow("CBString::format out of memory.");
#else #else
b = bformat ("<NULL>"); b = bformat("<NULL>");
break; break;
#endif #endif
} }
va_start (arglist, fmt); va_start(arglist, fmt);
exvsnprintf (r, (char *) b->data, n + 1, fmt, arglist); exvsnprintf(r, (char*) b->data, n + 1, fmt, arglist);
va_end (arglist); va_end(arglist);
b->data[n] = '\0'; b->data[n] = '\0';
b->slen = (int) (strlen) ((char *) b->data); b->slen = (int) (strlen)((char*) b->data);
if (b->slen < n) break; if (b->slen < n) break;
if (r > n) n = r; else n += n; if (r > n)
} n = r;
*this = *b; else
bdestroy (b); n += n;
} }
} *this = *b;
} bdestroy(b);
}
void CBString::formata (const char * fmt, ...) { }
bstring b; }
va_list arglist;
int r, n; void CBString::formata(const char* fmt, ...) {
bstring b;
if (mlen <= 0) bstringThrow ("Write protection error"); va_list arglist;
if (fmt == NULL) { int r, n;
*this += "<NULL>";
bstringThrow ("CBString::formata (NULL, ...) is erroneous."); if (mlen <= 0) bstringThrow("Write protection error");
} else { if (fmt == NULL) {
*this += "<NULL>";
if ((b = bfromcstr ("")) == NULL) { bstringThrow("CBString::formata (NULL, ...) is erroneous.");
} else {
if ((b = bfromcstr("")) == NULL) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::format out of memory."); bstringThrow("CBString::format out of memory.");
#else #else
*this += "<NULL>"; *this += "<NULL>";
#endif #endif
} else { } else {
if ((n = (int) (2 * (strlen) (fmt))) < START_VSNBUFF) n = START_VSNBUFF; if ((n = (int) (2 * (strlen)(fmt))) < START_VSNBUFF) n = START_VSNBUFF;
for (;;) { for (;;) {
if (BSTR_OK != balloc (b, n + 2)) { if (BSTR_OK != balloc(b, n + 2)) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::format out of memory."); bstringThrow("CBString::format out of memory.");
#else #else
b = bformat ("<NULL>"); b = bformat("<NULL>");
break; break;
#endif #endif
} }
va_start (arglist, fmt); va_start(arglist, fmt);
exvsnprintf (r, (char *) b->data, n + 1, fmt, arglist); exvsnprintf(r, (char*) b->data, n + 1, fmt, arglist);
va_end (arglist); va_end(arglist);
b->data[n] = '\0'; b->data[n] = '\0';
b->slen = (int) (strlen) ((char *) b->data); b->slen = (int) (strlen)((char*) b->data);
if (b->slen < n) break; if (b->slen < n) break;
if (r > n) n = r; else n += n; if (r > n)
} n = r;
*this += *b; else
bdestroy (b); n += n;
} }
} *this += *b;
bdestroy(b);
}
}
} }
int CBString::caselessEqual (const CBString& b) const { int CBString::caselessEqual(const CBString& b) const {
int ret; int ret;
if (BSTR_ERR == (ret = biseqcaseless ((bstring) this, (bstring) &b))) { if (BSTR_ERR == (ret = biseqcaseless((bstring) this, (bstring) &b))) {
bstringThrow ("CBString::caselessEqual Unable to compare"); bstringThrow("CBString::caselessEqual Unable to compare");
} }
return ret; return ret;
} }
int CBString::caselessCmp (const CBString& b) const { int CBString::caselessCmp(const CBString& b) const {
int ret; int ret;
if (SHRT_MIN == (ret = bstricmp ((bstring) this, (bstring) &b))) { if (SHRT_MIN == (ret = bstricmp((bstring) this, (bstring) &b))) {
bstringThrow ("CBString::caselessCmp Unable to compare"); bstringThrow("CBString::caselessCmp Unable to compare");
} }
return ret; return ret;
} }
int CBString::find (const CBString& b, int pos) const { int CBString::find(const CBString& b, int pos) const {
return binstr ((bstring) this, pos, (bstring) &b); return binstr((bstring) this, pos, (bstring) &b);
} }
/* /*
int CBString::find (const char * b, int pos) const; int CBString::find (const char * b, int pos) const;
Uses and unrolling and sliding paired indexes character matching. Since Uses and unrolling and sliding paired indexes character matching. Since
the unrolling is the primary real world impact the true purpose of this the unrolling is the primary real world impact the true purpose of this
algorithm choice is maximize the effectiveness of the unrolling. The algorithm choice is maximize the effectiveness of the unrolling. The
idea is to scan until at least one match of the current indexed character idea is to scan until at least one match of the current indexed character
from each string, and then shift indexes of both down by and repeat until from each string, and then shift indexes of both down by and repeat until
the last character form b matches. When the last character from b the last character form b matches. When the last character from b
matches if the were no mismatches in previous strlen(b) characters then matches if the were no mismatches in previous strlen(b) characters then
we know we have a full match, otherwise shift both indexes back strlen(b) we know we have a full match, otherwise shift both indexes back strlen(b)
characters and continue. characters and continue.
In general, if there is any character in b that is not at all in this In general, if there is any character in b that is not at all in this
CBString, then this algorithm is O(slen). The algorithm does not easily CBString, then this algorithm is O(slen). The algorithm does not easily
degenerate into O(slen * strlen(b)) performance except in very uncommon degenerate into O(slen * strlen(b)) performance except in very uncommon
situations. Thus from a real world perspective, the overhead of situations. Thus from a real world perspective, the overhead of
precomputing suffix shifts in the Boyer-Moore algorithm is avoided, while precomputing suffix shifts in the Boyer-Moore algorithm is avoided, while
delivering an unrolled matching inner loop most of the time. delivering an unrolled matching inner loop most of the time.
*/ */
int CBString::find (const char * b, int pos) const { int CBString::find(const char* b, int pos) const {
int ii, j; int ii, j;
unsigned char c0; unsigned char c0;
register int i, l; register int i, l;
register unsigned char cx; register unsigned char cx;
register unsigned char * pdata; register unsigned char* pdata;
if (NULL == b) { if (NULL == b) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::find NULL."); bstringThrow("CBString::find NULL.");
#else #else
return BSTR_ERR; return BSTR_ERR;
#endif #endif
} }
if ((unsigned int) pos > (unsigned int) slen) return BSTR_ERR; if ((unsigned int) pos > (unsigned int) slen) return BSTR_ERR;
if ('\0' == b[0]) return pos; if ('\0' == b[0]) return pos;
if (pos == slen) return BSTR_ERR; if (pos == slen) return BSTR_ERR;
if ('\0' == b[1]) return find (b[0], pos); if ('\0' == b[1]) return find(b[0], pos);
cx = c0 = (unsigned char) b[0]; cx = c0 = (unsigned char) b[0];
l = slen - 1; l = slen - 1;
pdata = data; pdata = data;
for (ii = -1, i = pos, j = 0; i < l;) { for (ii = -1, i = pos, j = 0; i < l;) {
/* Unrolled current character test */ /* Unrolled current character test */
if (cx != pdata[i]) { if (cx != pdata[i]) {
if (cx != pdata[1+i]) { if (cx != pdata[1 + i]) {
i += 2; i += 2;
continue; continue;
} }
i++; i++;
} }
/* Take note if this is the start of a potential match */ /* Take note if this is the start of a potential match */
if (0 == j) ii = i; if (0 == j) ii = i;
/* Shift the test character down by one */ /* Shift the test character down by one */
j++; j++;
i++; i++;
/* If this isn't past the last character continue */ /* If this isn't past the last character continue */
if ('\0' != (cx = b[j])) continue; if ('\0' != (cx = b[j])) continue;
N0:; N0:;
/* If no characters mismatched, then we matched */ /* If no characters mismatched, then we matched */
if (i == ii+j) return ii; if (i == ii + j) return ii;
/* Shift back to the beginning */ /* Shift back to the beginning */
i -= j; i -= j;
j = 0; j = 0;
cx = c0; cx = c0;
} }
/* Deal with last case if unrolling caused a misalignment */ /* Deal with last case if unrolling caused a misalignment */
if (i == l && cx == pdata[i] && '\0' == b[j+1]) goto N0; if (i == l && cx == pdata[i] && '\0' == b[j + 1]) goto N0;
return BSTR_ERR; return BSTR_ERR;
} }
int CBString::caselessfind (const CBString& b, int pos) const { int CBString::caselessfind(const CBString& b, int pos) const {
return binstrcaseless ((bstring) this, pos, (bstring) &b); return binstrcaseless((bstring) this, pos, (bstring) &b);
} }
int CBString::caselessfind (const char * b, int pos) const { int CBString::caselessfind(const char* b, int pos) const {
struct tagbstring t; struct tagbstring t;
if (NULL == b) { if (NULL == b) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::caselessfind NULL."); bstringThrow("CBString::caselessfind NULL.");
#else #else
return BSTR_ERR; return BSTR_ERR;
#endif #endif
} }
if ((unsigned int) pos > (unsigned int) slen) return BSTR_ERR; if ((unsigned int) pos > (unsigned int) slen) return BSTR_ERR;
if ('\0' == b[0]) return pos; if ('\0' == b[0]) return pos;
if (pos == slen) return BSTR_ERR; if (pos == slen) return BSTR_ERR;
btfromcstr (t, b); btfromcstr(t, b);
return binstrcaseless ((bstring) this, pos, (bstring) &t); return binstrcaseless((bstring) this, pos, (bstring) &t);
} }
int CBString::find (char c, int pos) const { int CBString::find(char c, int pos) const {
if (pos < 0) return BSTR_ERR; if (pos < 0) return BSTR_ERR;
for (;pos < slen; pos++) { for (; pos < slen; pos++) {
if (data[pos] == (unsigned char) c) return pos; if (data[pos] == (unsigned char) c) return pos;
} }
return BSTR_ERR; return BSTR_ERR;
} }
int CBString::reversefind (const CBString& b, int pos) const { int CBString::reversefind(const CBString& b, int pos) const {
return binstrr ((bstring) this, pos, (bstring) &b); return binstrr((bstring) this, pos, (bstring) &b);
} }
int CBString::reversefind (const char * b, int pos) const { int CBString::reversefind(const char* b, int pos) const {
struct tagbstring t; struct tagbstring t;
if (NULL == b) { if (NULL == b) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::reversefind NULL."); bstringThrow("CBString::reversefind NULL.");
#else #else
return BSTR_ERR; return BSTR_ERR;
#endif #endif
} }
cstr2tbstr (t, b); cstr2tbstr(t, b);
return binstrr ((bstring) this, pos, &t); return binstrr((bstring) this, pos, &t);
} }
int CBString::caselessreversefind (const CBString& b, int pos) const { int CBString::caselessreversefind(const CBString& b, int pos) const {
return binstrrcaseless ((bstring) this, pos, (bstring) &b); return binstrrcaseless((bstring) this, pos, (bstring) &b);
} }
int CBString::caselessreversefind (const char * b, int pos) const { int CBString::caselessreversefind(const char* b, int pos) const {
struct tagbstring t; struct tagbstring t;
if (NULL == b) { if (NULL == b) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::caselessreversefind NULL."); bstringThrow("CBString::caselessreversefind NULL.");
#else #else
return BSTR_ERR; return BSTR_ERR;
#endif #endif
} }
if ((unsigned int) pos > (unsigned int) slen) return BSTR_ERR; if ((unsigned int) pos > (unsigned int) slen) return BSTR_ERR;
if ('\0' == b[0]) return pos; if ('\0' == b[0]) return pos;
if (pos == slen) return BSTR_ERR; if (pos == slen) return BSTR_ERR;
btfromcstr (t, b); btfromcstr(t, b);
return binstrrcaseless ((bstring) this, pos, (bstring) &t); return binstrrcaseless((bstring) this, pos, (bstring) &t);
} }
int CBString::reversefind (char c, int pos) const { int CBString::reversefind(char c, int pos) const {
if (pos > slen) return BSTR_ERR; if (pos > slen) return BSTR_ERR;
if (pos == slen) pos--; if (pos == slen) pos--;
for (;pos >= 0; pos--) { for (; pos >= 0; pos--) {
if (data[pos] == (unsigned char) c) return pos; if (data[pos] == (unsigned char) c) return pos;
} }
return BSTR_ERR; return BSTR_ERR;
} }
int CBString::findchr (const CBString& b, int pos) const { int CBString::findchr(const CBString& b, int pos) const {
return binchr ((bstring) this, pos, (bstring) &b); return binchr((bstring) this, pos, (bstring) &b);
} }
int CBString::findchr (const char * s, int pos) const { int CBString::findchr(const char* s, int pos) const {
struct tagbstring t; struct tagbstring t;
if (NULL == s) { if (NULL == s) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::findchr NULL."); bstringThrow("CBString::findchr NULL.");
#else #else
return BSTR_ERR; return BSTR_ERR;
#endif #endif
} }
cstr2tbstr (t, s); cstr2tbstr(t, s);
return binchr ((bstring) this, pos, (bstring) &t); return binchr((bstring) this, pos, (bstring) &t);
} }
int CBString::nfindchr (const CBString& b, int pos) const { int CBString::nfindchr(const CBString& b, int pos) const {
return bninchr ((bstring) this, pos, (bstring) &b); return bninchr((bstring) this, pos, (bstring) &b);
} }
int CBString::nfindchr (const char * s, int pos) const { int CBString::nfindchr(const char* s, int pos) const {
struct tagbstring t; struct tagbstring t;
if (NULL == s) { if (NULL == s) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::nfindchr NULL."); bstringThrow("CBString::nfindchr NULL.");
#else #else
return BSTR_ERR; return BSTR_ERR;
#endif #endif
} }
cstr2tbstr (t, s); cstr2tbstr(t, s);
return bninchr ((bstring) this, pos, &t); return bninchr((bstring) this, pos, &t);
} }
int CBString::reversefindchr (const CBString& b, int pos) const { int CBString::reversefindchr(const CBString& b, int pos) const {
return binchrr ((bstring) this, pos, (bstring) &b); return binchrr((bstring) this, pos, (bstring) &b);
} }
int CBString::reversefindchr (const char * s, int pos) const { int CBString::reversefindchr(const char* s, int pos) const {
struct tagbstring t; struct tagbstring t;
if (NULL == s) { if (NULL == s) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::reversefindchr NULL."); bstringThrow("CBString::reversefindchr NULL.");
#else #else
return BSTR_ERR; return BSTR_ERR;
#endif #endif
} }
cstr2tbstr (t, s); cstr2tbstr(t, s);
return binchrr ((bstring) this, pos, &t); return binchrr((bstring) this, pos, &t);
} }
int CBString::nreversefindchr (const CBString& b, int pos) const { int CBString::nreversefindchr(const CBString& b, int pos) const {
return bninchrr ((bstring) this, pos, (bstring) &b); return bninchrr((bstring) this, pos, (bstring) &b);
} }
int CBString::nreversefindchr (const char * s, int pos) const { int CBString::nreversefindchr(const char* s, int pos) const {
struct tagbstring t; struct tagbstring t;
if (NULL == s) { if (NULL == s) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("CBString::nreversefindchr NULL."); bstringThrow("CBString::nreversefindchr NULL.");
#else #else
return BSTR_ERR; return BSTR_ERR;
#endif #endif
} }
cstr2tbstr (t, s); cstr2tbstr(t, s);
return bninchrr ((bstring) this, pos, &t); return bninchrr((bstring) this, pos, &t);
} }
const CBString CBString::midstr (int left, int len) const { const CBString CBString::midstr(int left, int len) const {
struct tagbstring t; struct tagbstring t;
if (left < 0) { if (left < 0) {
len += left; len += left;
left = 0; left = 0;
} }
if (len > slen - left) len = slen - left; if (len > slen - left) len = slen - left;
if (len <= 0) return CBString (""); if (len <= 0) return CBString("");
blk2tbstr (t, data + left, len); blk2tbstr(t, data + left, len);
return CBString (t); return CBString(t);
} }
void CBString::alloc (int len) { void CBString::alloc(int len) {
if (BSTR_ERR == balloc ((bstring)this, len)) { if (BSTR_ERR == balloc((bstring) this, len)) {
bstringThrow ("Failure in alloc"); bstringThrow("Failure in alloc");
} }
} }
void CBString::fill (int len, unsigned char cfill) { void CBString::fill(int len, unsigned char cfill) {
slen = 0; slen = 0;
if (BSTR_ERR == bsetstr (this, len, NULL, cfill)) { if (BSTR_ERR == bsetstr(this, len, NULL, cfill)) {
bstringThrow ("Failure in fill"); bstringThrow("Failure in fill");
} }
} }
void CBString::setsubstr (int pos, const CBString& b, unsigned char cfill) { void CBString::setsubstr(int pos, const CBString& b, unsigned char cfill) {
if (BSTR_ERR == bsetstr (this, pos, (bstring) &b, cfill)) { if (BSTR_ERR == bsetstr(this, pos, (bstring) &b, cfill)) {
bstringThrow ("Failure in setsubstr"); bstringThrow("Failure in setsubstr");
} }
} }
void CBString::setsubstr (int pos, const char * s, unsigned char cfill) { void CBString::setsubstr(int pos, const char* s, unsigned char cfill) {
struct tagbstring t; struct tagbstring t;
if (NULL == s) { if (NULL == s) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("setsubstr NULL."); bstringThrow("setsubstr NULL.");
#else #else
return; return;
#endif #endif
} }
cstr2tbstr (t, s); cstr2tbstr(t, s);
if (BSTR_ERR == bsetstr (this, pos, &t, cfill)) { if (BSTR_ERR == bsetstr(this, pos, &t, cfill)) {
bstringThrow ("Failure in setsubstr"); bstringThrow("Failure in setsubstr");
} }
} }
void CBString::insert (int pos, const CBString& b, unsigned char cfill) { void CBString::insert(int pos, const CBString& b, unsigned char cfill) {
if (BSTR_ERR == binsert (this, pos, (bstring) &b, cfill)) { if (BSTR_ERR == binsert(this, pos, (bstring) &b, cfill)) {
bstringThrow ("Failure in insert"); bstringThrow("Failure in insert");
} }
} }
void CBString::insert (int pos, const char * s, unsigned char cfill) { void CBString::insert(int pos, const char* s, unsigned char cfill) {
struct tagbstring t; struct tagbstring t;
if (NULL == s) { if (NULL == s) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("insert NULL."); bstringThrow("insert NULL.");
#else #else
return; return;
#endif #endif
} }
cstr2tbstr (t, s); cstr2tbstr(t, s);
if (BSTR_ERR == binsert (this, pos, &t, cfill)) { if (BSTR_ERR == binsert(this, pos, &t, cfill)) {
bstringThrow ("Failure in insert"); bstringThrow("Failure in insert");
} }
} }
void CBString::insertchrs (int pos, int len, unsigned char cfill) { void CBString::insertchrs(int pos, int len, unsigned char cfill) {
if (BSTR_ERR == binsertch (this, pos, len, cfill)) { if (BSTR_ERR == binsertch(this, pos, len, cfill)) {
bstringThrow ("Failure in insertchrs"); bstringThrow("Failure in insertchrs");
} }
} }
void CBString::replace (int pos, int len, const CBString& b, unsigned char cfill) { void CBString::replace(
if (BSTR_ERR == breplace (this, pos, len, (bstring) &b, cfill)) { int pos, int len, const CBString& b, unsigned char cfill) {
bstringThrow ("Failure in replace"); if (BSTR_ERR == breplace(this, pos, len, (bstring) &b, cfill)) {
} bstringThrow("Failure in replace");
} }
}
void CBString::replace (int pos, int len, const char * s, unsigned char cfill) {
struct tagbstring t; void CBString::replace(int pos, int len, const char* s, unsigned char cfill) {
size_t q; struct tagbstring t;
size_t q;
if (mlen <= 0) bstringThrow ("Write protection error");
if (NULL == s || (pos|len) < 0) { if (mlen <= 0) bstringThrow("Write protection error");
bstringThrow ("Failure in replace"); if (NULL == s || (pos | len) < 0) {
} else { bstringThrow("Failure in replace");
if (pos + len >= slen) { } else {
cstr2tbstr (t, s); if (pos + len >= slen) {
if (BSTR_ERR == bsetstr (this, pos, &t, cfill)) { cstr2tbstr(t, s);
bstringThrow ("Failure in replace"); if (BSTR_ERR == bsetstr(this, pos, &t, cfill)) {
} else if (pos + t.slen < slen) { bstringThrow("Failure in replace");
slen = pos + t.slen; } else if (pos + t.slen < slen) {
data[slen] = '\0'; slen = pos + t.slen;
} data[slen] = '\0';
} else { }
} else {
/* Aliasing case */ /* Aliasing case */
if ((unsigned int) (data - (unsigned char *) s) < (unsigned int) slen) { if ((unsigned int) (data - (unsigned char*) s) < (unsigned int) slen) {
replace (pos, len, CBString(s), cfill); replace(pos, len, CBString(s), cfill);
return; return;
} }
if ((q = strlen (s)) > (size_t) len || len < 0) { if ((q = strlen(s)) > (size_t) len || len < 0) {
if (slen + q - len >= INT_MAX) bstringThrow ("Failure in replace, result too long."); if (slen + q - len >= INT_MAX)
alloc ((int) (slen + q - len)); bstringThrow("Failure in replace, result too long.");
if (NULL == data) return; alloc((int) (slen + q - len));
} if (NULL == data) return;
if ((int) q != len) bstr__memmove (data + pos + q, data + pos + len, slen - (pos + len)); }
bstr__memcpy (data + pos, s, q); if ((int) q != len)
slen += ((int) q) - len; bstr__memmove(data + pos + q, data + pos + len, slen - (pos + len));
data[slen] = '\0'; bstr__memcpy(data + pos, s, q);
} slen += ((int) q) - len;
} data[slen] = '\0';
} }
}
void CBString::findreplace (const CBString& sfind, const CBString& repl, int pos) { }
if (BSTR_ERR == bfindreplace (this, (bstring) &sfind, (bstring) &repl, pos)) {
bstringThrow ("Failure in findreplace"); void CBString::findreplace(
} const CBString& sfind, const CBString& repl, int pos) {
} if (BSTR_ERR == bfindreplace(this, (bstring) &sfind, (bstring) &repl, pos)) {
bstringThrow("Failure in findreplace");
void CBString::findreplace (const CBString& sfind, const char * repl, int pos) { }
struct tagbstring t; }
if (NULL == repl) {
void CBString::findreplace(const CBString& sfind, const char* repl, int pos) {
struct tagbstring t;
if (NULL == repl) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("findreplace NULL."); bstringThrow("findreplace NULL.");
#else #else
return; return;
#endif #endif
} }
cstr2tbstr (t, repl); cstr2tbstr(t, repl);
if (BSTR_ERR == bfindreplace (this, (bstring) &sfind, (bstring) &t, pos)) { if (BSTR_ERR == bfindreplace(this, (bstring) &sfind, (bstring) &t, pos)) {
bstringThrow ("Failure in findreplace"); bstringThrow("Failure in findreplace");
} }
} }
void CBString::findreplace (const char * sfind, const CBString& repl, int pos) { void CBString::findreplace(const char* sfind, const CBString& repl, int pos) {
struct tagbstring t; struct tagbstring t;
if (NULL == sfind) { if (NULL == sfind) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("findreplace NULL."); bstringThrow("findreplace NULL.");
#else #else
return; return;
#endif #endif
} }
cstr2tbstr (t, sfind); cstr2tbstr(t, sfind);
if (BSTR_ERR == bfindreplace (this, (bstring) &t, (bstring) &repl, pos)) { if (BSTR_ERR == bfindreplace(this, (bstring) &t, (bstring) &repl, pos)) {
bstringThrow ("Failure in findreplace"); bstringThrow("Failure in findreplace");
} }
} }
void CBString::findreplace (const char * sfind, const char * repl, int pos) { void CBString::findreplace(const char* sfind, const char* repl, int pos) {
struct tagbstring t, u; struct tagbstring t, u;
if (NULL == repl || NULL == sfind) { if (NULL == repl || NULL == sfind) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("findreplace NULL."); bstringThrow("findreplace NULL.");
#else #else
return; return;
#endif #endif
} }
cstr2tbstr (t, sfind); cstr2tbstr(t, sfind);
cstr2tbstr (u, repl); cstr2tbstr(u, repl);
if (BSTR_ERR == bfindreplace (this, (bstring) &t, (bstring) &u, pos)) { if (BSTR_ERR == bfindreplace(this, (bstring) &t, (bstring) &u, pos)) {
bstringThrow ("Failure in findreplace"); bstringThrow("Failure in findreplace");
} }
} }
void CBString::findreplacecaseless (const CBString& sfind, const CBString& repl, int pos) { void CBString::findreplacecaseless(
if (BSTR_ERR == bfindreplacecaseless (this, (bstring) &sfind, (bstring) &repl, pos)) { const CBString& sfind, const CBString& repl, int pos) {
bstringThrow ("Failure in findreplacecaseless"); if (BSTR_ERR ==
} bfindreplacecaseless(this, (bstring) &sfind, (bstring) &repl, pos)) {
} bstringThrow("Failure in findreplacecaseless");
}
void CBString::findreplacecaseless (const CBString& sfind, const char * repl, int pos) { }
struct tagbstring t;
if (NULL == repl) { void CBString::findreplacecaseless(
const CBString& sfind, const char* repl, int pos) {
struct tagbstring t;
if (NULL == repl) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("findreplacecaseless NULL."); bstringThrow("findreplacecaseless NULL.");
#else #else
return; return;
#endif #endif
} }
cstr2tbstr (t, repl); cstr2tbstr(t, repl);
if (BSTR_ERR == bfindreplacecaseless (this, (bstring) &sfind, (bstring) &t, pos)) { if (BSTR_ERR ==
bstringThrow ("Failure in findreplacecaseless"); bfindreplacecaseless(this, (bstring) &sfind, (bstring) &t, pos)) {
} bstringThrow("Failure in findreplacecaseless");
} }
}
void CBString::findreplacecaseless (const char * sfind, const CBString& repl, int pos) {
struct tagbstring t; void CBString::findreplacecaseless(
if (NULL == sfind) { const char* sfind, const CBString& repl, int pos) {
struct tagbstring t;
if (NULL == sfind) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("findreplacecaseless NULL."); bstringThrow("findreplacecaseless NULL.");
#else #else
return; return;
#endif #endif
} }
cstr2tbstr (t, sfind); cstr2tbstr(t, sfind);
if (BSTR_ERR == bfindreplacecaseless (this, (bstring) &t, (bstring) &repl, pos)) { if (BSTR_ERR ==
bstringThrow ("Failure in findreplacecaseless"); bfindreplacecaseless(this, (bstring) &t, (bstring) &repl, pos)) {
} bstringThrow("Failure in findreplacecaseless");
} }
}
void CBString::findreplacecaseless (const char * sfind, const char * repl, int pos) {
struct tagbstring t, u; void CBString::findreplacecaseless(
if (NULL == repl || NULL == sfind) { const char* sfind, const char* repl, int pos) {
struct tagbstring t, u;
if (NULL == repl || NULL == sfind) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("findreplacecaseless NULL."); bstringThrow("findreplacecaseless NULL.");
#else #else
return; return;
#endif #endif
} }
cstr2tbstr (t, sfind); cstr2tbstr(t, sfind);
cstr2tbstr (u, repl); cstr2tbstr(u, repl);
if (BSTR_ERR == bfindreplacecaseless (this, (bstring) &t, (bstring) &u, pos)) { if (BSTR_ERR == bfindreplacecaseless(this, (bstring) &t, (bstring) &u, pos)) {
bstringThrow ("Failure in findreplacecaseless"); bstringThrow("Failure in findreplacecaseless");
} }
} }
void CBString::remove (int pos, int len) { void CBString::remove(int pos, int len) {
if (BSTR_ERR == bdelete (this, pos, len)) { if (BSTR_ERR == bdelete(this, pos, len)) {
bstringThrow ("Failure in remove"); bstringThrow("Failure in remove");
} }
} }
void CBString::trunc (int len) { void CBString::trunc(int len) {
if (len < 0) { if (len < 0) {
bstringThrow ("Failure in trunc"); bstringThrow("Failure in trunc");
} }
if (len < slen) { if (len < slen) {
slen = len; slen = len;
data[len] = '\0'; data[len] = '\0';
} }
} }
void CBString::ltrim (const CBString& b) { void CBString::ltrim(const CBString& b) {
int l = nfindchr (b, 0); int l = nfindchr(b, 0);
if (l == BSTR_ERR) l = slen; if (l == BSTR_ERR) l = slen;
remove (0, l); remove(0, l);
} }
void CBString::rtrim (const CBString& b) { void CBString::rtrim(const CBString& b) {
int l = nreversefindchr (b, slen - 1); int l = nreversefindchr(b, slen - 1);
#if BSTR_ERR != -1 #if BSTR_ERR != -1
if (l == BSTR_ERR) l = -1; if (l == BSTR_ERR) l = -1;
#endif #endif
slen = l + 1; slen = l + 1;
if (mlen > slen) data[slen] = '\0'; if (mlen > slen) data[slen] = '\0';
} }
void CBString::toupper () { void CBString::toupper() {
if (BSTR_ERR == btoupper ((bstring) this)) { if (BSTR_ERR == btoupper((bstring) this)) {
bstringThrow ("Failure in toupper"); bstringThrow("Failure in toupper");
} }
} }
void CBString::tolower () { void CBString::tolower() {
if (BSTR_ERR == btolower ((bstring) this)) { if (BSTR_ERR == btolower((bstring) this)) {
bstringThrow ("Failure in tolower"); bstringThrow("Failure in tolower");
} }
} }
void CBString::repeat (int count) { void CBString::repeat(int count) {
count *= slen; count *= slen;
if (count == 0) { if (count == 0) {
trunc (0); trunc(0);
return; return;
} }
if (count < 0 || BSTR_ERR == bpattern (this, count)) { if (count < 0 || BSTR_ERR == bpattern(this, count)) {
bstringThrow ("Failure in repeat"); bstringThrow("Failure in repeat");
} }
} }
int CBString::gets (bNgetc getcPtr, void * parm, char terminator) { int CBString::gets(bNgetc getcPtr, void* parm, char terminator) {
if (mlen <= 0) bstringThrow ("Write protection error"); if (mlen <= 0) bstringThrow("Write protection error");
bstring b = bgets (getcPtr, parm, terminator); bstring b = bgets(getcPtr, parm, terminator);
if (b == NULL) { if (b == NULL) {
slen = 0; slen = 0;
return -1; return -1;
} }
*this = *b; *this = *b;
bdestroy (b); bdestroy(b);
return 0; return 0;
} }
int CBString::read (bNread readPtr, void * parm) { int CBString::read(bNread readPtr, void* parm) {
if (mlen <= 0) bstringThrow ("Write protection error"); if (mlen <= 0) bstringThrow("Write protection error");
bstring b = bread (readPtr, parm); bstring b = bread(readPtr, parm);
if (b == NULL) { if (b == NULL) {
slen = 0; slen = 0;
return -1; return -1;
} }
*this = *b; *this = *b;
bdestroy (b); bdestroy(b);
return 0; return 0;
} }
const CBString operator + (const char *a, const CBString& b) { const CBString operator+(const char* a, const CBString& b) {
return CBString(a) + b; return CBString(a) + b;
} }
const CBString operator + (const unsigned char *a, const CBString& b) { const CBString operator+(const unsigned char* a, const CBString& b) {
return CBString((const char *)a) + b; return CBString((const char*) a) + b;
} }
const CBString operator + (char c, const CBString& b) { const CBString operator+(char c, const CBString& b) {
return CBString(c) + b; return CBString(c) + b;
} }
const CBString operator + (unsigned char c, const CBString& b) { const CBString operator+(unsigned char c, const CBString& b) {
return CBString(c) + b; return CBString(c) + b;
} }
const CBString operator + (const tagbstring& x, const CBString& b) { const CBString operator+(const tagbstring& x, const CBString& b) {
return CBString(x) + b; return CBString(x) + b;
} }
void CBString::writeprotect () { void CBString::writeprotect() {
if (mlen >= 0) mlen = -1; if (mlen >= 0) mlen = -1;
} }
void CBString::writeallow () { void CBString::writeallow() {
if (mlen == -1) mlen = slen + (slen == 0); if (mlen == -1)
else if (mlen < 0) { mlen = slen + (slen == 0);
bstringThrow ("Cannot unprotect a constant"); else if (mlen < 0) {
} bstringThrow("Cannot unprotect a constant");
}
} }
#if defined(BSTRLIB_CAN_USE_STL) #if defined(BSTRLIB_CAN_USE_STL)
// Constructors. // Constructors.
CBString::CBString (const CBStringList& l) { CBString::CBString(const CBStringList& l) {
int c; int c;
size_t i; size_t i;
for (c=1, i=0; i < l.size(); i++) { for (c = 1, i = 0; i < l.size(); i++) {
c += l.at(i).slen; c += l.at(i).slen;
} }
mlen = c; mlen = c;
slen = 0; slen = 0;
data = (unsigned char *) bstr__alloc (c); data = (unsigned char*) bstr__alloc(c);
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in (CBStringList) constructor"); bstringThrow("Failure in (CBStringList) constructor");
} else { } else {
for (i=0; i < l.size(); i++) { for (i = 0; i < l.size(); i++) {
*this += l.at(i); *this += l.at(i);
} }
} }
} }
CBString::CBString (const struct CBStringList& l, const CBString& sep) { CBString::CBString(const struct CBStringList& l, const CBString& sep) {
int c, sl = sep.length (); int c, sl = sep.length();
size_t i; size_t i;
for (c=1, i=0; i < l.size(); i++) { for (c = 1, i = 0; i < l.size(); i++) {
c += l.at(i).slen + sl; c += l.at(i).slen + sl;
} }
mlen = c; mlen = c;
slen = 0; slen = 0;
data = (unsigned char *) bstr__alloc (mlen); data = (unsigned char*) bstr__alloc(mlen);
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in (CBStringList) constructor"); bstringThrow("Failure in (CBStringList) constructor");
} else { } else {
for (i=0; i < l.size(); i++) { for (i = 0; i < l.size(); i++) {
if (i > 0) *this += sep; if (i > 0) *this += sep;
*this += l.at(i); *this += l.at(i);
} }
} }
} }
CBString::CBString (const struct CBStringList& l, char sep) { CBString::CBString(const struct CBStringList& l, char sep) {
int c; int c;
size_t i; size_t i;
for (c=1, i=0; i < l.size(); i++) { for (c = 1, i = 0; i < l.size(); i++) {
c += l.at(i).slen + 1; c += l.at(i).slen + 1;
} }
mlen = c; mlen = c;
slen = 0; slen = 0;
data = (unsigned char *) bstr__alloc (mlen); data = (unsigned char*) bstr__alloc(mlen);
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in (CBStringList) constructor"); bstringThrow("Failure in (CBStringList) constructor");
} else { } else {
for (i=0; i < l.size(); i++) { for (i = 0; i < l.size(); i++) {
if (i > 0) *this += sep; if (i > 0) *this += sep;
*this += l.at(i); *this += l.at(i);
} }
} }
} }
CBString::CBString (const struct CBStringList& l, unsigned char sep) { CBString::CBString(const struct CBStringList& l, unsigned char sep) {
int c; int c;
size_t i; size_t i;
for (c=1, i=0; i < l.size(); i++) { for (c = 1, i = 0; i < l.size(); i++) {
c += l.at(i).slen + 1; c += l.at(i).slen + 1;
} }
mlen = c; mlen = c;
slen = 0; slen = 0;
data = (unsigned char *) bstr__alloc (mlen); data = (unsigned char*) bstr__alloc(mlen);
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in (CBStringList) constructor"); bstringThrow("Failure in (CBStringList) constructor");
} else { } else {
for (i=0; i < l.size(); i++) { for (i = 0; i < l.size(); i++) {
if (i > 0) *this += sep; if (i > 0) *this += sep;
*this += l.at(i); *this += l.at(i);
} }
} }
} }
void CBString::join (const struct CBStringList& l) { void CBString::join(const struct CBStringList& l) {
int c; int c;
size_t i; size_t i;
if (mlen <= 0) { if (mlen <= 0) {
bstringThrow ("Write protection error"); bstringThrow("Write protection error");
} }
for (c=1, i=0; i < l.size(); i++) { for (c = 1, i = 0; i < l.size(); i++) {
c += l.at(i).slen; c += l.at(i).slen;
if (c < 0) bstringThrow ("Failure in (CBStringList) constructor, too long"); if (c < 0) bstringThrow("Failure in (CBStringList) constructor, too long");
} }
alloc (c); alloc(c);
slen = 0; slen = 0;
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in (CBStringList) constructor"); bstringThrow("Failure in (CBStringList) constructor");
} else { } else {
for (i=0; i < l.size(); i++) { for (i = 0; i < l.size(); i++) {
*this += l.at(i); *this += l.at(i);
} }
} }
} }
void CBString::join (const struct CBStringList& l, const CBString& sep) { void CBString::join(const struct CBStringList& l, const CBString& sep) {
int c, sl = sep.length(); int c, sl = sep.length();
size_t i; size_t i;
if (mlen <= 0) { if (mlen <= 0) {
bstringThrow ("Write protection error"); bstringThrow("Write protection error");
} }
for (c=1, i=0; i < l.size(); i++) { for (c = 1, i = 0; i < l.size(); i++) {
c += l.at(i).slen + sl; c += l.at(i).slen + sl;
if (c < sl) bstringThrow ("Failure in (CBStringList) constructor, too long"); if (c < sl) bstringThrow("Failure in (CBStringList) constructor, too long");
} }
alloc (c); alloc(c);
slen = 0; slen = 0;
if (!data) { if (!data) {
mlen = slen = 0; mlen = slen = 0;
bstringThrow ("Failure in (CBStringList) constructor"); bstringThrow("Failure in (CBStringList) constructor");
} else { } else {
for (i=0; i < l.size(); i++) { for (i = 0; i < l.size(); i++) {
if (i > 0) *this += sep; if (i > 0) *this += sep;
*this += l.at(i); *this += l.at(i);
} }
} }
} }
void CBString::join(const struct CBStringList& l, char sep) {
void CBString::join (const struct CBStringList& l, char sep) { int c;
int c; size_t i;
size_t i;
if (mlen <= 0) {
if (mlen <= 0) { bstringThrow("Write protection error");
bstringThrow ("Write protection error"); }
}
for (c = 1, i = 0; i < l.size(); i++) {
for (c=1, i=0; i < l.size(); i++) { c += l.at(i).slen + 1;
c += l.at(i).slen + 1; if (c <= 0) bstringThrow("Failure in (CBStringList) constructor, too long");
if (c <= 0) bstringThrow ("Failure in (CBStringList) constructor, too long"); }
}
alloc(c);
alloc (c); slen = 0;
slen = 0; if (!data) {
if (!data) { mlen = slen = 0;
mlen = slen = 0; bstringThrow("Failure in (CBStringList) constructor");
bstringThrow ("Failure in (CBStringList) constructor"); } else {
} else { for (i = 0; i < l.size(); i++) {
for (i=0; i < l.size(); i++) { if (i > 0) *this += sep;
if (i > 0) *this += sep; *this += l.at(i);
*this += l.at(i); }
} }
} }
}
void CBString::join(const struct CBStringList& l, unsigned char sep) {
void CBString::join (const struct CBStringList& l, unsigned char sep) { int c;
int c; size_t i;
size_t i;
if (mlen <= 0) {
if (mlen <= 0) { bstringThrow("Write protection error");
bstringThrow ("Write protection error"); }
}
for (c = 1, i = 0; i < l.size(); i++) {
for (c=1, i=0; i < l.size(); i++) { c += l.at(i).slen + 1;
c += l.at(i).slen + 1; if (c <= 0) bstringThrow("Failure in (CBStringList) constructor, too long");
if (c <= 0) bstringThrow ("Failure in (CBStringList) constructor, too long"); }
}
alloc(c);
alloc (c); slen = 0;
slen = 0; if (!data) {
if (!data) { mlen = slen = 0;
mlen = slen = 0; bstringThrow("Failure in (CBStringList) constructor");
bstringThrow ("Failure in (CBStringList) constructor"); } else {
} else { for (i = 0; i < l.size(); i++) {
for (i=0; i < l.size(); i++) { if (i > 0) *this += sep;
if (i > 0) *this += sep; *this += l.at(i);
*this += l.at(i); }
} }
}
} }
// Split functions. // Split functions.
void CBStringList::split (const CBString& b, unsigned char splitChar) { void CBStringList::split(const CBString& b, unsigned char splitChar) {
int p, i; int p, i;
p = 0; p = 0;
do { do {
for (i = p; i < b.length (); i++) { for (i = p; i < b.length(); i++) {
if (b.character (i) == splitChar) break; if (b.character(i) == splitChar) break;
} }
if (i >= p) this->push_back (CBString (&(b.data[p]), i - p)); if (i >= p) this->push_back(CBString(&(b.data[p]), i - p));
p = i + 1; p = i + 1;
} while (p <= b.length ()); } while (p <= b.length());
} }
void CBStringList::split (const CBString& b, const CBString& s) { void CBStringList::split(const CBString& b, const CBString& s) {
struct { unsigned long content[(1 << CHAR_BIT) / 32]; } chrs; struct {
unsigned char c; unsigned long content[(1 << CHAR_BIT) / 32];
int p, i; } chrs;
unsigned char c;
if (s.length() == 0) bstringThrow ("Null splitstring failure"); int p, i;
if (s.length() == 1) {
this->split (b, s.character (0)); if (s.length() == 0) bstringThrow("Null splitstring failure");
} else { if (s.length() == 1) {
this->split(b, s.character(0));
for (i=0; i < ((1 << CHAR_BIT) / 32); i++) chrs.content[i] = 0x0; } else {
for (i=0; i < s.length(); i++) { for (i = 0; i < ((1 << CHAR_BIT) / 32); i++) chrs.content[i] = 0x0;
c = s.character (i); for (i = 0; i < s.length(); i++) {
chrs.content[c >> 5] |= ((long)1) << (c & 31); c = s.character(i);
} chrs.content[c >> 5] |= ((long) 1) << (c & 31);
}
p = 0;
do { p = 0;
for (i = p; i < b.length (); i++) { do {
c = b.character (i); for (i = p; i < b.length(); i++) {
if (chrs.content[c >> 5] & ((long)1) << (c & 31)) break; c = b.character(i);
} if (chrs.content[c >> 5] & ((long) 1) << (c & 31)) break;
if (i >= p) this->push_back (CBString (&(b.data[p]), i - p)); }
p = i + 1; if (i >= p) this->push_back(CBString(&(b.data[p]), i - p));
} while (p <= b.length ()); p = i + 1;
} } while (p <= b.length());
} }
}
void CBStringList::splitstr (const CBString& b, const CBString& s) {
int p, i; void CBStringList::splitstr(const CBString& b, const CBString& s) {
int p, i;
if (s.length() == 1) {
this->split (b, s.character (0)); if (s.length() == 1) {
} else if (s.length() == 0) { this->split(b, s.character(0));
for (i=0; i < b.length (); i++) { } else if (s.length() == 0) {
this->push_back (CBString (b.data[i])); for (i = 0; i < b.length(); i++) {
} this->push_back(CBString(b.data[i]));
} else { }
for (p=0; (i = b.find (s, p)) >= 0; p = i + s.length ()) { } else {
this->push_back (b.midstr (p, i - p)); for (p = 0; (i = b.find(s, p)) >= 0; p = i + s.length()) {
} this->push_back(b.midstr(p, i - p));
if (p <= b.length ()) { }
this->push_back (b.midstr (p, b.length () - p)); if (p <= b.length()) {
} this->push_back(b.midstr(p, b.length() - p));
} }
} }
}
static int streamSplitCb (void * parm, int ofs, const_bstring entry) {
CBStringList * r = (CBStringList *) parm; static int streamSplitCb(void* parm, int ofs, const_bstring entry) {
CBStringList* r = (CBStringList*) parm;
ofs = ofs;
r->push_back (CBString (*entry)); ofs = ofs;
return 0; r->push_back(CBString(*entry));
} return 0;
}
void CBStringList::split (const CBStream& b, const CBString& s) {
if (0 > bssplitscb (b.m_s, (bstring) &s, streamSplitCb, void CBStringList::split(const CBStream& b, const CBString& s) {
(void *) this)) { if (0 > bssplitscb(b.m_s, (bstring) &s, streamSplitCb, (void*) this)) {
bstringThrow ("Split bstream failure"); bstringThrow("Split bstream failure");
} }
} }
void CBStringList::split (const CBStream& b, unsigned char splitChar) { void CBStringList::split(const CBStream& b, unsigned char splitChar) {
CBString sc (splitChar); CBString sc(splitChar);
if (0 > bssplitscb (b.m_s, (bstring) &sc, if (0 > bssplitscb(b.m_s, (bstring) &sc, streamSplitCb, (void*) this)) {
streamSplitCb, (void *) this)) { bstringThrow("Split bstream failure");
bstringThrow ("Split bstream failure"); }
} }
}
void CBStringList::splitstr(const CBStream& b, const CBString& s) {
void CBStringList::splitstr (const CBStream& b, const CBString& s) { if (0 > bssplitstrcb(b.m_s, (bstring) &s, streamSplitCb, (void*) this)) {
if (0 > bssplitstrcb (b.m_s, (bstring) &s, streamSplitCb, bstringThrow("Split bstream failure");
(void *) this)) { }
bstringThrow ("Split bstream failure");
}
} }
#endif #endif
#if defined(BSTRLIB_CAN_USE_IOSTREAM) #if defined(BSTRLIB_CAN_USE_IOSTREAM)
std::ostream& operator << (std::ostream& sout, CBString b) { std::ostream& operator<<(std::ostream& sout, CBString b) {
return sout.write ((const char *)b, b.length()); return sout.write((const char*) b, b.length());
} }
#include <ctype.h> #include <ctype.h>
static int istreamGets (void * parm) { static int istreamGets(void* parm) {
char c = '\n'; char c = '\n';
((std::istream *)parm)->get(c); ((std::istream*) parm)->get(c);
if (isspace (c)) c = '\n'; if (isspace(c)) c = '\n';
return c; return c;
} }
std::istream& operator >> (std::istream& sin, CBString& b) { std::istream& operator>>(std::istream& sin, CBString& b) {
do { do {
b.gets ((bNgetc) istreamGets, &sin, '\n'); b.gets((bNgetc) istreamGets, &sin, '\n');
if (b.slen > 0 && b.data[b.slen-1] == '\n') b.slen--; if (b.slen > 0 && b.data[b.slen - 1] == '\n') b.slen--;
} while (b.slen == 0 && !sin.eof ()); } while (b.slen == 0 && !sin.eof());
return sin; return sin;
} }
struct sgetc { struct sgetc {
std::istream * sin; std::istream* sin;
char terminator; char terminator;
}; };
static int istreamGetc (void * parm) { static int istreamGetc(void* parm) {
char c = ((struct sgetc *)parm)->terminator; char c = ((struct sgetc*) parm)->terminator;
((struct sgetc *)parm)->sin->get(c); ((struct sgetc*) parm)->sin->get(c);
return c; return c;
} }
std::istream& getline (std::istream& sin, CBString& b, char terminator) { std::istream& getline(std::istream& sin, CBString& b, char terminator) {
struct sgetc parm; struct sgetc parm;
parm.sin = &sin; parm.sin = &sin;
parm.terminator = terminator; parm.terminator = terminator;
b.gets ((bNgetc) istreamGetc, &parm, terminator); b.gets((bNgetc) istreamGetc, &parm, terminator);
if (b.slen > 0 && b.data[b.slen-1] == terminator) b.slen--; if (b.slen > 0 && b.data[b.slen - 1] == terminator) b.slen--;
return sin; return sin;
} }
#endif #endif
CBStream::CBStream (bNread readPtr, void * parm) { CBStream::CBStream(bNread readPtr, void* parm) {
m_s = bsopen (readPtr, parm); m_s = bsopen(readPtr, parm);
} }
CBStream::~CBStream () { CBStream::~CBStream() {
bsclose (m_s); bsclose(m_s);
} }
int CBStream::buffLengthSet (int sz) { int CBStream::buffLengthSet(int sz) {
if (sz <= 0) { if (sz <= 0) {
bstringThrow ("buffLengthSet parameter failure"); bstringThrow("buffLengthSet parameter failure");
} }
return bsbufflength (m_s, sz); return bsbufflength(m_s, sz);
} }
int CBStream::buffLengthGet () { int CBStream::buffLengthGet() {
return bsbufflength (m_s, 0); return bsbufflength(m_s, 0);
} }
CBString CBStream::readLine (char terminator) { CBString CBStream::readLine(char terminator) {
CBString ret(""); CBString ret("");
if (0 > bsreadln ((bstring) &ret, m_s, terminator) && eof () < 0) { if (0 > bsreadln((bstring) &ret, m_s, terminator) && eof() < 0) {
bstringThrow ("Failed readLine"); bstringThrow("Failed readLine");
} }
return ret; return ret;
} }
CBString CBStream::readLine (const CBString& terminator) { CBString CBStream::readLine(const CBString& terminator) {
CBString ret(""); CBString ret("");
if (0 > bsreadlns ((bstring) &ret, m_s, (bstring) &terminator) && eof () < 0) { if (0 > bsreadlns((bstring) &ret, m_s, (bstring) &terminator) && eof() < 0) {
bstringThrow ("Failed readLine"); bstringThrow("Failed readLine");
} }
return ret; return ret;
} }
void CBStream::readLine (CBString& s, char terminator) { void CBStream::readLine(CBString& s, char terminator) {
if (0 > bsreadln ((bstring) &s, m_s, terminator) && eof () < 0) { if (0 > bsreadln((bstring) &s, m_s, terminator) && eof() < 0) {
bstringThrow ("Failed readLine"); bstringThrow("Failed readLine");
} }
} }
void CBStream::readLine (CBString& s, const CBString& terminator) { void CBStream::readLine(CBString& s, const CBString& terminator) {
if (0 > bsreadlns ((bstring) &s, m_s, (bstring) &terminator) && eof () < 0) { if (0 > bsreadlns((bstring) &s, m_s, (bstring) &terminator) && eof() < 0) {
bstringThrow ("Failed readLine"); bstringThrow("Failed readLine");
} }
} }
void CBStream::readLineAppend (CBString& s, char terminator) { void CBStream::readLineAppend(CBString& s, char terminator) {
if (0 > bsreadlna ((bstring) &s, m_s, terminator) && eof () < 0) { if (0 > bsreadlna((bstring) &s, m_s, terminator) && eof() < 0) {
bstringThrow ("Failed readLineAppend"); bstringThrow("Failed readLineAppend");
} }
} }
void CBStream::readLineAppend (CBString& s, const CBString& terminator) { void CBStream::readLineAppend(CBString& s, const CBString& terminator) {
if (0 > bsreadlnsa ((bstring) &s, m_s, (bstring) &terminator) && eof () < 0) { if (0 > bsreadlnsa((bstring) &s, m_s, (bstring) &terminator) && eof() < 0) {
bstringThrow ("Failed readLineAppend"); bstringThrow("Failed readLineAppend");
} }
} }
#define BS_BUFF_SZ (1024) #define BS_BUFF_SZ (1024)
CBString CBStream::read () { CBString CBStream::read() {
CBString ret(""); CBString ret("");
while (!bseof (m_s)) { while (!bseof(m_s)) {
if (0 > bsreada ((bstring) &ret, m_s, BS_BUFF_SZ) && eof () < 0) { if (0 > bsreada((bstring) &ret, m_s, BS_BUFF_SZ) && eof() < 0) {
bstringThrow ("Failed read"); bstringThrow("Failed read");
} }
} }
return ret; return ret;
} }
CBString& CBStream::operator >> (CBString& s) { CBString& CBStream::operator>>(CBString& s) {
while (!bseof (m_s)) { while (!bseof(m_s)) {
if (0 > bsreada ((bstring) &s, m_s, BS_BUFF_SZ) && eof () < 0) { if (0 > bsreada((bstring) &s, m_s, BS_BUFF_SZ) && eof() < 0) {
bstringThrow ("Failed read"); bstringThrow("Failed read");
} }
} }
return s; return s;
} }
CBString CBStream::read (int n) { CBString CBStream::read(int n) {
CBString ret(""); CBString ret("");
if (0 > bsread ((bstring) &ret, m_s, n) && eof () < 0) { if (0 > bsread((bstring) &ret, m_s, n) && eof() < 0) {
bstringThrow ("Failed read"); bstringThrow("Failed read");
} }
return ret; return ret;
} }
void CBStream::read (CBString& s) { void CBStream::read(CBString& s) {
s.slen = 0; s.slen = 0;
while (!bseof (m_s)) { while (!bseof(m_s)) {
if (0 > bsreada ((bstring) &s, m_s, BS_BUFF_SZ)) { if (0 > bsreada((bstring) &s, m_s, BS_BUFF_SZ)) {
bstringThrow ("Failed read"); bstringThrow("Failed read");
} }
} }
} }
void CBStream::read (CBString& s, int n) { void CBStream::read(CBString& s, int n) {
if (0 > bsread ((bstring) &s, m_s, n)) { if (0 > bsread((bstring) &s, m_s, n)) {
bstringThrow ("Failed read"); bstringThrow("Failed read");
} }
} }
void CBStream::readAppend (CBString& s) { void CBStream::readAppend(CBString& s) {
while (!bseof (m_s)) { while (!bseof(m_s)) {
if (0 > bsreada ((bstring) &s, m_s, BS_BUFF_SZ)) { if (0 > bsreada((bstring) &s, m_s, BS_BUFF_SZ)) {
bstringThrow ("Failed readAppend"); bstringThrow("Failed readAppend");
} }
} }
} }
void CBStream::readAppend (CBString& s, int n) { void CBStream::readAppend(CBString& s, int n) {
if (0 > bsreada ((bstring) &s, m_s, n)) { if (0 > bsreada((bstring) &s, m_s, n)) {
bstringThrow ("Failed readAppend"); bstringThrow("Failed readAppend");
} }
} }
void CBStream::unread (const CBString& s) { void CBStream::unread(const CBString& s) {
if (0 > bsunread (m_s, (bstring) &s)) { if (0 > bsunread(m_s, (bstring) &s)) {
bstringThrow ("Failed unread"); bstringThrow("Failed unread");
} }
} }
CBString CBStream::peek () const { CBString CBStream::peek() const {
CBString ret (""); CBString ret("");
if (0 > bspeek ((bstring) &ret, m_s)) { if (0 > bspeek((bstring) &ret, m_s)) {
bstringThrow ("Failed peek"); bstringThrow("Failed peek");
} }
return ret; return ret;
} }
void CBStream::peek (CBString& s) const { void CBStream::peek(CBString& s) const {
s.slen = 0; s.slen = 0;
if (0 > bspeek ((bstring) &s, m_s)) { if (0 > bspeek((bstring) &s, m_s)) {
bstringThrow ("Failed peek"); bstringThrow("Failed peek");
} }
} }
void CBStream::peekAppend (CBString& s) const { void CBStream::peekAppend(CBString& s) const {
if (0 > bspeek ((bstring) &s, m_s)) { if (0 > bspeek((bstring) &s, m_s)) {
bstringThrow ("Failed peekAppend"); bstringThrow("Failed peekAppend");
} }
} }
int CBStream::eof () const { int CBStream::eof() const {
int ret = bseof (m_s); int ret = bseof(m_s);
if (0 > ret) { if (0 > ret) {
bstringThrow ("Failed eof"); bstringThrow("Failed eof");
} }
return ret; return ret;
} }
} // namespace Bstrlib } // namespace Bstrlib
...@@ -20,30 +20,31 @@ ...@@ -20,30 +20,31 @@
// ported over STLport, then you can #define BSTRLIB_CAN_USE_STL to use // ported over STLport, then you can #define BSTRLIB_CAN_USE_STL to use
// the CBStringList class. // the CBStringList class.
#if defined(__WATCOMC__) #if defined(__WATCOMC__)
# if !defined (BSTRLIB_CAN_USE_STL) && !defined (BSTRLIB_CANNOT_USE_STL) #if !defined(BSTRLIB_CAN_USE_STL) && !defined(BSTRLIB_CANNOT_USE_STL)
# define BSTRLIB_CANNOT_USE_STL #define BSTRLIB_CANNOT_USE_STL
# endif #endif
# if !defined (BSTRLIB_CAN_USE_IOSTREAM) && !defined (BSTRLIB_CANNOT_USE_IOSTREAM) #if !defined(BSTRLIB_CAN_USE_IOSTREAM) && !defined(BSTRLIB_CANNOT_USE_IOSTREAM)
# define BSTRLIB_CANNOT_USE_IOSTREAM #define BSTRLIB_CANNOT_USE_IOSTREAM
# endif #endif
#endif #endif
// By default it assumed that STL has been installed and works for your // By default it assumed that STL has been installed and works for your
// compiler. If this is not the case, then #define BSTRLIB_CANNOT_USE_STL // compiler. If this is not the case, then #define BSTRLIB_CANNOT_USE_STL
#if !defined (BSTRLIB_CANNOT_USE_STL) && !defined (BSTRLIB_CAN_USE_STL) #if !defined(BSTRLIB_CANNOT_USE_STL) && !defined(BSTRLIB_CAN_USE_STL)
#define BSTRLIB_CAN_USE_STL #define BSTRLIB_CAN_USE_STL
#endif #endif
// By default it assumed that std::iostream works well with your compiler. // By default it assumed that std::iostream works well with your compiler.
// If this is not the case, then #define BSTRLIB_CAN_USE_IOSTREAM // If this is not the case, then #define BSTRLIB_CAN_USE_IOSTREAM
#if !defined (BSTRLIB_CANNOT_USE_IOSTREAM) && !defined (BSTRLIB_CAN_USE_IOSTREAM) #if !defined(BSTRLIB_CANNOT_USE_IOSTREAM) && !defined(BSTRLIB_CAN_USE_IOSTREAM)
#define BSTRLIB_CAN_USE_IOSTREAM #define BSTRLIB_CAN_USE_IOSTREAM
#endif #endif
// By default it is assumed that your compiler can deal with and has enabled // By default it is assumed that your compiler can deal with and has enabled
// exception handlling. If this is not the case then you will need to // exception handlling. If this is not the case then you will need to
// #define BSTRLIB_DOESNT_THROW_EXCEPTIONS // #define BSTRLIB_DOESNT_THROW_EXCEPTIONS
#if !defined (BSTRLIB_THROWS_EXCEPTIONS) && !defined (BSTRLIB_DOESNT_THROW_EXCEPTIONS) #if !defined(BSTRLIB_THROWS_EXCEPTIONS) && \
!defined(BSTRLIB_DOESNT_THROW_EXCEPTIONS)
#define BSTRLIB_THROWS_EXCEPTIONS #define BSTRLIB_THROWS_EXCEPTIONS
#endif #endif
...@@ -79,357 +80,369 @@ namespace Bstrlib { ...@@ -79,357 +80,369 @@ namespace Bstrlib {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
#if defined(BSTRLIB_CAN_USE_STL) #if defined(BSTRLIB_CAN_USE_STL)
struct CBStringException : public std::exception { struct CBStringException : public std::exception {
private: private:
std::string msg; std::string msg;
public:
CBStringException (const std::string inmsg) : msg(inmsg) {} public:
virtual ~CBStringException () throw () {} CBStringException(const std::string inmsg) : msg(inmsg) {}
virtual const char *what () const throw () { return msg.c_str(); } virtual ~CBStringException() throw() {}
virtual const char* what() const throw() { return msg.c_str(); }
}; };
#else #else
struct CBStringException { struct CBStringException {
private: private:
char * msg; char* msg;
int needToFree; int needToFree;
public:
CBStringException (const char * inmsg) : needToFree(0) { public:
if (inmsg) { CBStringException(const char* inmsg) : needToFree(0) {
msg = (char *) malloc (1 + strlen (inmsg)); if (inmsg) {
if (NULL == msg) msg = "Out of memory"; msg = (char*) malloc(1 + strlen(inmsg));
else { if (NULL == msg)
strcpy (msg, inmsg); msg = "Out of memory";
needToFree = 1; else {
} strcpy(msg, inmsg);
} else { needToFree = 1;
msg = "NULL exception message"; }
} } else {
} msg = "NULL exception message";
virtual ~CBStringException () throw () { }
if (needToFree) { }
free (msg); virtual ~CBStringException() throw() {
needToFree = 0; if (needToFree) {
msg = NULL; free(msg);
} needToFree = 0;
} msg = NULL;
virtual const char *what () const throw () { return msg; } }
}
virtual const char* what() const throw() { return msg; }
}; };
#endif #endif
#define bstringThrow(er) {\ #define bstringThrow(er) \
CBStringException bstr__cppwrapper_exception ("CBString::" er "");\ { \
throw bstr__cppwrapper_exception;\ CBStringException bstr__cppwrapper_exception("CBString::" er ""); \
} throw bstr__cppwrapper_exception; \
}
#else #else
#define bstringThrow(er) {} #define bstringThrow(er) \
{}
#endif #endif
struct CBString; struct CBString;
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable:4512) #pragma warning(disable : 4512)
#endif #endif
class CBCharWriteProtected { class CBCharWriteProtected {
friend struct CBString; friend struct CBString;
private:
const struct tagbstring& s; private:
unsigned int idx; const struct tagbstring& s;
CBCharWriteProtected (const struct tagbstring& c, int i) : s(c), idx((unsigned int)i) { unsigned int idx;
if (idx >= (unsigned) s.slen) { CBCharWriteProtected(const struct tagbstring& c, int i)
bstringThrow ("character index out of bounds"); : s(c), idx((unsigned int) i) {
} if (idx >= (unsigned) s.slen) {
} bstringThrow("character index out of bounds");
}
public: }
inline char operator = (char c) { public:
if (s.mlen <= 0) { inline char operator=(char c) {
bstringThrow ("Write protection error"); if (s.mlen <= 0) {
} else { bstringThrow("Write protection error");
} else {
#ifndef BSTRLIB_THROWS_EXCEPTIONS #ifndef BSTRLIB_THROWS_EXCEPTIONS
if (idx >= (unsigned) s.slen) return '\0'; if (idx >= (unsigned) s.slen) return '\0';
#endif #endif
s.data[idx] = (unsigned char) c; s.data[idx] = (unsigned char) c;
} }
return (char) s.data[idx]; return (char) s.data[idx];
} }
inline unsigned char operator = (unsigned char c) { inline unsigned char operator=(unsigned char c) {
if (s.mlen <= 0) { if (s.mlen <= 0) {
bstringThrow ("Write protection error"); bstringThrow("Write protection error");
} else { } else {
#ifndef BSTRLIB_THROWS_EXCEPTIONS #ifndef BSTRLIB_THROWS_EXCEPTIONS
if (idx >= (unsigned) s.slen) return '\0'; if (idx >= (unsigned) s.slen) return '\0';
#endif #endif
s.data[idx] = c; s.data[idx] = c;
} }
return s.data[idx]; return s.data[idx];
} }
inline operator unsigned char () const { inline operator unsigned char() const {
#ifndef BSTRLIB_THROWS_EXCEPTIONS #ifndef BSTRLIB_THROWS_EXCEPTIONS
if (idx >= (unsigned) s.slen) return (unsigned char) '\0'; if (idx >= (unsigned) s.slen) return (unsigned char) '\0';
#endif #endif
return s.data[idx]; return s.data[idx];
} }
}; };
struct CBString : public tagbstring { struct CBString : public tagbstring {
// Constructors
// Constructors CBString();
CBString (); CBString(char c);
CBString (char c); CBString(unsigned char c);
CBString (unsigned char c); CBString(const char* s);
CBString (const char *s); CBString(int len, const char* s);
CBString (int len, const char *s); CBString(const CBString& b);
CBString (const CBString& b); CBString(const tagbstring& x);
CBString (const tagbstring& x); CBString(char c, int len);
CBString (char c, int len); CBString(const void* blk, int len);
CBString (const void * blk, int len);
#if defined(BSTRLIB_CAN_USE_STL) #if defined(BSTRLIB_CAN_USE_STL)
CBString (const struct CBStringList& l); CBString(const struct CBStringList& l);
CBString (const struct CBStringList& l, const CBString& sep); CBString(const struct CBStringList& l, const CBString& sep);
CBString (const struct CBStringList& l, char sep); CBString(const struct CBStringList& l, char sep);
CBString (const struct CBStringList& l, unsigned char sep); CBString(const struct CBStringList& l, unsigned char sep);
#endif #endif
// Destructor // Destructor
#if !defined(BSTRLIB_DONT_USE_VIRTUAL_DESTRUCTOR) #if !defined(BSTRLIB_DONT_USE_VIRTUAL_DESTRUCTOR)
virtual virtual
#endif #endif
~CBString (); ~CBString();
// = operator // = operator
const CBString& operator = (char c); const CBString& operator=(char c);
const CBString& operator = (unsigned char c); const CBString& operator=(unsigned char c);
const CBString& operator = (const char *s); const CBString& operator=(const char* s);
const CBString& operator = (const CBString& b); const CBString& operator=(const CBString& b);
const CBString& operator = (const tagbstring& x); const CBString& operator=(const tagbstring& x);
// += operator // += operator
const CBString& operator += (char c); const CBString& operator+=(char c);
const CBString& operator += (unsigned char c); const CBString& operator+=(unsigned char c);
const CBString& operator += (const char *s); const CBString& operator+=(const char* s);
const CBString& operator += (const CBString& b); const CBString& operator+=(const CBString& b);
const CBString& operator += (const tagbstring& x); const CBString& operator+=(const tagbstring& x);
// *= operator // *= operator
inline const CBString& operator *= (int count) { inline const CBString& operator*=(int count) {
this->repeat (count); this->repeat(count);
return *this; return *this;
} }
// + operator // + operator
const CBString operator + (char c) const; const CBString operator+(char c) const;
const CBString operator + (unsigned char c) const; const CBString operator+(unsigned char c) const;
const CBString operator + (const unsigned char *s) const; const CBString operator+(const unsigned char* s) const;
const CBString operator + (const char *s) const; const CBString operator+(const char* s) const;
const CBString operator + (const CBString& b) const; const CBString operator+(const CBString& b) const;
const CBString operator + (const tagbstring& x) const; const CBString operator+(const tagbstring& x) const;
// * operator // * operator
inline const CBString operator * (int count) const { inline const CBString operator*(int count) const {
CBString retval (*this); CBString retval(*this);
retval.repeat (count); retval.repeat(count);
return retval; return retval;
} }
// Comparison operators // Comparison operators
bool operator == (const CBString& b) const; bool operator==(const CBString& b) const;
bool operator == (const char * s) const; bool operator==(const char* s) const;
bool operator == (const unsigned char * s) const; bool operator==(const unsigned char* s) const;
bool operator != (const CBString& b) const; bool operator!=(const CBString& b) const;
bool operator != (const char * s) const; bool operator!=(const char* s) const;
bool operator != (const unsigned char * s) const; bool operator!=(const unsigned char* s) const;
bool operator < (const CBString& b) const; bool operator<(const CBString& b) const;
bool operator < (const char * s) const; bool operator<(const char* s) const;
bool operator < (const unsigned char * s) const; bool operator<(const unsigned char* s) const;
bool operator <= (const CBString& b) const; bool operator<=(const CBString& b) const;
bool operator <= (const char * s) const; bool operator<=(const char* s) const;
bool operator <= (const unsigned char * s) const; bool operator<=(const unsigned char* s) const;
bool operator > (const CBString& b) const; bool operator>(const CBString& b) const;
bool operator > (const char * s) const; bool operator>(const char* s) const;
bool operator > (const unsigned char * s) const; bool operator>(const unsigned char* s) const;
bool operator >= (const CBString& b) const; bool operator>=(const CBString& b) const;
bool operator >= (const char * s) const; bool operator>=(const char* s) const;
bool operator >= (const unsigned char * s) const; bool operator>=(const unsigned char* s) const;
// Casts // Casts
inline operator const char* () const { return (const char *)data; } inline operator const char*() const { return (const char*) data; }
inline operator const unsigned char* () const { return (const unsigned char *)data; } inline operator const unsigned char*() const {
operator double () const; return (const unsigned char*) data;
operator float () const; }
operator int () const; operator double() const;
operator unsigned int () const; operator float() const;
operator int() const;
// Accessors operator unsigned int() const;
inline int length () const {return slen;}
// Accessors
inline unsigned char character (int i) const { inline int length() const { return slen; }
if (((unsigned) i) >= (unsigned) slen) {
inline unsigned char character(int i) const {
if (((unsigned) i) >= (unsigned) slen) {
#ifdef BSTRLIB_THROWS_EXCEPTIONS #ifdef BSTRLIB_THROWS_EXCEPTIONS
bstringThrow ("character idx out of bounds"); bstringThrow("character idx out of bounds");
#else #else
return '\0'; return '\0';
#endif #endif
} }
return data[i]; return data[i];
} }
inline unsigned char operator [] (int i) const { return character(i); } inline unsigned char operator[](int i) const { return character(i); }
inline CBCharWriteProtected character (int i) { inline CBCharWriteProtected character(int i) {
return CBCharWriteProtected (*this, i); return CBCharWriteProtected(*this, i);
} }
inline CBCharWriteProtected operator [] (int i) { return character(i); } inline CBCharWriteProtected operator[](int i) { return character(i); }
// Space allocation hint method. // Space allocation hint method.
void alloc (int length); void alloc(int length);
// Search methods. // Search methods.
int caselessEqual (const CBString& b) const; int caselessEqual(const CBString& b) const;
int caselessCmp (const CBString& b) const; int caselessCmp(const CBString& b) const;
int find (const CBString& b, int pos = 0) const; int find(const CBString& b, int pos = 0) const;
int find (const char * b, int pos = 0) const; int find(const char* b, int pos = 0) const;
int caselessfind (const CBString& b, int pos = 0) const; int caselessfind(const CBString& b, int pos = 0) const;
int caselessfind (const char * b, int pos = 0) const; int caselessfind(const char* b, int pos = 0) const;
int find (char c, int pos = 0) const; int find(char c, int pos = 0) const;
int reversefind (const CBString& b, int pos) const; int reversefind(const CBString& b, int pos) const;
int reversefind (const char * b, int pos) const; int reversefind(const char* b, int pos) const;
int caselessreversefind (const CBString& b, int pos) const; int caselessreversefind(const CBString& b, int pos) const;
int caselessreversefind (const char * b, int pos) const; int caselessreversefind(const char* b, int pos) const;
int reversefind (char c, int pos) const; int reversefind(char c, int pos) const;
int findchr (const CBString& b, int pos = 0) const; int findchr(const CBString& b, int pos = 0) const;
int findchr (const char * s, int pos = 0) const; int findchr(const char* s, int pos = 0) const;
int reversefindchr (const CBString& b, int pos) const; int reversefindchr(const CBString& b, int pos) const;
int reversefindchr (const char * s, int pos) const; int reversefindchr(const char* s, int pos) const;
int nfindchr (const CBString& b, int pos = 0) const; int nfindchr(const CBString& b, int pos = 0) const;
int nfindchr (const char * b, int pos = 0) const; int nfindchr(const char* b, int pos = 0) const;
int nreversefindchr (const CBString& b, int pos) const; int nreversefindchr(const CBString& b, int pos) const;
int nreversefindchr (const char * b, int pos) const; int nreversefindchr(const char* b, int pos) const;
// Search and substitute methods. // Search and substitute methods.
void findreplace (const CBString& find, const CBString& repl, int pos = 0); void findreplace(const CBString& find, const CBString& repl, int pos = 0);
void findreplace (const CBString& find, const char * repl, int pos = 0); void findreplace(const CBString& find, const char* repl, int pos = 0);
void findreplace (const char * find, const CBString& repl, int pos = 0); void findreplace(const char* find, const CBString& repl, int pos = 0);
void findreplace (const char * find, const char * repl, int pos = 0); void findreplace(const char* find, const char* repl, int pos = 0);
void findreplacecaseless (const CBString& find, const CBString& repl, int pos = 0); void findreplacecaseless(
void findreplacecaseless (const CBString& find, const char * repl, int pos = 0); const CBString& find, const CBString& repl, int pos = 0);
void findreplacecaseless (const char * find, const CBString& repl, int pos = 0); void findreplacecaseless(const CBString& find, const char* repl, int pos = 0);
void findreplacecaseless (const char * find, const char * repl, int pos = 0); void findreplacecaseless(const char* find, const CBString& repl, int pos = 0);
void findreplacecaseless(const char* find, const char* repl, int pos = 0);
// Extraction method.
const CBString midstr (int left, int len) const; // Extraction method.
const CBString midstr(int left, int len) const;
// Standard manipulation methods.
void setsubstr (int pos, const CBString& b, unsigned char fill = ' '); // Standard manipulation methods.
void setsubstr (int pos, const char * b, unsigned char fill = ' '); void setsubstr(int pos, const CBString& b, unsigned char fill = ' ');
void insert (int pos, const CBString& b, unsigned char fill = ' '); void setsubstr(int pos, const char* b, unsigned char fill = ' ');
void insert (int pos, const char * b, unsigned char fill = ' '); void insert(int pos, const CBString& b, unsigned char fill = ' ');
void insertchrs (int pos, int len, unsigned char fill = ' '); void insert(int pos, const char* b, unsigned char fill = ' ');
void replace (int pos, int len, const CBString& b, unsigned char fill = ' '); void insertchrs(int pos, int len, unsigned char fill = ' ');
void replace (int pos, int len, const char * s, unsigned char fill = ' '); void replace(int pos, int len, const CBString& b, unsigned char fill = ' ');
void remove (int pos, int len); void replace(int pos, int len, const char* s, unsigned char fill = ' ');
void trunc (int len); void remove(int pos, int len);
void trunc(int len);
// Miscellaneous methods.
void format (const char * fmt, ...); // Miscellaneous methods.
void formata (const char * fmt, ...); void format(const char* fmt, ...);
void fill (int length, unsigned char fill = ' '); void formata(const char* fmt, ...);
void repeat (int count); void fill(int length, unsigned char fill = ' ');
void ltrim (const CBString& b = CBString (bsStaticBlkParms (" \t\v\f\r\n"))); void repeat(int count);
void rtrim (const CBString& b = CBString (bsStaticBlkParms (" \t\v\f\r\n"))); void ltrim(const CBString& b = CBString(bsStaticBlkParms(" \t\v\f\r\n")));
inline void trim (const CBString& b = CBString (bsStaticBlkParms (" \t\v\f\r\n"))) { void rtrim(const CBString& b = CBString(bsStaticBlkParms(" \t\v\f\r\n")));
rtrim (b); inline void trim(
ltrim (b); const CBString& b = CBString(bsStaticBlkParms(" \t\v\f\r\n"))) {
} rtrim(b);
void toupper (); ltrim(b);
void tolower (); }
void toupper();
// Write protection methods. void tolower();
void writeprotect ();
void writeallow (); // Write protection methods.
inline bool iswriteprotected () const { return mlen <= 0; } void writeprotect();
void writeallow();
// Join methods. inline bool iswriteprotected() const { return mlen <= 0; }
// Join methods.
#if defined(BSTRLIB_CAN_USE_STL) #if defined(BSTRLIB_CAN_USE_STL)
void join (const struct CBStringList& l); void join(const struct CBStringList& l);
void join (const struct CBStringList& l, const CBString& sep); void join(const struct CBStringList& l, const CBString& sep);
void join (const struct CBStringList& l, char sep); void join(const struct CBStringList& l, char sep);
void join (const struct CBStringList& l, unsigned char sep); void join(const struct CBStringList& l, unsigned char sep);
#endif #endif
// CBStream methods // CBStream methods
int gets (bNgetc getcPtr, void * parm, char terminator = '\n'); int gets(bNgetc getcPtr, void* parm, char terminator = '\n');
int read (bNread readPtr, void * parm); int read(bNread readPtr, void* parm);
}; };
extern const CBString operator + (const char *a, const CBString& b); extern const CBString operator+(const char* a, const CBString& b);
extern const CBString operator + (const unsigned char *a, const CBString& b); extern const CBString operator+(const unsigned char* a, const CBString& b);
extern const CBString operator + (char c, const CBString& b); extern const CBString operator+(char c, const CBString& b);
extern const CBString operator + (unsigned char c, const CBString& b); extern const CBString operator+(unsigned char c, const CBString& b);
extern const CBString operator + (const tagbstring& x, const CBString& b); extern const CBString operator+(const tagbstring& x, const CBString& b);
inline const CBString operator * (int count, const CBString& b) { inline const CBString operator*(int count, const CBString& b) {
CBString retval (b); CBString retval(b);
retval.repeat (count); retval.repeat(count);
return retval; return retval;
} }
#if defined(BSTRLIB_CAN_USE_IOSTREAM) #if defined(BSTRLIB_CAN_USE_IOSTREAM)
extern std::ostream& operator << (std::ostream& sout, CBString b); extern std::ostream& operator<<(std::ostream& sout, CBString b);
extern std::istream& operator >> (std::istream& sin, CBString& b); extern std::istream& operator>>(std::istream& sin, CBString& b);
extern std::istream& getline (std::istream& sin, CBString& b, char terminator='\n'); extern std::istream& getline(
std::istream& sin, CBString& b, char terminator = '\n');
#endif #endif
struct CBStream { struct CBStream {
friend struct CBStringList; friend struct CBStringList;
private:
struct bStream * m_s; private:
public: struct bStream* m_s;
CBStream (bNread readPtr, void * parm);
~CBStream (); public:
int buffLengthSet (int sz); CBStream(bNread readPtr, void* parm);
int buffLengthGet (); ~CBStream();
int eof () const; int buffLengthSet(int sz);
int buffLengthGet();
CBString readLine (char terminator); int eof() const;
CBString readLine (const CBString& terminator);
void readLine (CBString& s, char terminator); CBString readLine(char terminator);
void readLine (CBString& s, const CBString& terminator); CBString readLine(const CBString& terminator);
void readLineAppend (CBString& s, char terminator); void readLine(CBString& s, char terminator);
void readLineAppend (CBString& s, const CBString& terminator); void readLine(CBString& s, const CBString& terminator);
void readLineAppend(CBString& s, char terminator);
CBString read (); void readLineAppend(CBString& s, const CBString& terminator);
CBString& operator >> (CBString& s);
CBString read();
CBString read (int n); CBString& operator>>(CBString& s);
void read (CBString& s);
void read (CBString& s, int n); CBString read(int n);
void readAppend (CBString& s); void read(CBString& s);
void readAppend (CBString& s, int n); void read(CBString& s, int n);
void readAppend(CBString& s);
void unread (const CBString& s); void readAppend(CBString& s, int n);
inline CBStream& operator << (const CBString& s) {
this->unread (s); void unread(const CBString& s);
return *this; inline CBStream& operator<<(const CBString& s) {
} this->unread(s);
return *this;
CBString peek () const; }
void peek (CBString& s) const;
void peekAppend (CBString& s) const; CBString peek() const;
void peek(CBString& s) const;
void peekAppend(CBString& s) const;
}; };
#if defined(BSTRLIB_CAN_USE_STL) #if defined(BSTRLIB_CAN_USE_STL)
struct CBStringList : public std::vector<CBString> { struct CBStringList : public std::vector<CBString> {
// split a string into a vector of strings. // split a string into a vector of strings.
void split (const CBString& b, unsigned char splitChar); void split(const CBString& b, unsigned char splitChar);
void split (const CBString& b, const CBString& s); void split(const CBString& b, const CBString& s);
void splitstr (const CBString& b, const CBString& s); void splitstr(const CBString& b, const CBString& s);
void split (const CBStream& b, unsigned char splitChar); void split(const CBStream& b, unsigned char splitChar);
void split (const CBStream& b, const CBString& s); void split(const CBStream& b, const CBString& s);
void splitstr (const CBStream& b, const CBString& s); void splitstr(const CBStream& b, const CBString& s);
}; };
#endif #endif
} // namespace Bstrlib } // namespace Bstrlib
#if !defined (BSTRLIB_DONT_ASSUME_NAMESPACE) #if !defined(BSTRLIB_DONT_ASSUME_NAMESPACE)
using namespace Bstrlib; using namespace Bstrlib;
#endif #endif
......
...@@ -23,15 +23,14 @@ ...@@ -23,15 +23,14 @@
* Scan string and return 1 if its entire contents is entirely UTF8 code * Scan string and return 1 if its entire contents is entirely UTF8 code
* points. Otherwise return 0. * points. Otherwise return 0.
*/ */
int buIsUTF8Content (const_bstring bu) { int buIsUTF8Content(const_bstring bu) {
struct utf8Iterator iter; struct utf8Iterator iter;
if (NULL == bdata (bu)) return 0; if (NULL == bdata(bu)) return 0;
for (utf8IteratorInit (&iter, bu->data, bu->slen); for (utf8IteratorInit(&iter, bu->data, bu->slen); iter.next < iter.slen;) {
iter.next < iter.slen;) { if (0 >= utf8IteratorGetNextCodePoint(&iter, -1)) return 0;
if (0 >= utf8IteratorGetNextCodePoint (&iter, -1)) return 0; }
} return 1;
return 1;
} }
/* int buGetBlkUTF16 (cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, /* int buGetBlkUTF16 (cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu,
...@@ -43,56 +42,59 @@ struct utf8Iterator iter; ...@@ -43,56 +42,59 @@ struct utf8Iterator iter;
* target array ucs2. If any code point in bu is unparsable, it will be * target array ucs2. If any code point in bu is unparsable, it will be
* translated to errCh. * translated to errCh.
*/ */
int buGetBlkUTF16 (/* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos) { int buGetBlkUTF16(
struct tagbstring t; /* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos) {
struct utf8Iterator iter; struct tagbstring t;
cpUcs4 ucs4; struct utf8Iterator iter;
int i, j; cpUcs4 ucs4;
int i, j;
if (!isLegalUnicodeCodePoint (errCh)) errCh = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER; if (!isLegalUnicodeCodePoint(errCh))
if (NULL == ucs2 || 0 >= len || NULL == bdata (bu) || 0 > pos) return BSTR_ERR; errCh = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER;
if (NULL == ucs2 || 0 >= len || NULL == bdata(bu) || 0 > pos) return BSTR_ERR;
for (j=0, i=0; j < bu->slen; j++) { for (j = 0, i = 0; j < bu->slen; j++) {
if (0x80 != (0xC0 & bu->data[j])) { if (0x80 != (0xC0 & bu->data[j])) {
if (i >= pos) break; if (i >= pos) break;
i++; i++;
} }
} }
t.mlen = -1; t.mlen = -1;
t.data = bu->data + j; t.data = bu->data + j;
t.slen = bu->slen - j; t.slen = bu->slen - j;
utf8IteratorInit (&iter, t.data, t.slen); utf8IteratorInit(&iter, t.data, t.slen);
ucs4 = BSTR_ERR; ucs4 = BSTR_ERR;
for (i=0; 0 < len && iter.next < iter.slen && for (i = 0; 0 < len && iter.next < iter.slen &&
0 <= (ucs4 = utf8IteratorGetNextCodePoint (&iter, errCh)); i++) { 0 <= (ucs4 = utf8IteratorGetNextCodePoint(&iter, errCh));
if (ucs4 < 0x10000) { i++) {
*ucs2++ = (cpUcs2) ucs4; if (ucs4 < 0x10000) {
len--; *ucs2++ = (cpUcs2) ucs4;
} else { len--;
if (len < 2) { } else {
*ucs2++ = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER; if (len < 2) {
len--; *ucs2++ = UNICODE__CODE_POINT__REPLACEMENT_CHARACTER;
} else { len--;
long y = ucs4 - 0x10000; } else {
ucs2[0] = (cpUcs2) (0xD800 | (y >> 10)); long y = ucs4 - 0x10000;
ucs2[1] = (cpUcs2) (0xDC00 | (y & 0x03FF)); ucs2[0] = (cpUcs2)(0xD800 | (y >> 10));
len -= 2; ucs2[1] = (cpUcs2)(0xDC00 | (y & 0x03FF));
ucs2 += 2; len -= 2;
i++; ucs2 += 2;
} i++;
} }
} }
while (0 < len) { }
*ucs2++ = 0; while (0 < len) {
len--; *ucs2++ = 0;
} len--;
}
utf8IteratorUninit (&iter); utf8IteratorUninit(&iter);
if (0 > ucs4) return BSTR_ERR; if (0 > ucs4) return BSTR_ERR;
return i; return i;
} }
/* /*
...@@ -118,58 +120,59 @@ UTF-32: U-000000 - U-10FFFF ...@@ -118,58 +120,59 @@ UTF-32: U-000000 - U-10FFFF
* valid code point, then this translation will halt upon the first error * valid code point, then this translation will halt upon the first error
* and return BSTR_ERR. Otherwise BSTR_OK is returned. * and return BSTR_ERR. Otherwise BSTR_OK is returned.
*/ */
int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh) { int buAppendBlkUcs4(bstring b, const cpUcs4* bu, int len, cpUcs4 errCh) {
int i, oldSlen; int i, oldSlen;
if (NULL == bu || NULL == b || 0 > len || 0 > (oldSlen = blengthe (b, -1))) return BSTR_ERR; if (NULL == bu || NULL == b || 0 > len || 0 > (oldSlen = blengthe(b, -1)))
if (!isLegalUnicodeCodePoint (errCh)) errCh = ~0; return BSTR_ERR;
if (!isLegalUnicodeCodePoint(errCh)) errCh = ~0;
for (i=0; i < len; i++) { for (i = 0; i < len; i++) {
unsigned char c[6]; unsigned char c[6];
cpUcs4 v = bu[i]; cpUcs4 v = bu[i];
if (!isLegalUnicodeCodePoint (v)) { if (!isLegalUnicodeCodePoint(v)) {
if (~0 == errCh) { if (~0 == errCh) {
b->slen = oldSlen; b->slen = oldSlen;
return BSTR_ERR; return BSTR_ERR;
} }
v = errCh; v = errCh;
} }
if (v < 0x80) { if (v < 0x80) {
if (BSTR_OK != bconchar (b, (char) v)) { if (BSTR_OK != bconchar(b, (char) v)) {
b->slen = oldSlen; b->slen = oldSlen;
return BSTR_ERR; return BSTR_ERR;
} }
} else if (v < 0x800) { } else if (v < 0x800) {
c[0] = (unsigned char) ( (v >> 6) + 0xc0); c[0] = (unsigned char) ((v >> 6) + 0xc0);
c[1] = (unsigned char) (( v & 0x3f) + 0x80); c[1] = (unsigned char) ((v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 2)) { if (BSTR_OK != bcatblk(b, c, 2)) {
b->slen = oldSlen; b->slen = oldSlen;
return BSTR_ERR; return BSTR_ERR;
} }
} else if (v < 0x10000) { } else if (v < 0x10000) {
c[0] = (unsigned char) ( (v >> 12) + 0xe0); c[0] = (unsigned char) ((v >> 12) + 0xe0);
c[1] = (unsigned char) (((v >> 6) & 0x3f) + 0x80); c[1] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[2] = (unsigned char) (( v & 0x3f) + 0x80); c[2] = (unsigned char) ((v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 3)) { if (BSTR_OK != bcatblk(b, c, 3)) {
b->slen = oldSlen; b->slen = oldSlen;
return BSTR_ERR; return BSTR_ERR;
} }
} else } else
#if 0 #if 0
if (v < 0x200000) if (v < 0x200000)
#endif #endif
{ {
c[0] = (unsigned char) ( (v >> 18) + 0xf0); c[0] = (unsigned char) ((v >> 18) + 0xf0);
c[1] = (unsigned char) (((v >> 12) & 0x3f) + 0x80); c[1] = (unsigned char) (((v >> 12) & 0x3f) + 0x80);
c[2] = (unsigned char) (((v >> 6) & 0x3f) + 0x80); c[2] = (unsigned char) (((v >> 6) & 0x3f) + 0x80);
c[3] = (unsigned char) (( v & 0x3f) + 0x80); c[3] = (unsigned char) ((v & 0x3f) + 0x80);
if (BSTR_OK != bcatblk (b, c, 4)) { if (BSTR_OK != bcatblk(b, c, 4)) {
b->slen = oldSlen; b->slen = oldSlen;
return BSTR_ERR; return BSTR_ERR;
} }
} }
#if 0 #if 0
else if (v < 0x4000000) { else if (v < 0x4000000) {
c[0] = (unsigned char) ( (v >> 24) + 0xf8); c[0] = (unsigned char) ( (v >> 24) + 0xf8);
...@@ -194,11 +197,12 @@ int i, oldSlen; ...@@ -194,11 +197,12 @@ int i, oldSlen;
} }
} }
#endif #endif
} }
return BSTR_OK; return BSTR_OK;
} }
#define endSwap(cs,mode) ((mode) ? ((((cs) & 0xFF) << 8) | (((cs) >> 8) & 0xFF)) : (cs)) #define endSwap(cs, mode) \
((mode) ? ((((cs) &0xFF) << 8) | (((cs) >> 8) & 0xFF)) : (cs))
#define TEMP_UCS4_BUFFER_SIZE (64) #define TEMP_UCS4_BUFFER_SIZE (64)
/* int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, /* int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len,
...@@ -212,63 +216,64 @@ int i, oldSlen; ...@@ -212,63 +216,64 @@ int i, oldSlen;
* set to 0, it will be filled in with the BOM as read from the first * set to 0, it will be filled in with the BOM as read from the first
* character if it is a BOM. * character if it is a BOM.
*/ */
int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh) { int buAppendBlkUTF16(
cpUcs4 buff[TEMP_UCS4_BUFFER_SIZE]; bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh) {
int cc, i, sm, oldSlen; cpUcs4 buff[TEMP_UCS4_BUFFER_SIZE];
int cc, i, sm, oldSlen;
if (NULL == bdata(bu) || NULL == utf16 || len < 0) return BSTR_ERR; if (NULL == bdata(bu) || NULL == utf16 || len < 0) return BSTR_ERR;
if (!isLegalUnicodeCodePoint (errCh)) errCh = ~0; if (!isLegalUnicodeCodePoint(errCh)) errCh = ~0;
if (len == 0) return BSTR_OK; if (len == 0) return BSTR_OK;
oldSlen = bu->slen; oldSlen = bu->slen;
i = 0; i = 0;
/* Check for BOM character and select endianess. Also remove the /* Check for BOM character and select endianess. Also remove the
BOM from the stream, since there is no need for it in a UTF-8 encoding. */ BOM from the stream, since there is no need for it in a UTF-8 encoding. */
if (bom && (cpUcs2) 0xFFFE == *bom) { if (bom && (cpUcs2) 0xFFFE == *bom) {
sm = 8; sm = 8;
} else if (bom && (cpUcs2) 0xFEFF == *bom) { } else if (bom && (cpUcs2) 0xFEFF == *bom) {
sm = 0; sm = 0;
} else if (utf16[i] == (cpUcs2) 0xFFFE) { } else if (utf16[i] == (cpUcs2) 0xFFFE) {
if (bom) *bom = utf16[i]; if (bom) *bom = utf16[i];
sm = 8; sm = 8;
i++; i++;
} else if (utf16[i] == (cpUcs2) 0xFEFF) { } else if (utf16[i] == (cpUcs2) 0xFEFF) {
if (bom) *bom = utf16[i]; if (bom) *bom = utf16[i];
sm = 0; sm = 0;
i++; i++;
} else { } else {
sm = 0; /* Assume local endianness. */ sm = 0; /* Assume local endianness. */
} }
cc = 0; cc = 0;
for (;i < len; i++) { for (; i < len; i++) {
cpUcs4 c, v; cpUcs4 c, v;
v = endSwap (utf16[i], sm); v = endSwap(utf16[i], sm);
if ((v | 0x7FF) == 0xDFFF) { /* Deal with surrogate pairs */ if ((v | 0x7FF) == 0xDFFF) { /* Deal with surrogate pairs */
if (v >= 0xDC00 || i >= len) { if (v >= 0xDC00 || i >= len) {
ErrMode:; ErrMode:;
if (~0 == errCh) { if (~0 == errCh) {
ErrReturn:; ErrReturn:;
bu->slen = oldSlen; bu->slen = oldSlen;
return BSTR_ERR; return BSTR_ERR;
} }
v = errCh; v = errCh;
} else { } else {
i++; i++;
if ((c = endSwap (utf16[i], sm) - 0xDC00) > 0x3FF) goto ErrMode; if ((c = endSwap(utf16[i], sm) - 0xDC00) > 0x3FF) goto ErrMode;
v = ((v - 0xD800) << 10) + c + 0x10000; v = ((v - 0xD800) << 10) + c + 0x10000;
} }
} }
buff[cc] = v; buff[cc] = v;
cc++; cc++;
if (cc >= TEMP_UCS4_BUFFER_SIZE) { if (cc >= TEMP_UCS4_BUFFER_SIZE) {
if (0 > buAppendBlkUcs4 (bu, buff, cc, errCh)) goto ErrReturn; if (0 > buAppendBlkUcs4(bu, buff, cc, errCh)) goto ErrReturn;
cc = 0; cc = 0;
} }
} }
if (cc > 0 && 0 > buAppendBlkUcs4 (bu, buff, cc, errCh)) goto ErrReturn; if (cc > 0 && 0 > buAppendBlkUcs4(bu, buff, cc, errCh)) goto ErrReturn;
return BSTR_OK; return BSTR_OK;
} }
...@@ -22,16 +22,17 @@ ...@@ -22,16 +22,17 @@
extern "C" { extern "C" {
#endif #endif
extern int buIsUTF8Content (const_bstring bu); extern int buIsUTF8Content(const_bstring bu);
extern int buAppendBlkUcs4 (bstring b, const cpUcs4* bu, int len, cpUcs4 errCh); extern int buAppendBlkUcs4(bstring b, const cpUcs4* bu, int len, cpUcs4 errCh);
/* For those unfortunate enough to be stuck supporting UTF16. */ /* For those unfortunate enough to be stuck supporting UTF16. */
extern int buGetBlkUTF16 (/* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos); extern int buGetBlkUTF16(
extern int buAppendBlkUTF16 (bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh); /* @out */ cpUcs2* ucs2, int len, cpUcs4 errCh, const_bstring bu, int pos);
extern int buAppendBlkUTF16(
bstring bu, const cpUcs2* utf16, int len, cpUcs2* bom, cpUcs4 errCh);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* BSTRLIB_UNICODE_UTILITIES */ #endif /* BSTRLIB_UNICODE_UTILITIES */
...@@ -16,99 +16,105 @@ ...@@ -16,99 +16,105 @@
#ifndef NULL #ifndef NULL
#ifdef __cplusplus #ifdef __cplusplus
#define NULL 0 #define NULL 0
#else #else
#define NULL ((void *)0) #define NULL ((void*) 0)
#endif #endif
#endif #endif
/* Surrogate range is wrong, there is a maximum, the BOM alias is illegal and 0xFFFF is illegal */ /* Surrogate range is wrong, there is a maximum, the BOM alias is illegal and
#define isLegalUnicodeCodePoint(v) ((((v) < 0xD800L) || ((v) > 0xDFFFL)) && (((unsigned long)(v)) <= 0x0010FFFFL) && (((v)|0x1F0001) != 0x1FFFFFL)) * 0xFFFF is illegal */
#define isLegalUnicodeCodePoint(v) \
void utf8IteratorInit (struct utf8Iterator* iter, unsigned char* data, int slen) { ((((v) < 0xD800L) || ((v) > 0xDFFFL)) && \
if (iter) { (((unsigned long) (v)) <= 0x0010FFFFL) && (((v) | 0x1F0001) != 0x1FFFFFL))
iter->data = data;
iter->slen = (iter->data && slen >= 0) ? slen : -1; void utf8IteratorInit(
iter->start = -1; struct utf8Iterator* iter, unsigned char* data, int slen) {
iter->next = (iter->slen >= 0) ? 0 : -1; if (iter) {
iter->error = (iter->slen >= 0) ? 0 : 1; iter->data = data;
} iter->slen = (iter->data && slen >= 0) ? slen : -1;
iter->start = -1;
iter->next = (iter->slen >= 0) ? 0 : -1;
iter->error = (iter->slen >= 0) ? 0 : 1;
}
} }
void utf8IteratorUninit (struct utf8Iterator* iter) { void utf8IteratorUninit(struct utf8Iterator* iter) {
if (iter) { if (iter) {
iter->data = NULL; iter->data = NULL;
iter->slen = -1; iter->slen = -1;
iter->start = iter->next = -1; iter->start = iter->next = -1;
} }
} }
int utf8ScanBackwardsForCodePoint (unsigned char* msg, int len, int pos, cpUcs4* out) { int utf8ScanBackwardsForCodePoint(
cpUcs4 v1, v2, v3, v4, x; unsigned char* msg, int len, int pos, cpUcs4* out) {
int ret; cpUcs4 v1, v2, v3, v4, x;
if (NULL == msg || len < 0 || (unsigned) pos >= (unsigned) len) { int ret;
return -__LINE__; if (NULL == msg || len < 0 || (unsigned) pos >= (unsigned) len) {
} return -__LINE__;
if (!out) out = &x; }
ret = 0; if (!out) out = &x;
if (msg[pos] < 0x80) { ret = 0;
*out = msg[pos]; if (msg[pos] < 0x80) {
return 0; *out = msg[pos];
} else if (msg[pos] < 0xC0) { return 0;
if (0 == pos) return -__LINE__; } else if (msg[pos] < 0xC0) {
ret = -__LINE__; if (0 == pos) return -__LINE__;
if (msg[pos-1] >= 0xC1 && msg[pos-1] < 0xF8) { ret = -__LINE__;
pos--; if (msg[pos - 1] >= 0xC1 && msg[pos - 1] < 0xF8) {
ret = 1; pos--;
} else { ret = 1;
if (1 == pos) return -__LINE__; } else {
if ((msg[pos-1] | 0x3F) != 0xBF) return -__LINE__; if (1 == pos) return -__LINE__;
if (msg[pos-2] >= 0xE0 && msg[pos-2] < 0xF8) { if ((msg[pos - 1] | 0x3F) != 0xBF) return -__LINE__;
pos -= 2; if (msg[pos - 2] >= 0xE0 && msg[pos - 2] < 0xF8) {
ret = 2; pos -= 2;
} else { ret = 2;
if (2 == pos) return -__LINE__; } else {
if ((msg[pos-2] | 0x3F) != 0xBF) return -__LINE__; if (2 == pos) return -__LINE__;
if ((msg[pos-3]|0x07) == 0xF7) { if ((msg[pos - 2] | 0x3F) != 0xBF) return -__LINE__;
pos -= 3; if ((msg[pos - 3] | 0x07) == 0xF7) {
ret = 3; pos -= 3;
} else return -__LINE__; ret = 3;
} } else
} return -__LINE__;
} }
if (msg[pos] < 0xE0) { }
if (pos + 1 >= len) return -__LINE__; }
v1 = msg[pos] & ~0xE0; if (msg[pos] < 0xE0) {
v2 = msg[pos+1] & ~0xC0; if (pos + 1 >= len) return -__LINE__;
v1 = (v1 << 6) + v2; v1 = msg[pos] & ~0xE0;
if (v1 < 0x80) return -__LINE__; v2 = msg[pos + 1] & ~0xC0;
*out = v1; v1 = (v1 << 6) + v2;
return ret; if (v1 < 0x80) return -__LINE__;
} *out = v1;
if (msg[pos] < 0xF0) { return ret;
if (pos + 2 >= len) return -__LINE__; }
v1 = msg[pos] & ~0xF0; if (msg[pos] < 0xF0) {
v2 = msg[pos+1] & ~0xC0; if (pos + 2 >= len) return -__LINE__;
v3 = msg[pos+2] & ~0xC0; v1 = msg[pos] & ~0xF0;
v1 = (v1 << 12) + (v2 << 6) + v3; v2 = msg[pos + 1] & ~0xC0;
if (v1 < 0x800) return -__LINE__; v3 = msg[pos + 2] & ~0xC0;
if (!isLegalUnicodeCodePoint(v1)) return -__LINE__; v1 = (v1 << 12) + (v2 << 6) + v3;
*out = v1; if (v1 < 0x800) return -__LINE__;
return ret; if (!isLegalUnicodeCodePoint(v1)) return -__LINE__;
} *out = v1;
return ret;
if (msg[pos] >= 0xF8) return -__LINE__; }
if (pos + 3 >= len) return -__LINE__; if (msg[pos] >= 0xF8) return -__LINE__;
v1 = msg[pos] & ~0xF8;
v2 = msg[pos+1] & ~0xC0; if (pos + 3 >= len) return -__LINE__;
v3 = msg[pos+2] & ~0xC0; v1 = msg[pos] & ~0xF8;
v4 = msg[pos+3] & ~0xC0; v2 = msg[pos + 1] & ~0xC0;
v1 = (v1 << 18) + (v2 << 12) + (v3 << 6) + v4; v3 = msg[pos + 2] & ~0xC0;
if (v1 < 0x10000) return -__LINE__; v4 = msg[pos + 3] & ~0xC0;
if (!isLegalUnicodeCodePoint(v1)) return -__LINE__; v1 = (v1 << 18) + (v2 << 12) + (v3 << 6) + v4;
*out = v1; if (v1 < 0x10000) return -__LINE__;
return ret; if (!isLegalUnicodeCodePoint(v1)) return -__LINE__;
*out = v1;
return ret;
} }
/* /*
...@@ -130,65 +136,70 @@ U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx ...@@ -130,65 +136,70 @@ U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
* *
* iter->data + iter->next points at the characters that will be read next. * iter->data + iter->next points at the characters that will be read next.
* *
* iter->error is boolean indicating whether or not last read contained an error. * iter->error is boolean indicating whether or not last read contained an
* error.
*/ */
cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, cpUcs4 errCh) { cpUcs4 utf8IteratorGetNextCodePoint(struct utf8Iterator* iter, cpUcs4 errCh) {
unsigned char * chrs; unsigned char* chrs;
unsigned char c, d, e; unsigned char c, d, e;
long v; long v;
int i, ofs; int i, ofs;
if (NULL == iter || iter->next < 0) return errCh; if (NULL == iter || iter->next < 0) return errCh;
if (iter->next >= iter->slen) { if (iter->next >= iter->slen) {
iter->start = iter->slen; iter->start = iter->slen;
return errCh; return errCh;
} }
if (NULL == iter->data || iter->next < 0 || utf8IteratorNoMore(iter)) return errCh; if (NULL == iter->data || iter->next < 0 || utf8IteratorNoMore(iter))
chrs = iter->data + iter->next; return errCh;
chrs = iter->data + iter->next;
iter->error = 0;
c = chrs[0]; iter->error = 0;
ofs = 0; c = chrs[0];
ofs = 0;
if (c < 0xC0 || c > 0xFD) {
if (c >= 0x80) goto ErrMode; if (c < 0xC0 || c > 0xFD) {
v = c; if (c >= 0x80) goto ErrMode;
ofs = 1; v = c;
} else if (c < 0xE0) { ofs = 1;
if (iter->next >= iter->slen + 1) goto ErrMode; } else if (c < 0xE0) {
v = (c << 6u) - (0x0C0 << 6u); if (iter->next >= iter->slen + 1) goto ErrMode;
c = (unsigned char) ((unsigned) chrs[1] - 0x080); v = (c << 6u) - (0x0C0 << 6u);
v += c; c = (unsigned char) ((unsigned) chrs[1] - 0x080);
if (c >= 0x40 || v < 0x80) goto ErrMode; v += c;
ofs = 2; if (c >= 0x40 || v < 0x80) goto ErrMode;
} else if (c < 0xF0) { ofs = 2;
if (iter->next >= iter->slen + 2) goto ErrMode; } else if (c < 0xF0) {
v = (c << 12) - (0x0E0 << 12u); if (iter->next >= iter->slen + 2) goto ErrMode;
c = (unsigned char) ((unsigned) chrs[1] - 0x080); v = (c << 12) - (0x0E0 << 12u);
d = (unsigned char) ((unsigned) chrs[2] - 0x080); c = (unsigned char) ((unsigned) chrs[1] - 0x080);
v += (c << 6u) + d; d = (unsigned char) ((unsigned) chrs[2] - 0x080);
if ((c|d) >= 0x40 || v < 0x800 || !isLegalUnicodeCodePoint (v)) goto ErrMode; v += (c << 6u) + d;
ofs = 3; if ((c | d) >= 0x40 || v < 0x800 || !isLegalUnicodeCodePoint(v))
} else if (c < 0xF8) { goto ErrMode;
if (iter->next >= iter->slen + 3) goto ErrMode; ofs = 3;
v = (c << 18) - (0x0F0 << 18u); } else if (c < 0xF8) {
c = (unsigned char) ((unsigned) chrs[1] - 0x080); if (iter->next >= iter->slen + 3) goto ErrMode;
d = (unsigned char) ((unsigned) chrs[2] - 0x080); v = (c << 18) - (0x0F0 << 18u);
e = (unsigned char) ((unsigned) chrs[3] - 0x080); c = (unsigned char) ((unsigned) chrs[1] - 0x080);
v += (c << 12u) + (d << 6u) + e; d = (unsigned char) ((unsigned) chrs[2] - 0x080);
if ((c|d|e) >= 0x40 || v < 0x10000 || !isLegalUnicodeCodePoint (v)) goto ErrMode; e = (unsigned char) ((unsigned) chrs[3] - 0x080);
ofs = 4; v += (c << 12u) + (d << 6u) + e;
} else { /* 5 and 6 byte encodings are invalid */ if ((c | d | e) >= 0x40 || v < 0x10000 || !isLegalUnicodeCodePoint(v))
ErrMode:; goto ErrMode;
iter->error = 1; ofs = 4;
v = errCh; } else { /* 5 and 6 byte encodings are invalid */
for (i = iter->next+1; i < iter->slen; i++) if ((iter->data[i] & 0xC0) != 0x80) break; ErrMode:;
ofs = i - iter->next; iter->error = 1;
} v = errCh;
for (i = iter->next + 1; i < iter->slen; i++)
iter->start = iter->next; if ((iter->data[i] & 0xC0) != 0x80) break;
iter->next += ofs; ofs = i - iter->next;
return v; }
iter->start = iter->next;
iter->next += ofs;
return v;
} }
/* /*
...@@ -198,52 +209,56 @@ cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, cpUcs4 errCh) { ...@@ -198,52 +209,56 @@ cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, cpUcs4 errCh) {
* *
* iter->data + iter->next points at the characters that will be read next. * iter->data + iter->next points at the characters that will be read next.
* *
* iter->error is boolean indicating whether or not last read contained an error. * iter->error is boolean indicating whether or not last read contained an
* error.
*/ */
cpUcs4 utf8IteratorGetCurrCodePoint (struct utf8Iterator* iter, cpUcs4 errCh) { cpUcs4 utf8IteratorGetCurrCodePoint(struct utf8Iterator* iter, cpUcs4 errCh) {
unsigned char * chrs; unsigned char* chrs;
unsigned char c, d, e; unsigned char c, d, e;
long v; long v;
if (NULL == iter || iter->next < 0) return errCh; if (NULL == iter || iter->next < 0) return errCh;
if (iter->next >= iter->slen) { if (iter->next >= iter->slen) {
iter->start = iter->slen; iter->start = iter->slen;
return errCh; return errCh;
} }
if (NULL == iter->data || iter->next < 0 || utf8IteratorNoMore(iter)) return errCh; if (NULL == iter->data || iter->next < 0 || utf8IteratorNoMore(iter))
chrs = iter->data + iter->next; return errCh;
chrs = iter->data + iter->next;
iter->error = 0;
c = chrs[0]; iter->error = 0;
c = chrs[0];
if (c < 0xC0 || c > 0xFD) {
if (c >= 0x80) goto ErrMode; if (c < 0xC0 || c > 0xFD) {
v = c; if (c >= 0x80) goto ErrMode;
} else if (c < 0xE0) { v = c;
if (iter->next >= iter->slen + 1) goto ErrMode; } else if (c < 0xE0) {
v = (c << 6u) - (0x0C0 << 6u); if (iter->next >= iter->slen + 1) goto ErrMode;
c = (unsigned char) ((unsigned) chrs[1] - 0x080); v = (c << 6u) - (0x0C0 << 6u);
v += c; c = (unsigned char) ((unsigned) chrs[1] - 0x080);
if (c >= 0x40 || v < 0x80) goto ErrMode; v += c;
} else if (c < 0xF0) { if (c >= 0x40 || v < 0x80) goto ErrMode;
if (iter->next >= iter->slen + 2) goto ErrMode; } else if (c < 0xF0) {
v = (c << 12lu) - (0x0E0 << 12u); if (iter->next >= iter->slen + 2) goto ErrMode;
c = (unsigned char) ((unsigned) chrs[1] - 0x080); v = (c << 12lu) - (0x0E0 << 12u);
d = (unsigned char) ((unsigned) chrs[2] - 0x080); c = (unsigned char) ((unsigned) chrs[1] - 0x080);
v += (c << 6u) + d; d = (unsigned char) ((unsigned) chrs[2] - 0x080);
if ((c|d) >= 0x40 || v < 0x800 || !isLegalUnicodeCodePoint (v)) goto ErrMode; v += (c << 6u) + d;
} else if (c < 0xF8) { if ((c | d) >= 0x40 || v < 0x800 || !isLegalUnicodeCodePoint(v))
if (iter->next >= iter->slen + 3) goto ErrMode; goto ErrMode;
v = (c << 18lu) - (0x0F0 << 18u); } else if (c < 0xF8) {
c = (unsigned char) ((unsigned) chrs[1] - 0x080); if (iter->next >= iter->slen + 3) goto ErrMode;
d = (unsigned char) ((unsigned) chrs[2] - 0x080); v = (c << 18lu) - (0x0F0 << 18u);
e = (unsigned char) ((unsigned) chrs[3] - 0x080); c = (unsigned char) ((unsigned) chrs[1] - 0x080);
v += (c << 12lu) + (d << 6u) + e; d = (unsigned char) ((unsigned) chrs[2] - 0x080);
if ((c|d|e) >= 0x40 || v < 0x10000 || !isLegalUnicodeCodePoint (v)) goto ErrMode; e = (unsigned char) ((unsigned) chrs[3] - 0x080);
} else { /* 5 and 6 byte encodings are invalid */ v += (c << 12lu) + (d << 6u) + e;
ErrMode:; if ((c | d | e) >= 0x40 || v < 0x10000 || !isLegalUnicodeCodePoint(v))
iter->error = 1; goto ErrMode;
v = errCh; } else { /* 5 and 6 byte encodings are invalid */
} ErrMode:;
return v; iter->error = 1;
v = errCh;
}
return v;
} }
...@@ -21,39 +21,45 @@ extern "C" { ...@@ -21,39 +21,45 @@ extern "C" {
#endif #endif
#if INT_MAX >= 0x7fffffffUL #if INT_MAX >= 0x7fffffffUL
typedef int cpUcs4; typedef int cpUcs4;
#elif LONG_MAX >= 0x7fffffffUL #elif LONG_MAX >= 0x7fffffffUL
typedef long cpUcs4; typedef long cpUcs4;
#else #else
#error This compiler is not supported #error This compiler is not supported
#endif #endif
#if UINT_MAX == 0xFFFF #if UINT_MAX == 0xFFFF
typedef unsigned int cpUcs2; typedef unsigned int cpUcs2;
#elif USHRT_MAX == 0xFFFF #elif USHRT_MAX == 0xFFFF
typedef unsigned short cpUcs2; typedef unsigned short cpUcs2;
#elif UCHAR_MAX == 0xFFFF #elif UCHAR_MAX == 0xFFFF
typedef unsigned char cpUcs2; typedef unsigned char cpUcs2;
#else #else
#error This compiler is not supported #error This compiler is not supported
#endif #endif
#define isLegalUnicodeCodePoint(v) ((((v) < 0xD800L) || ((v) > 0xDFFFL)) && (((unsigned long)(v)) <= 0x0010FFFFL) && (((v)|0x1F0001) != 0x1FFFFFL)) #define isLegalUnicodeCodePoint(v) \
((((v) < 0xD800L) || ((v) > 0xDFFFL)) && \
(((unsigned long) (v)) <= 0x0010FFFFL) && (((v) | 0x1F0001) != 0x1FFFFFL))
struct utf8Iterator { struct utf8Iterator {
unsigned char* data; unsigned char* data;
int slen; int slen;
int start, next; int start, next;
int error; int error;
}; };
#define utf8IteratorNoMore(it) (!(it) || (it)->next >= (it)->slen) #define utf8IteratorNoMore(it) (!(it) || (it)->next >= (it)->slen)
extern void utf8IteratorInit (struct utf8Iterator* iter, unsigned char* data, int slen); extern void utf8IteratorInit(
extern void utf8IteratorUninit (struct utf8Iterator* iter); struct utf8Iterator* iter, unsigned char* data, int slen);
extern cpUcs4 utf8IteratorGetNextCodePoint (struct utf8Iterator* iter, cpUcs4 errCh); extern void utf8IteratorUninit(struct utf8Iterator* iter);
extern cpUcs4 utf8IteratorGetCurrCodePoint (struct utf8Iterator* iter, cpUcs4 errCh); extern cpUcs4 utf8IteratorGetNextCodePoint(
extern int utf8ScanBackwardsForCodePoint (unsigned char* msg, int len, int pos, cpUcs4* out); struct utf8Iterator* iter, cpUcs4 errCh);
extern cpUcs4 utf8IteratorGetCurrCodePoint(
struct utf8Iterator* iter, cpUcs4 errCh);
extern int utf8ScanBackwardsForCodePoint(
unsigned char* msg, int len, int pos, cpUcs4* out);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -53,7 +53,7 @@ bool mime_parser::parse(const std::string& str) { ...@@ -53,7 +53,7 @@ bool mime_parser::parse(const std::string& str) {
str.substr(content_type_pos + 14, crlf_pos - (content_type_pos + 14)); str.substr(content_type_pos + 14, crlf_pos - (content_type_pos + 14));
Logger::smf_app().debug("Content Type: %s", p.content_type.c_str()); Logger::smf_app().debug("Content Type: %s", p.content_type.c_str());
crlf_pos = str.find(CRLF + CRLF, content_type_pos); // beginning of content crlf_pos = str.find(CRLF + CRLF, content_type_pos); // beginning of content
boundary_pos = str.find(boundary_full, crlf_pos); boundary_pos = str.find(boundary_full, crlf_pos);
if (boundary_pos == std::string::npos) { if (boundary_pos == std::string::npos) {
boundary_pos = str.find(last_boundary, crlf_pos); boundary_pos = str.find(last_boundary, crlf_pos);
......
...@@ -44,7 +44,8 @@ int decode_authentication_reject( ...@@ -44,7 +44,8 @@ int decode_authentication_reject(
case AUTHENTICATION_REJECT_EAP_MESSAGE_IEI: case AUTHENTICATION_REJECT_EAP_MESSAGE_IEI:
// if((decoded_result = decode_message_type // if((decoded_result = decode_message_type
// (&authentication_reject->messagetype, // (&authentication_reject->messagetype,
// AUTHENTICATION_REJECT_EAP_MESSAGE_IEI, buffer+decoded,len-decoded))<0) // AUTHENTICATION_REJECT_EAP_MESSAGE_IEI,
// buffer+decoded,len-decoded))<0)
if ((decoded_result = decode_eap_message( if ((decoded_result = decode_eap_message(
&authentication_reject->eapmessage, &authentication_reject->eapmessage,
AUTHENTICATION_REJECT_EAP_MESSAGE_IEI, buffer + decoded, AUTHENTICATION_REJECT_EAP_MESSAGE_IEI, buffer + decoded,
......
...@@ -222,8 +222,8 @@ int encode_pdu_session_establishment_accept( ...@@ -222,8 +222,8 @@ int encode_pdu_session_establishment_accept(
else else
encoded += encoded_result; encoded += encoded_result;
// TODO: In Wireshark Version 3.2.2 (Git commit a3efece3d640), SSC Mode (4 // TODO: In Wireshark Version 3.2.2 (Git commit a3efece3d640), SSC Mode (4
// bit) + PDU session type (4 bit) = 1 byte, so disable encode SSC Mode for the // bit) + PDU session type (4 bit) = 1 byte, so disable encode SSC Mode for
// moment, Should be verified later // the moment, Should be verified later
/* if((encoded_result = encode_ssc_mode /* if((encoded_result = encode_ssc_mode
(pdu_session_establishment_accept->sscmode, 0, (pdu_session_establishment_accept->sscmode, 0,
buffer+encoded,len-encoded))<0) return encoded_result; else encoded += buffer+encoded,len-encoded))<0) return encoded_result; else encoded +=
......
/* /*
* Copyright (c) 2017 Sprint * Copyright (c) 2017 Sprint
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include "async_shell_cmd.hpp" #include "async_shell_cmd.hpp"
#include "common_defs.h" #include "common_defs.h"
...@@ -33,43 +32,43 @@ ...@@ -33,43 +32,43 @@
#include <thread> #include <thread>
#include <signal.h> #include <signal.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> // srand #include <stdlib.h> // srand
#include <unistd.h> // get_pid(), pause() #include <unistd.h> // get_pid(), pause()
using namespace smf; using namespace smf;
using namespace util; using namespace util;
using namespace std; using namespace std;
using namespace oai::smf_server::api; using namespace oai::smf_server::api;
itti_mw *itti_inst = nullptr; itti_mw* itti_inst = nullptr;
async_shell_cmd *async_shell_cmd_inst = nullptr; async_shell_cmd* async_shell_cmd_inst = nullptr;
smf_app *smf_app_inst = nullptr; smf_app* smf_app_inst = nullptr;
smf_config smf_cfg; smf_config smf_cfg;
SMFApiServer *smf_api_server_1 = nullptr; SMFApiServer* smf_api_server_1 = nullptr;
smf_http2_server *smf_api_server_2 = nullptr; smf_http2_server* smf_api_server_2 = nullptr;
void send_heartbeat_to_tasks(const uint32_t sequence); void send_heartbeat_to_tasks(const uint32_t sequence);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void send_heartbeat_to_tasks(const uint32_t sequence) void send_heartbeat_to_tasks(const uint32_t sequence) {
{ itti_msg_ping* itti_msg = new itti_msg_ping(TASK_SMF_APP, TASK_ALL, sequence);
itti_msg_ping *itti_msg = new itti_msg_ping(TASK_SMF_APP, TASK_ALL, sequence);
std::shared_ptr<itti_msg_ping> i = std::shared_ptr<itti_msg_ping>(itti_msg); std::shared_ptr<itti_msg_ping> i = std::shared_ptr<itti_msg_ping>(itti_msg);
int ret = itti_inst->send_broadcast_msg(i); int ret = itti_inst->send_broadcast_msg(i);
if (RETURNok != ret) { if (RETURNok != ret) {
Logger::smf_app().error( "Could not send ITTI message %s to task TASK_ALL", i->get_msg_name()); Logger::smf_app().error(
"Could not send ITTI message %s to task TASK_ALL", i->get_msg_name());
} }
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void my_app_signal_handler(int s) void my_app_signal_handler(int s) {
{
std::cout << "Caught signal " << s << std::endl; std::cout << "Caught signal " << s << std::endl;
Logger::system().startup( "exiting" ); Logger::system().startup("exiting");
itti_inst->send_terminate_msg(TASK_SMF_APP); itti_inst->send_terminate_msg(TASK_SMF_APP);
itti_inst->wait_tasks_end(); itti_inst->wait_tasks_end();
std::cout << "Freeing Allocated memory..." << std::endl; std::cout << "Freeing Allocated memory..." << std::endl;
if (async_shell_cmd_inst) delete async_shell_cmd_inst; async_shell_cmd_inst = nullptr; if (async_shell_cmd_inst) delete async_shell_cmd_inst;
async_shell_cmd_inst = nullptr;
std::cout << "Async Shell CMD memory done." << std::endl; std::cout << "Async Shell CMD memory done." << std::endl;
if (smf_api_server_1) { if (smf_api_server_1) {
smf_api_server_1->shutdown(); smf_api_server_1->shutdown();
...@@ -82,29 +81,29 @@ void my_app_signal_handler(int s) ...@@ -82,29 +81,29 @@ void my_app_signal_handler(int s)
smf_api_server_2 = nullptr; smf_api_server_2 = nullptr;
} }
std::cout << "SMF API Server memory done." << std::endl; std::cout << "SMF API Server memory done." << std::endl;
if (itti_inst) delete itti_inst; itti_inst = nullptr; if (itti_inst) delete itti_inst;
itti_inst = nullptr;
std::cout << "ITTI memory done." << std::endl; std::cout << "ITTI memory done." << std::endl;
if (smf_app_inst) delete smf_app_inst; smf_app_inst = nullptr; if (smf_app_inst) delete smf_app_inst;
smf_app_inst = nullptr;
std::cout << "SMF APP memory done." << std::endl; std::cout << "SMF APP memory done." << std::endl;
std::cout << "Freeing Allocated memory done" << std::endl; std::cout << "Freeing Allocated memory done" << std::endl;
exit(0); exit(0);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int main(int argc, char **argv) int main(int argc, char** argv) {
{ srand(time(NULL));
srand (time(NULL));
// Command line options // Command line options
if ( !Options::parse( argc, argv ) ) if (!Options::parse(argc, argv)) {
{ std::cout << "Options::parse() failed" << std::endl;
std::cout << "Options::parse() failed" << std::endl; return 1;
return 1;
} }
// Logger // Logger
Logger::init( "smf" , Options::getlogStdout() , Options::getlogRotFilelog()); Logger::init("smf", Options::getlogStdout(), Options::getlogRotFilelog());
Logger::smf_app().startup( "Options parsed" ); Logger::smf_app().startup("Options parsed");
struct sigaction sigIntHandler; struct sigaction sigIntHandler;
sigIntHandler.sa_handler = my_app_signal_handler; sigIntHandler.sa_handler = my_app_signal_handler;
...@@ -121,36 +120,40 @@ int main(int argc, char **argv) ...@@ -121,36 +120,40 @@ int main(int argc, char **argv)
itti_inst->start(smf_cfg.itti.itti_timer_sched_params); itti_inst->start(smf_cfg.itti.itti_timer_sched_params);
// system command // system command
async_shell_cmd_inst = new async_shell_cmd(smf_cfg.itti.async_cmd_sched_params); async_shell_cmd_inst =
new async_shell_cmd(smf_cfg.itti.async_cmd_sched_params);
// SMF application layer // SMF application layer
smf_app_inst = new smf_app(Options::getlibconfigConfig()); smf_app_inst = new smf_app(Options::getlibconfigConfig());
// PID file // PID file
// Currently hard-coded value. TODO: add as config option. // Currently hard-coded value. TODO: add as config option.
string pid_file_name = get_exe_absolute_path("/var/run", smf_cfg.instance); string pid_file_name = get_exe_absolute_path("/var/run", smf_cfg.instance);
if (! is_pid_file_lock_success(pid_file_name.c_str())) { if (!is_pid_file_lock_success(pid_file_name.c_str())) {
Logger::smf_app().error( "Lock PID file %s failed\n", pid_file_name.c_str()); Logger::smf_app().error("Lock PID file %s failed\n", pid_file_name.c_str());
exit (-EDEADLK); exit(-EDEADLK);
} }
//SMF Pistache API server (HTTP1) // SMF Pistache API server (HTTP1)
Pistache::Address addr(std::string(inet_ntoa (*((struct in_addr *)&smf_cfg.sbi.addr4))) , Pistache::Port(smf_cfg.sbi.port)); Pistache::Address addr(
std::string(inet_ntoa(*((struct in_addr*) &smf_cfg.sbi.addr4))),
Pistache::Port(smf_cfg.sbi.port));
smf_api_server_1 = new SMFApiServer(addr, smf_app_inst); smf_api_server_1 = new SMFApiServer(addr, smf_app_inst);
smf_api_server_1->init(2); smf_api_server_1->init(2);
//smf_api_server_1->start(); // smf_api_server_1->start();
std::thread smf_http1_manager(&SMFApiServer::start, smf_api_server_1); std::thread smf_http1_manager(&SMFApiServer::start, smf_api_server_1);
//SMF NGHTTP API server (HTTP2) // SMF NGHTTP API server (HTTP2)
smf_api_server_2 = new smf_http2_server(conv::toString(smf_cfg.sbi.addr4), smf_cfg.sbi_http2_port, smf_app_inst); smf_api_server_2 = new smf_http2_server(
//smf_api_server_2->start(); conv::toString(smf_cfg.sbi.addr4), smf_cfg.sbi_http2_port, smf_app_inst);
// smf_api_server_2->start();
std::thread smf_http2_manager(&smf_http2_server::start, smf_api_server_2); std::thread smf_http2_manager(&smf_http2_server::start, smf_api_server_2);
smf_http1_manager.join(); smf_http1_manager.join();
smf_http2_manager.join(); smf_http2_manager.join();
FILE *fp = NULL; FILE* fp = NULL;
std::string filename = fmt::format("/tmp/smf_{}.status", getpid()); std::string filename = fmt::format("/tmp/smf_{}.status", getpid());
fp = fopen(filename.c_str(), "w+"); fp = fopen(filename.c_str(), "w+");
fprintf(fp, "STARTED\n"); fprintf(fp, "STARTED\n");
fflush(fp); fflush(fp);
fclose(fp); fclose(fp);
......
/* /*
* Copyright (c) 2017 Sprint * Copyright (c) 2017 Sprint
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include <iostream> #include <iostream>
#include <stdlib.h> #include <stdlib.h>
...@@ -28,83 +27,104 @@ std::string Options::m_libconfigcfg; ...@@ -28,83 +27,104 @@ std::string Options::m_libconfigcfg;
bool Options::m_log_rot_file_log; bool Options::m_log_rot_file_log;
bool Options::m_log_stdout; bool Options::m_log_stdout;
void Options::help() void Options::help() {
{ std::cout << std::endl
std::cout << std::endl << "Usage: smf [OPTIONS]..." << std::endl
<< "Usage: smf [OPTIONS]..." << std::endl << " -h, --help Print help and exit" << std::endl
<< " -h, --help Print help and exit" << std::endl << " -c, --libconfigcfg filename Read the application "
<< " -c, --libconfigcfg filename Read the application configuration from this file." << std::endl "configuration from this file."
<< " -o, --stdoutlog Send the application logs to STDOUT fd." << std::endl << std::endl
<< " -r, --rotatelog Send the application logs to local file (in current working directory)." << std::endl << " -o, --stdoutlog Send the application logs to "
; "STDOUT fd."
<< std::endl
<< " -r, --rotatelog Send the application logs to "
"local file (in current working directory)."
<< std::endl;
} }
bool Options::parse( int argc, char **argv ){ bool Options::parse(int argc, char** argv) {
bool ret = true;
bool ret = true;
ret = parseInputOptions( argc, argv ); ret = parseInputOptions(argc, argv);
ret &= validateOptions(); ret &= validateOptions();
return ret; return ret;
} }
bool Options::validateOptions() {
bool Options::validateOptions(){ return ((options & libconfigcfg));
return (
(options & libconfigcfg)
);
} }
bool Options::parseInputOptions( int argc, char **argv ) bool Options::parseInputOptions(int argc, char** argv) {
{ int c;
int c; int option_index = 0;
int option_index = 0; bool result = true;
bool result = true;
struct option long_options[] = {
struct option long_options[] = { {"help", no_argument, NULL, 'h'},
{ "help", no_argument, NULL, 'h' }, {"libconfigcfg", required_argument, NULL, 'f'},
{ "libconfigcfg", required_argument, NULL, 'f' }, {"stdoutlog", no_argument, NULL, 'o'},
{ "stdoutlog", no_argument, NULL, 'o' }, {"rotatelog", no_argument, NULL, 'r'},
{ "rotatelog", no_argument, NULL, 'r' }, {NULL, 0, NULL, 0}};
{ NULL,0,NULL,0 }
}; // Loop on arguments
while (1) {
// Loop on arguments c = getopt_long(argc, argv, "horc:", long_options, &option_index);
while (1) if (c == -1) break; // Exit from the loop.
{
c = getopt_long(argc, argv, "horc:", long_options, &option_index ); switch (c) {
if (c == -1) case 'h': {
break; // Exit from the loop. help();
exit(0);
switch (c) break;
{ }
case 'h': { help(); exit(0); break; } case 'c': {
case 'c': { m_libconfigcfg = optarg; options |= libconfigcfg; break; } m_libconfigcfg = optarg;
case 'o': { m_log_stdout = true; options |= log_stdout; break; } options |= libconfigcfg;
case 'r': { m_log_rot_file_log = true; options |= log_rot_file_log; break; } break;
}
case 'o': {
m_log_stdout = true;
options |= log_stdout;
break;
}
case 'r': {
m_log_rot_file_log = true;
options |= log_rot_file_log;
break;
}
case '?': case '?': {
{ switch (optopt) {
switch ( optopt ) case 'c': {
{ std::cout << "Option -l (libconfig config) requires an argument"
case 'c': { std::cout << "Option -l (libconfig config) requires an argument" << std::endl; break; } << std::endl;
case 'o': { std::cout << "Option -o do not requires an argument, can be also set with option -r." << std::endl; break; } break;
case 'r': { std::cout << "Option -r do not requires an argument, can be also set with option -o." << std::endl; break; } }
default: { std::cout << "Unrecognized option [" << c << "]" << std::endl; break; } case 'o': {
} std::cout << "Option -o do not requires an argument, can be also "
result = false; "set with option -r."
<< std::endl;
break; break;
} }
default: case 'r': {
{ std::cout << "Option -r do not requires an argument, can be also "
"set with option -o."
<< std::endl;
break;
}
default: {
std::cout << "Unrecognized option [" << c << "]" << std::endl; std::cout << "Unrecognized option [" << c << "]" << std::endl;
result = false; break;
} }
}
result = false;
break;
} }
} default: {
return result; std::cout << "Unrecognized option [" << c << "]" << std::endl;
result = false;
}
}
}
return result;
} }
/* /*
* Copyright (c) 2017 Sprint * Copyright (c) 2017 Sprint
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, * distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#ifndef __OPTIONS_H #ifndef __OPTIONS_H
#define __OPTIONS_H #define __OPTIONS_H
...@@ -20,35 +20,31 @@ ...@@ -20,35 +20,31 @@
#include <stdint.h> #include <stdint.h>
#include <string> #include <string>
class Options {
public:
static bool parse(int argc, char** argv);
static bool parseInputOptions(int argc, char** argv);
static bool parseJson();
static bool validateOptions();
class Options static const std::string& getlibconfigConfig() { return m_libconfigcfg; }
{ static const bool& getlogRotFilelog() { return m_log_rot_file_log; }
public: static const bool& getlogStdout() { return m_log_stdout; }
static bool parse( int argc, char **argv ); private:
static bool parseInputOptions( int argc, char **argv ); enum OptionsSelected {
static bool parseJson(); libconfigcfg = 0x01,
static bool validateOptions(); log_stdout = 0x02,
log_rot_file_log = 0x04
};
static const std::string &getlibconfigConfig() { return m_libconfigcfg; } static void help();
static const bool &getlogRotFilelog() { return m_log_rot_file_log; }
static const bool &getlogStdout() { return m_log_stdout; }
private: static int options;
enum OptionsSelected { static bool m_log_rot_file_log;
libconfigcfg = 0x01, static bool m_log_stdout;
log_stdout = 0x02, static std::string m_libconfigcfg;
log_rot_file_log = 0x04
};
static void help();
static int options;
static bool m_log_rot_file_log;
static bool m_log_stdout;
static std::string m_libconfigcfg;
}; };
#endif // #define __OPTIONS_H #endif // #define __OPTIONS_H
...@@ -53,9 +53,9 @@ int smf_app::pco_push_protocol_or_container_id( ...@@ -53,9 +53,9 @@ int smf_app::pco_push_protocol_or_container_id(
pco_item.length_of_protocol_id_contents = pco_item.length_of_protocol_id_contents =
poc_id->length_of_protocol_id_contents; poc_id->length_of_protocol_id_contents;
pco_item.protocol_id_contents = poc_id->protocol_id_contents; pco_item.protocol_id_contents = poc_id->protocol_id_contents;
// assert(pco_item.length_of_protocol_id_contents == // assert(pco_item.length_of_protocol_id_contents ==
// pco_item.protocol_id_contents.size()); // pco_item.protocol_id_contents.size());
// pco_item.protocol_id_contents = nullptr; // pco_item.protocol_id_contents = nullptr;
pco.protocol_or_container_ids.push_back(pco_item); pco.protocol_or_container_ids.push_back(pco_item);
pco.num_protocol_or_container_id += 1; pco.num_protocol_or_container_id += 1;
......
...@@ -331,7 +331,7 @@ void session_create_sm_context_procedure::handle_itti_msg( ...@@ -331,7 +331,7 @@ void session_create_sm_context_procedure::handle_itti_msg(
smf_qos_flow default_qos_flow = {}; smf_qos_flow default_qos_flow = {};
// flow_updated info will be used to construct N1,N2 container // flow_updated info will be used to construct N1,N2 container
qos_flow_context_updated flow_updated = {}; qos_flow_context_updated flow_updated = {};
QOSRulesIE qos_rule = {}; QOSRulesIE qos_rule = {};
flow_updated.set_cause(REQUEST_ACCEPTED); flow_updated.set_cause(REQUEST_ACCEPTED);
if (not sps->get_default_qos_flow(default_qos_flow)) { if (not sps->get_default_qos_flow(default_qos_flow)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment