Skip to content
Snippets Groups Projects
Commit 537069d3 authored by Jonathan Schöbel's avatar Jonathan Schöbel
Browse files

enlarge Text

The space a Text has for saving the string is allocated in chunks. To
request additional space SH_Text_enlarge is called. If the requestad
size fits inside the already allocated space or is even smaller than the
current size, nothing is done. Otherwise a multiple of chunk size is
allocated beeing equal or greater than the requested size. The chunk
size can be changed by changing the macro CHUNK_SIZE in src/text.h. The
default is 64.
This adjustment is done automatically when a string is added.
parent 252f968f
Branches
Tags
No related merge requests found
......@@ -28,34 +28,34 @@ long_line_behaviour=1
long_line_column=72
[files]
current_page=9
current_page=21
FILE_NAME_0=607;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8
FILE_NAME_1=395;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2FMakefile.am;0;8
FILE_NAME_2=847;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmain.c;0;8
FILE_NAME_3=1067;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fcms.c;0;8
FILE_NAME_4=1148;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fcms.h;0;8
FILE_NAME_5=4565;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.c;0;8
FILE_NAME_5=3598;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.c;0;8
FILE_NAME_6=1099;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fdata.h;0;8
FILE_NAME_7=1546;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.c;0;8
FILE_NAME_7=2130;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.c;0;8
FILE_NAME_8=876;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ffragment.h;0;8
FILE_NAME_9=0;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ftext.c;0;4
FILE_NAME_10=0;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ftext.h;0;4
FILE_NAME_11=2888;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fvalidator.c;0;8
FILE_NAME_9=2416;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ftext.c;0;8
FILE_NAME_10=896;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ftext.h;0;8
FILE_NAME_11=3294;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fvalidator.c;0;8
FILE_NAME_12=900;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fvalidator.h;0;8
FILE_NAME_13=994;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Ferror.h;0;4
FILE_NAME_14=881;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flog.h;0;4
FILE_NAME_15=869;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmacro.h;0;8
FILE_NAME_16=847;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fsefht.h;0;8
FILE_NAME_17=1025;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8
FILE_NAME_18=1253;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8
FILE_NAME_18=1113;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8
FILE_NAME_19=3059;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8
FILE_NAME_20=2908;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_fragment.c;0;8
FILE_NAME_21=0;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;4
FILE_NAME_22=3404;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
FILE_NAME_20=2736;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_fragment.c;0;8
FILE_NAME_21=1860;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
FILE_NAME_22=4613;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
FILE_NAME_23=55;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
[VTE]
last_dir=/home/jonathan/Dokumente/projekte/prgm/internet/web/SeFHT/src
last_dir=/home/jonathan/Dokumente/projekte/prgm/internet/web/SeFHT/tests
[prjorg]
source_patterns=*.c;*.C;*.cpp;*.cxx;*.c++;*.cc;*.m;
......
......@@ -15,3 +15,5 @@ sefht_fcgi_SOURCES += data.c data.h
sefht_fcgi_SOURCES += fragment.c fragment.h
sefht_fcgi_SOURCES += text.c text.h
sefht_fcgi_SOURCES += validator.c validator.h
sefht_fcgi_LDADD = -lm
......@@ -22,8 +22,14 @@
*/
#include <errno.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "macro.h"
#include "error.h"
#include "log.h"
......@@ -49,9 +55,22 @@ SH_Text_new (struct SH_Error * error)
}
text->length = 0;
text->size = 1;
text->text = malloc (1);
text->text = malloc (CHUNK_SIZE * sizeof (char));
if (text->text == NULL)
{
ERROR1 ("Memory allocation for SH_Text failed.\n");
if (error != NULL)
{
error->type = ALLOCATION_FAILED;
}
return NULL;
}
text->text[0] = 0;
text->size = CHUNK_SIZE;
if (error != NULL)
{
......@@ -75,3 +94,82 @@ SH_Text_free (struct SH_Text * text, struct SH_Error * error)
return;
}
bool
SH_Text_enlarge (struct SH_Text * text, size_t size,
struct SH_Error * error)
{
size_t new_size;
if (size <= text->size)
{
if (error != NULL)
{
error->type = SUCCESS;
}
return TRUE;
}
/* if both operands were integers,
* this operation would fail
* as the division will behave like
* calling floor in the first place. */
new_size = ceilf (size / (float) CHUNK_SIZE);
if (new_size >= (SIZE_MAX / (float) CHUNK_SIZE))
{
ERROR1 ("Maximum length of SH_Text reached.\n");
if (error != NULL)
{
error->type = DOMAIN_ERROR;
}
return FALSE;
}
new_size *= CHUNK_SIZE;
text->text = realloc (text->text, new_size * sizeof (char));
if (errno == ENOMEM)
{
ERROR1 ("Memory allocation for SH_Text data failed.\n");
if (error != NULL)
{
error->type = ALLOCATION_FAILED;
}
return FALSE;
}
text->size = new_size;
if (error != NULL)
{
error->type = SUCCESS;
}
return TRUE;
};
bool
SH_Text_append_string (struct SH_Text * text, char * string,
struct SH_Error * error)
{
unsigned int length;
length = strlen (string);
if (!SH_Text_enlarge (text, text->length + length + 1, error))
{
return FALSE;
}
text->text = strcat (text->text, string);
/* this is save as text->size is always at least one greater
* and SH_Text_enlarge hasn't failed. */
text->length += length;
return TRUE;
}
......@@ -25,18 +25,26 @@
#ifndef _TEXT_H
#define _TEXT_H
#include <stdbool.h>
#include "error.h"
#define CHUNK_SIZE 64
struct SH_Text
{
unsigned int length;
unsigned int size;
size_t length;
size_t size;
char * text;
};
struct SH_Text * SH_Text_new (struct SH_Error * error);
void SH_Text_free (struct SH_Text * text, struct SH_Error * error);
bool SH_Text_enlarge (struct SH_Text * text, size_t size,
struct SH_Error * error);
bool SH_Text_append_string (struct SH_Text * text, char * string,
struct SH_Error * error);
#endif /* _TEXT_H */
......@@ -23,9 +23,13 @@
#include <check.h>
#include <limits.h>
#include <stdbool.h>
#include <stdlib.h>
#include "macro.h"
#include "error.h"
#include "text.h"
......@@ -37,6 +41,8 @@ START_TEST(test_text)
text = SH_Text_new (NULL);
ck_assert_int_ne ((long int) text, (long int) NULL);
ck_assert_int_ge (text->size, CHUNK_SIZE);
SH_Text_free (text, NULL);
error.type = UNDEFINED;
......@@ -44,12 +50,100 @@ START_TEST(test_text)
ck_assert_int_ne ((long int) text, (long int) NULL);
ck_assert_int_eq (error.type, SUCCESS);
ck_assert_int_ge (text->size, CHUNK_SIZE);
error.type = UNDEFINED;
SH_Text_free (text, &error);
ck_assert_int_eq (error.type, SUCCESS);
}
END_TEST
START_TEST(test_text_enlarge)
{
struct SH_Error error;
struct SH_Text * text;
bool result;
size_t size1;
size_t size2;
size_t size2_;
size_t size3;
size1 = CHUNK_SIZE;
size2 = CHUNK_SIZE + 1;
size2_ = 2 * CHUNK_SIZE;
if (SIZE_MAX % CHUNK_SIZE == 0)
{
size3 = ((SIZE_MAX / CHUNK_SIZE) - 1) * CHUNK_SIZE;
}
else
{
size3 = (SIZE_MAX / CHUNK_SIZE) * CHUNK_SIZE;
}
text = SH_Text_new (NULL);
/* size == current size */
result = SH_Text_enlarge (text, size1, NULL);
ck_assert_int_eq (result, TRUE);
ck_assert_int_eq (text->size, size1);
/* size > current size */
result = SH_Text_enlarge (text, size2, NULL);
ck_assert_int_eq (result, TRUE);
ck_assert_int_eq (text->size, size2_);
/* size < current size */
result = SH_Text_enlarge (text, size1, NULL);
ck_assert_int_eq (result, TRUE);
ck_assert_int_eq (text->size, size2_);
/* size throw overflow */
result = SH_Text_enlarge (text, size3, NULL);
ck_assert_int_eq (result, FALSE);
SH_Text_free (text, NULL);
text = SH_Text_new (NULL);
/* size == current size */
error.type = UNDEFINED;
result = SH_Text_enlarge (text, size1, &error);
ck_assert_int_eq (result, TRUE);
ck_assert_int_eq (error.type, SUCCESS);
ck_assert_int_eq (text->size, size1);
/* size > current size */
error.type = UNDEFINED;
result = SH_Text_enlarge (text, size2, &error);
ck_assert_int_eq (result, TRUE);
ck_assert_int_eq (error.type, SUCCESS);
ck_assert_int_eq (text->size, size2_);
/* size < current size */
error.type = UNDEFINED;
result = SH_Text_enlarge (text, size1, &error);
ck_assert_int_eq (result, TRUE);
ck_assert_int_eq (error.type, SUCCESS);
ck_assert_int_eq (text->size, size2_);
/* size throw overflow */
error.type = UNDEFINED;
result = SH_Text_enlarge (text, size3, &error);
ck_assert_int_eq (result, FALSE);
ck_assert_int_eq (error.type, DOMAIN_ERROR);
SH_Text_free (text, NULL);
}
END_TEST
Suite * text_suite (void)
{
Suite *s;
......@@ -61,6 +155,7 @@ Suite * text_suite (void)
tc_core = tcase_create ("Core");
tcase_add_test (tc_core, test_text);
tcase_add_test (tc_core, test_text_enlarge);
suite_add_tcase (s, tc_core);
return s;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment