Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-SMF
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-SMF
Commits
e1c9d4df
Commit
e1c9d4df
authored
Jan 23, 2021
by
Tien-Thinh Nguyen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Code cleanup
parent
c63a4711
Changes
29
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
3353 additions
and
3276 deletions
+3353
-3276
src/api-server/api/SMContextsCollectionApi.cpp
src/api-server/api/SMContextsCollectionApi.cpp
+2
-1
src/api-server/impl/IndividualSMContextApiImpl.cpp
src/api-server/impl/IndividualSMContextApiImpl.cpp
+2
-2
src/api-server/impl/IndividualSubscriptionDocumentApiImpl.cpp
...api-server/impl/IndividualSubscriptionDocumentApiImpl.cpp
+0
-1
src/api-server/impl/NFStatusNotifyApiImpl.h
src/api-server/impl/NFStatusNotifyApiImpl.h
+0
-1
src/api-server/impl/PDUSessionsCollectionApiImpl.cpp
src/api-server/impl/PDUSessionsCollectionApiImpl.cpp
+0
-1
src/api-server/smf-http2-server.cpp
src/api-server/smf-http2-server.cpp
+6
-4
src/common/3gpp_23.003.h
src/common/3gpp_23.003.h
+1
-1
src/common/3gpp_29.502.h
src/common/3gpp_29.502.h
+5
-5
src/common/endpoint.hpp
src/common/endpoint.hpp
+23
-40
src/common/logger.hpp
src/common/logger.hpp
+60
-100
src/common/serializable.hpp
src/common/serializable.hpp
+3
-3
src/common/utils/3gpp_conversions.cpp
src/common/utils/3gpp_conversions.cpp
+1
-2
src/common/utils/bstr/bsafe.c
src/common/utils/bstr/bsafe.c
+49
-44
src/common/utils/bstr/bsafe.h
src/common/utils/bstr/bsafe.h
+10
-10
src/common/utils/bstr/bstrlib.c
src/common/utils/bstr/bstrlib.c
+945
-899
src/common/utils/bstr/bstrwrap.cpp
src/common/utils/bstr/bstrwrap.cpp
+1326
-1302
src/common/utils/bstr/bstrwrap.h
src/common/utils/bstr/bstrwrap.h
+325
-312
src/common/utils/bstr/buniutil.c
src/common/utils/bstr/buniutil.c
+158
-153
src/common/utils/bstr/buniutil.h
src/common/utils/bstr/buniutil.h
+6
-5
src/common/utils/bstr/utf8util.c
src/common/utils/bstr/utf8util.c
+205
-190
src/common/utils/bstr/utf8util.h
src/common/utils/bstr/utf8util.h
+21
-15
src/common/utils/mime_parser.cpp
src/common/utils/mime_parser.cpp
+1
-1
src/nas/mm/msg/AuthenticationReject.c
src/nas/mm/msg/AuthenticationReject.c
+2
-1
src/nas/sm/msg/PDUSessionEstablishmentAccept.c
src/nas/sm/msg/PDUSessionEstablishmentAccept.c
+2
-2
src/oai_smf/main.cpp
src/oai_smf/main.cpp
+58
-55
src/oai_smf/options.cpp
src/oai_smf/options.cpp
+103
-83
src/oai_smf/options.hpp
src/oai_smf/options.hpp
+35
-39
src/smf_app/smf_pco.cpp
src/smf_app/smf_pco.cpp
+3
-3
src/smf_app/smf_procedure.cpp
src/smf_app/smf_procedure.cpp
+1
-1
No files found.
src/api-server/api/SMContextsCollectionApi.cpp
View file @
e1c9d4df
...
...
@@ -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
...
...
src/api-server/impl/IndividualSMContextApiImpl.cpp
View file @
e1c9d4df
...
...
@@ -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)*/
...
...
src/api-server/impl/IndividualSubscriptionDocumentApiImpl.cpp
View file @
e1c9d4df
...
...
@@ -32,7 +32,6 @@
* contact@openairinterface.org
*/
#include "IndividualSubscriptionDocumentApiImpl.h"
namespace
oai
{
...
...
src/api-server/impl/NFStatusNotifyApiImpl.h
View file @
e1c9d4df
...
...
@@ -38,7 +38,6 @@
* contact@openairinterface.org
*/
#ifndef NF_STATUS_NOTIFY_API_IMPL_H_
#define NF_STATUS_NOTIFY_API_IMPL_H_
...
...
src/api-server/impl/PDUSessionsCollectionApiImpl.cpp
View file @
e1c9d4df
...
...
@@ -32,7 +32,6 @@
* contact@openairinterface.org
*/
#include "PDUSessionsCollectionApiImpl.h"
namespace
oai
{
...
...
src/api-server/smf-http2-server.cpp
View file @
e1c9d4df
...
...
@@ -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)*/
...
...
src/common/3gpp_23.003.h
View file @
e1c9d4df
...
...
@@ -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). */
...
...
src/common/3gpp_29.502.h
View file @
e1c9d4df
...
...
@@ -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
...
...
src/common/endpoint.hpp
View file @
e1c9d4df
...
...
@@ -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
src/common/logger.hpp
View file @
e1c9d4df
...
...
@@ -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
src/common/serializable.hpp
View file @
e1c9d4df
...
...
@@ -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 */
src/common/utils/3gpp_conversions.cpp
View file @
e1c9d4df
...
...
@@ -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
());
...
...
src/common/utils/bstr/bsafe.c
View file @
e1c9d4df
...
...
@@ -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\t
or 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\t
or "
"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;
}
*/
src/common/utils/bstr/bsafe.h
View file @
e1c9d4df
/*
* 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
}
...
...
src/common/utils/bstr/bstrlib.c
View file @
e1c9d4df
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/common/utils/bstr/bstrwrap.cpp
View file @
e1c9d4df
...
...
@@ -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
src/common/utils/bstr/bstrwrap.h
View file @
e1c9d4df
...
...
@@ -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
...
...
src/common/utils/bstr/buniutil.c
View file @
e1c9d4df
...
...
@@ -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
;
}
src/common/utils/bstr/buniutil.h
View file @
e1c9d4df
...
...
@@ -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 */
src/common/utils/bstr/utf8util.c
View file @
e1c9d4df
...
...
@@ -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
;
}
src/common/utils/bstr/utf8util.h
View file @
e1c9d4df
...
...
@@ -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
}
...
...
src/common/utils/mime_parser.cpp
View file @
e1c9d4df
...
...
@@ -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
);
...
...
src/nas/mm/msg/AuthenticationReject.c
View file @
e1c9d4df
...
...
@@ -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
,
...
...
src/nas/sm/msg/PDUSessionEstablishmentAccept.c
View file @
e1c9d4df
...
...
@@ -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 +=
...
...
src/oai_smf/main.cpp
View file @
e1c9d4df
/*
* 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
);
...
...
src/oai_smf/options.cpp
View file @
e1c9d4df
/*
* 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
;
}
src/oai_smf/options.hpp
View file @
e1c9d4df
/*
* 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
src/smf_app/smf_pco.cpp
View file @
e1c9d4df
...
...
@@ -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
;
...
...
src/smf_app/smf_procedure.cpp
View file @
e1c9d4df
...
...
@@ -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
))
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment