mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-29 14:44:17 +00:00
add sipcc to tree for sdp parser
This commit is contained in:
1 parent
36f89c8b7c
commit
0f00946782
369 files changed
+183596
No files matched your search
Executable
+386
@@ -0,0 +1,386 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#define __STRINGLIB_INTERNAL__
|
||||
|
||||
#include "cpr_types.h"
|
||||
#include "cpr_stdlib.h"
|
||||
#include "cpr_stdio.h"
|
||||
#include "cpr_string.h"
|
||||
#include "cpr_stddef.h"
|
||||
#include "cpr_locks.h"
|
||||
#include "string_lib.h"
|
||||
#include "phone_debug.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#define STRING_SIGNATURE (('S'<<8)|'T')
|
||||
#define STR_TO_STRUCT(str) ((string_block_t *)((str) - (offsetof(string_block_t,data))))
|
||||
#define STRUCT_TO_STR(sbt) ((const char *) (sbt)->data)
|
||||
|
||||
static string_t empty_str;
|
||||
static int strlib_is_string(string_t str);
|
||||
|
||||
/*
|
||||
* Function: strlib_malloc
|
||||
*
|
||||
* PARAMETERS:const char* : string which is to be malloc'ed
|
||||
int : length of string or -1
|
||||
*
|
||||
* DESCRIPTION:strlib_malloc : creates a new string and returns a const char*
|
||||
* to the new string. Size of String is equal to length specified or actual
|
||||
* length of the string when length is specified as -1(LEN_UNKNOWN)
|
||||
*
|
||||
* RETURNS: Pointer to malloc'ed string
|
||||
*
|
||||
*/
|
||||
string_t
|
||||
strlib_malloc (const char *str, int length, const char *fname, int line)
|
||||
{
|
||||
string_block_t *temp;
|
||||
int size;
|
||||
|
||||
// if specified length is unknown or invalid... then calculate it
|
||||
// Length < 0 is not expected, but since length is an int, it could
|
||||
// theoritically be negative. [ This check accounts for that, and
|
||||
// avoids a static analysis warning related to same ]
|
||||
if ((length == LEN_UNKNOWN) || (length < 0)) {
|
||||
length = strlen(str);
|
||||
}
|
||||
|
||||
size = sizeof(string_block_t) + length + 1;
|
||||
temp = (string_block_t *) cpr_malloc(size);
|
||||
|
||||
if (!temp) {
|
||||
err_msg("Error: Strlib_Malloc() Failed. Requested Size = %d\n", size);
|
||||
return (string_t) 0;
|
||||
}
|
||||
|
||||
temp->refcount = 1;
|
||||
temp->length = (uint16_t) length;
|
||||
temp->signature = STRING_SIGNATURE;
|
||||
temp->fname = fname;
|
||||
temp->line = line;
|
||||
/* There used to be memcpy here which will walk off the end of */
|
||||
/* str pointer which is a bad thing to do */
|
||||
sstrncpy(temp->data, str, length + 1);
|
||||
temp->data[length] = '\0';
|
||||
|
||||
return STRUCT_TO_STR(temp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strlib_copy
|
||||
*
|
||||
* PARAMETERS:string_t : string whose ref count is to be incremented
|
||||
*
|
||||
* DESCRIPTION:just increments the reference count of the string.
|
||||
* It is not like conventional strcpy as far as implementation
|
||||
* is concerned, but effectivly when user calls strlib_copy he gets
|
||||
* private copy which cannot be modified by any other function.
|
||||
* String should be modified only by calling strlib_open
|
||||
* which checks for the refcount and if its more than 1 allocates new string.
|
||||
*
|
||||
* RETURNS: string_t: string whose ref count is incremented
|
||||
*
|
||||
*/
|
||||
string_t
|
||||
strlib_copy (string_t str)
|
||||
{
|
||||
string_block_t *temp;
|
||||
|
||||
if (!strlib_is_string(str)) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
temp = STR_TO_STRUCT(str);
|
||||
|
||||
/*
|
||||
* Refcount is limited to USHRT_MAX since refcount is
|
||||
* of type uint16_t.
|
||||
*/
|
||||
if ((temp->refcount < 0xffff) && (str != empty_str)) {
|
||||
temp->refcount++;
|
||||
}
|
||||
|
||||
return STRUCT_TO_STR(temp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strlib_update
|
||||
*
|
||||
* PARAMETERS:string_t : destination string
|
||||
* const char* : source string
|
||||
*
|
||||
* DESCRIPTION:like strcpy but returns const char* to a string in pool
|
||||
*
|
||||
* RETURNS: string_t:Pointer to a new string
|
||||
*
|
||||
*/
|
||||
string_t
|
||||
strlib_update (string_t destination, const char *source,
|
||||
const char *calling_fname, int line)
|
||||
{
|
||||
const char *fname = "strlib_udpate";
|
||||
string_t ret_str;
|
||||
|
||||
/* Bogus destination */
|
||||
if (!destination) {
|
||||
/* Should never happen, so report it */
|
||||
err_msg("%s: Destination String is invalid: %s:%d", fname,
|
||||
calling_fname, line);
|
||||
/* bad input, bad output */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Bogus source */
|
||||
if (!source) {
|
||||
/* Should never happen, so report it and return something */
|
||||
err_msg("%s: Source String is invalid: %s:%d", fname,
|
||||
calling_fname, line);
|
||||
strlib_free(destination);
|
||||
return strlib_empty();
|
||||
}
|
||||
|
||||
if (source[0] == '\0') {
|
||||
/* Source is NULL string, use string empty */
|
||||
strlib_free(destination);
|
||||
return strlib_empty();
|
||||
}
|
||||
|
||||
ret_str = strlib_malloc(source, LEN_UNKNOWN, calling_fname, line);
|
||||
|
||||
if (!ret_str) {
|
||||
/*
|
||||
* If a malloc error occurred, give them back what they had.
|
||||
* It's not right, but it's better than nothing.
|
||||
*/
|
||||
ret_str = destination;
|
||||
} else {
|
||||
strlib_free(destination);
|
||||
}
|
||||
|
||||
return (ret_str);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strlib_append
|
||||
*
|
||||
* PARAMETERS: string_t : oringinal string
|
||||
* const char* : to be appended string
|
||||
*
|
||||
* DESCRIPTION:this function will append a string to the original string,
|
||||
* makes a duplicate of the string and returns it.
|
||||
*
|
||||
* RETURNS: Appended string (string_t) or NULL if failure
|
||||
*
|
||||
*/
|
||||
string_t
|
||||
strlib_append (string_t str, const char *toappend_str,
|
||||
const char *fname, int line)
|
||||
{
|
||||
int curlen;
|
||||
char *buf;
|
||||
|
||||
/* Should never happen */
|
||||
if (!str) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
curlen = strlen(str);
|
||||
/* not really an open, rather more like modify */
|
||||
buf = strlib_open(str, curlen + strlen(toappend_str) + 1, fname, line);
|
||||
/*
|
||||
* Validate returned value, but buf could be equal to str (buf == str)
|
||||
* so there still may be issues.
|
||||
*/
|
||||
if (buf) {
|
||||
strcpy(buf + curlen, toappend_str);
|
||||
return buf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strlib_free
|
||||
*
|
||||
* PARAMETERS: string_t : string to which reference is to be removed
|
||||
*
|
||||
* DESCRIPTION:It will remove the node containing the string from the linked
|
||||
* list if its refcount is 0 else it will decrement the refcount.
|
||||
*
|
||||
* RETURNS: none
|
||||
*
|
||||
*/
|
||||
void
|
||||
strlib_free (string_t str)
|
||||
{
|
||||
string_block_t *temp;
|
||||
|
||||
if ((!strlib_is_string(str)) || (str == empty_str)) {
|
||||
return;
|
||||
}
|
||||
|
||||
temp = STR_TO_STRUCT(str);
|
||||
temp->refcount--;
|
||||
if (temp->refcount == 0) {
|
||||
temp->signature = 0;
|
||||
cpr_free(temp);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strlib_open
|
||||
*
|
||||
* PARAMETERS: string_t : string to be modified
|
||||
* int : length of string to be modified
|
||||
*
|
||||
* DESCRIPTION:User will call open when he wants to modify the string. If
|
||||
* length of string after modification is going to be = < original string
|
||||
* return to him pointer to original string, else a new string is malloced
|
||||
* for user and a pointer to it is send to him.
|
||||
*
|
||||
* RETURNS: char* to modifiable string
|
||||
*
|
||||
*/
|
||||
char *
|
||||
strlib_open (string_t str, int length, const char *fname, int line)
|
||||
{
|
||||
char *ret_str;
|
||||
string_block_t *temp;
|
||||
|
||||
if (!strlib_is_string(str)) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
temp = STR_TO_STRUCT(str);
|
||||
|
||||
if ((temp->refcount == 1) && (length <= temp->length)) {
|
||||
ret_str = (char *) str;
|
||||
} else {
|
||||
ret_str = (char *) strlib_malloc(str, length, fname, line);
|
||||
if (!ret_str) {
|
||||
/*
|
||||
* If a malloc error occurred, give them back what they had.
|
||||
* It's not right, but it's better than nothing.
|
||||
*/
|
||||
ret_str = (char *) str;
|
||||
} else {
|
||||
strlib_free(str);
|
||||
}
|
||||
}
|
||||
|
||||
return (ret_str);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strlib_close
|
||||
*
|
||||
* PARAMETERS:char* : string to be made unmodifiable
|
||||
*
|
||||
* DESCRIPTION:Just returns const char* for the string, so that user
|
||||
* does not change it by mistake
|
||||
*
|
||||
* RETURNS:string_t: pointer to same string
|
||||
*
|
||||
*/
|
||||
string_t
|
||||
strlib_close (char *str)
|
||||
{
|
||||
if (!strlib_is_string(str)) {
|
||||
return (NULL);
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strlib_is_string
|
||||
*
|
||||
* PARAMETERS: string_t : string which is to be validated
|
||||
*
|
||||
* DESCRIPTION:Checks whether the signature for the provided string is valid
|
||||
*
|
||||
* RETURNS: static int
|
||||
*
|
||||
*/
|
||||
int
|
||||
strlib_is_string (string_t str)
|
||||
{
|
||||
string_block_t *temp;
|
||||
|
||||
if (str == NULL) {
|
||||
err_msg("Strlib Error: strlib_is_tring passed invalid string\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
temp = STR_TO_STRUCT(str);
|
||||
|
||||
if (temp->signature == STRING_SIGNATURE) {
|
||||
return (1);
|
||||
} else {
|
||||
err_msg("Strlib Error: strlib_is_tring passed invalid string\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
strlib_test_memory_is_string (void *mem)
|
||||
{
|
||||
string_block_t *temp;
|
||||
|
||||
if (!mem) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
temp = (string_block_t *) mem;
|
||||
if (temp->signature == STRING_SIGNATURE) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Function: strlib_empty
|
||||
*
|
||||
* PARAMETERS: None
|
||||
*
|
||||
* DESCRIPTION:strlib_empty will be called by user when he wants
|
||||
* to initialize his string to '/0' or "". It is not same as initializing
|
||||
* it to NULL. if(str) will evaluate to true if str = strlib_empty().
|
||||
* Correct way to check for empty string will be to do if (str[0] == '\0') or
|
||||
* if (str[0] == "")
|
||||
*
|
||||
* RETURNS: Pointer to empty_str
|
||||
*/
|
||||
string_t
|
||||
strlib_empty (void)
|
||||
{
|
||||
string_block_t *temp;
|
||||
static boolean empty_str_init = FALSE;
|
||||
|
||||
if (empty_str_init == FALSE) {
|
||||
empty_str = strlib_malloc("", LEN_UNKNOWN, __FILE__, __LINE__);
|
||||
temp = STR_TO_STRUCT(empty_str);
|
||||
temp->refcount = 0xffff;
|
||||
empty_str_init = TRUE;
|
||||
}
|
||||
return (empty_str);
|
||||
}
|
||||
|
||||
void
|
||||
strlib_init (void)
|
||||
{
|
||||
(void) strlib_empty(); // force it to allocate the empty string buffer
|
||||
}
|
||||
Reference in new issue
Block a user