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

Code cleanup

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