Browse Source

added a polymorphic clear method, give messages if an assertion in an test fails

master
Georg Hopp 14 years ago
parent
commit
e569955ca6
  1. 12
      include/token/cclass.h
  2. 19
      include/token/dyntype.h
  3. 13
      src/cclass.c
  4. 1
      src/crypt.c
  5. 80
      src/dyntype.c
  6. 7
      src/dyntype/hash.c
  7. 32
      src/packet.c
  8. 1
      tests/cclassTest.c
  9. 1
      tests/cryptTest.c
  10. 2
      tests/mock/class.c
  11. 49
      tests/packetTest.c
  12. 2
      tests/runtest.c
  13. 60
      tests/runtest.h

12
include/token/cclass.h

@ -32,33 +32,33 @@
extern const _CCLASS const __##_class; \ extern const _CCLASS const __##_class; \
struct _##_class struct _##_class
#define ENDC(_class) } * _class; \
extern const _CCLASS const __##_class;
typedef void (* ctor)(void *, va_list *); typedef void (* ctor)(void *, va_list *);
typedef void (* clr)(void *);
typedef void (* dtor)(void *); typedef void (* dtor)(void *);
typedef void (* jCtor)(void *, struct json_object *); typedef void (* jCtor)(void *, struct json_object *);
typedef void (* jTo)(void *, struct json_object **); typedef void (* jTo)(void *, struct json_object **);
typedef struct CCLASS { typedef struct CCLASS {
const int magic; const int magic;
size_t size; size_t size;
void (* __construct)(void * _this, va_list * params); void (* __construct)(void * _this, va_list * params);
void (* __clear)(void * _this);
void (* __destruct)(void * _this); void (* __destruct)(void * _this);
void (* __jsonConst)(void * _this, struct json_object * json); void (* __jsonConst)(void * _this, struct json_object * json);
void (* __toJson)(void * _this, struct json_object ** json); void (* __toJson)(void * _this, struct json_object ** json);
} * _CCLASS; } * _CCLASS;
#define CCLASS_PTR_SIZE sizeof(struct CCLASS *)
#define _CCLASS_SIZE sizeof(_CCLASS)
#define CCLASS_SIZE sizeof(struct CCLASS) #define CCLASS_SIZE sizeof(struct CCLASS)
#define __construct(class) static void __construct(class _this, va_list * params) #define __construct(class) static void __construct(class _this, va_list * params)
#define __clear(class) static void __clear(class _this)
#define __destruct(class) static void __destruct(class _this) #define __destruct(class) static void __destruct(class _this)
#define __jsonConst(class) static void __jsonConst(class _this, struct json_object * json) #define __jsonConst(class) static void __jsonConst(class _this, struct json_object * json)
#define __toJson(class) static void __toJson(class _this, struct json_object ** json) #define __toJson(class) static void __toJson(class _this, struct json_object ** json)
#define INIT_CCLASS(class) \ #define INIT_CCLASS(class) \
__construct(class); \ __construct(class); \
__clear(class); \
__destruct(class); \ __destruct(class); \
__jsonConst(class); \ __jsonConst(class); \
__toJson(class); \ __toJson(class); \
@ -66,6 +66,7 @@ typedef struct CCLASS {
CCLASS_MAGIC, \ CCLASS_MAGIC, \
sizeof(struct _##class), \ sizeof(struct _##class), \
(ctor)__construct, \ (ctor)__construct, \
(clr)__clear, \
(dtor)__destruct, \ (dtor)__destruct, \
(jCtor)__jsonConst, \ (jCtor)__jsonConst, \
(jTo)__toJson \ (jTo)__toJson \
@ -73,6 +74,7 @@ typedef struct CCLASS {
void * _new(const _CCLASS _class, ...); void * _new(const _CCLASS _class, ...);
void * _newFromJson(const _CCLASS _class, struct json_object * json); void * _newFromJson(const _CCLASS _class, struct json_object * json);
void clear(void * _object);
void delete(void * _object); void delete(void * _object);
void toJson(void * _object, struct json_object ** json); void toJson(void * _object, struct json_object ** json);
int isObject(void * _object); int isObject(void * _object);

19
include/token/dyntype.h

@ -40,11 +40,10 @@ enum DYNTYPE_TYPES {
CLASS(DYNTYPE) { CLASS(DYNTYPE) {
const _CCLASS const class; const _CCLASS const class;
enum DYNTYPE_TYPES type; enum DYNTYPE_TYPES type;
size_t size;
union _data { union _data {
unsigned char _boolean; unsigned char _boolean;
int _int; int _int;
double _float;
double _double;
char * _string; char * _string;
struct _DYNTYPE ** _array; struct _DYNTYPE ** _array;
DYNTYPE_HASH _hash; DYNTYPE_HASH _hash;
@ -53,6 +52,22 @@ CLASS(DYNTYPE) {
#include "token/dyntype/hash.h" #include "token/dyntype/hash.h"
#define dyntype_newBoolean(value) new(DYNTYPE, DYNTYPE_TYPE_BOOLEAN, value)
#define dyntype_newInt(value) new(DYNTYPE, DYNTYPE_TYPE_INT, value)
#define dyntype_newDouble(value) new(DYNTYPE, DYNTYPE_TYPE_DOUBLE, value)
#define dyntype_newString(value) new(DYNTYPE, DYNTYPE_TYPE_STRING, value)
#define dyntype_newArray(value) new(DYNTYPE, DYNTYPE_TYPE_ARRAY, value)
#define dyntype_newHash(value) new(DYNTYPE, DYNTYPE_TYPE_HASH, value)
enum DYNTYPE_TYPES dyntype_getType(DYNTYPE _this);
size_t dyntype_getSize(DYNTYPE _this);
unsigned char dyntype_getBoolean(DYNTYPE _this);
int dyntype_getInt(DYNTYPE _this);
double dyntype_getDouble(DYNTYPE _this);
char * dyntype_getString(DYNTYPE _this);
DYNTYPE * dyntype_getArray(DYNTYPE _this);
DYNTYPE_HASH dyntype_getHash(DYNTYPE _this);
#endif//__DYNTYPE_H__ #endif//__DYNTYPE_H__
// vim: set et ts=4 sw=4: // vim: set et ts=4 sw=4:

13
src/cclass.c

@ -23,6 +23,7 @@
#include "token/cclass.h" #include "token/cclass.h"
#undef __construct #undef __construct
#undef __clear
#undef __destruct #undef __destruct
#undef __jsonConst #undef __jsonConst
#undef __toJson #undef __toJson
@ -61,6 +62,16 @@ _newFromJson(const _CCLASS _class, struct json_object * json)
return object; return object;
} }
void
clear(void * _object)
{
const struct CCLASS ** class = _object;
if (_object && *class && (*class)->__clear) {
(*class)->__clear(_object);
}
}
void void
delete(void * _object) delete(void * _object)
{ {
@ -97,7 +108,7 @@ _instanceOf(const _CCLASS _class, void * _object)
{ {
const struct CCLASS ** class = _object; const struct CCLASS ** class = _object;
return (_class == *class);
return (class && _class == *class);
} }
// vim: set et ts=4 sw=4: // vim: set et ts=4 sw=4:

1
src/crypt.c

@ -56,6 +56,7 @@ __destruct(CRYPT)
__jsonConst(CRYPT) {} __jsonConst(CRYPT) {}
__toJson(CRYPT) {} __toJson(CRYPT) {}
__clear(CRYPT) {}
void * void *
crypt_createIv(CRYPT _this) crypt_createIv(CRYPT _this)

80
src/dyntype.c

@ -23,13 +23,22 @@
#include "token/dyntype.h" #include "token/dyntype.h"
#include "token/dyntype/hash.h" #include "token/dyntype/hash.h"
static
size_t _dyntype_sizes[] = {
0,
sizeof(unsigned char),
sizeof(int),
sizeof(double),
sizeof(char *),
sizeof(DYNTYPE *),
sizeof(DYNTYPE_HASH)
};
INIT_CCLASS(DYNTYPE); INIT_CCLASS(DYNTYPE);
__construct(DYNTYPE) __construct(DYNTYPE)
{ {
_this->type = va_arg(* params, enum DYNTYPE_TYPES); _this->type = va_arg(* params, enum DYNTYPE_TYPES);
_this->size = va_arg(* params, size_t);
switch(_this->type) { switch(_this->type) {
case DYNTYPE_TYPE_INT: case DYNTYPE_TYPE_INT:
@ -37,8 +46,13 @@ __construct(DYNTYPE)
break; break;
case DYNTYPE_TYPE_STRING: case DYNTYPE_TYPE_STRING:
(_this->data)._string = calloc(_this->size + 1, sizeof(char));
memcpy((_this->data)._string, va_arg(* params, const char *), _this->size);
{
const char * string = va_arg(* params, const char *);
const size_t length = strlen(string);
(_this->data)._string = calloc(length + 1, sizeof(char));
memcpy((_this->data)._string, string, length);
}
break; break;
case DYNTYPE_TYPE_HASH: case DYNTYPE_TYPE_HASH:
@ -55,35 +69,34 @@ __jsonConst(DYNTYPE)
switch (json_object_get_type(json)) { switch (json_object_get_type(json)) {
case json_type_int: case json_type_int:
_this->type = DYNTYPE_TYPE_INT; _this->type = DYNTYPE_TYPE_INT;
_this->size = sizeof(int);
(_this->data)._int = (int)json_object_get_int(json); (_this->data)._int = (int)json_object_get_int(json);
break; break;
case json_type_string: case json_type_string:
{ {
const char * string = json_object_get_string(json); const char * string = json_object_get_string(json);
const size_t length = strlen(string);
_this->type = DYNTYPE_TYPE_STRING; _this->type = DYNTYPE_TYPE_STRING;
_this->size = strlen(string);
(_this->data)._string = calloc(_this->size + 1, sizeof(char));
memcpy((_this->data)._string, string, _this->size);
(_this->data)._string = calloc(length + 1, sizeof(char));
memcpy((_this->data)._string, string, length);
// the json object handles the memory for string.... // the json object handles the memory for string....
} }
break; break;
case json_type_object: case json_type_object:
_this->type = DYNTYPE_TYPE_HASH; _this->type = DYNTYPE_TYPE_HASH;
_this->size = sizeof(DYNTYPE_HASH);
(_this->data)._hash = newFromJson(DYNTYPE_HASH, json); (_this->data)._hash = newFromJson(DYNTYPE_HASH, json);
break; break;
default: default:
_this->type = DYNTYPE_TYPE_NULL; _this->type = DYNTYPE_TYPE_NULL;
_this->size = 0;
(_this->data)._hash = NULL; (_this->data)._hash = NULL;
} }
} }
__clear(DYNTYPE) {}
__destruct(DYNTYPE) __destruct(DYNTYPE)
{ {
if (_this) { if (_this) {
@ -122,4 +135,53 @@ __toJson(DYNTYPE)
} }
} }
enum DYNTYPE_TYPES
dyntype_getType(DYNTYPE _this)
{
return _this->type;
}
size_t
dyntype_getSize(DYNTYPE _this)
{
return _dyntype_sizes[_this->type];
}
unsigned char
dyntype_getBoolean(DYNTYPE _this)
{
return (_this->data)._boolean;
}
int
dyntype_getInt(DYNTYPE _this)
{
return (_this->data)._int;
}
double
dyntype_getDouble(DYNTYPE _this)
{
return (_this->data)._double;
}
char *
dyntype_getString(DYNTYPE _this)
{
return (_this->data)._string;
}
DYNTYPE *
dyntype_getArray(DYNTYPE _this)
{
return (_this->data)._array;
}
DYNTYPE_HASH
dyntype_getHash(DYNTYPE _this)
{
return (_this->data)._hash;
}
// vim: set et ts=4 sw=4: // vim: set et ts=4 sw=4:

7
src/dyntype/hash.c

@ -37,6 +37,7 @@ __construct(DYNTYPE_HASH)
_this->used = 0; _this->used = 0;
_updateHashSize(_this); _updateHashSize(_this);
} }
#undef __construct #undef __construct
__jsonConst(DYNTYPE_HASH) __jsonConst(DYNTYPE_HASH)
@ -52,16 +53,22 @@ __jsonConst(DYNTYPE_HASH)
} }
} }
__clear(DYNTYPE_HASH) {}
__destruct(DYNTYPE_HASH) __destruct(DYNTYPE_HASH)
{ {
size_t index; size_t index;
for (index = 0; index < _this->used; index ++) { for (index = 0; index < _this->used; index ++) {
free(_this->keys[index]); free(_this->keys[index]);
delete(_this->values[index]);
} }
free(_this->keys); free(_this->keys);
free(_this->values); free(_this->values);
_this->size = _this->used = 0;
_updateHashSize(_this);
} }
__toJson(DYNTYPE_HASH) __toJson(DYNTYPE_HASH)

32
src/packet.c

@ -24,7 +24,23 @@ INIT_CCLASS(PACKET);
__construct(PACKET) __construct(PACKET)
{ {
DYNTYPE header = va_arg(* params, DYNTYPE);
DYNTYPE data = NULL;
if (instanceOf(DYNTYPE, header)) {
data = va_arg(* params, DYNTYPE);
}
if (instanceOf(DYNTYPE, data)) {
packet_setHeader(_this, header);
packet_setData(_this, data);
} else {
packet_set_default_content(_this); packet_set_default_content(_this);
}
} }
__jsonConst(PACKET) __jsonConst(PACKET)
@ -49,7 +65,21 @@ __jsonConst(PACKET)
packet_setData(_this, newFromJson(DYNTYPE, data)); packet_setData(_this, newFromJson(DYNTYPE, data));
} }
__destruct(PACKET) {}
__clear(PACKET) {}
__destruct(PACKET)
{
DYNTYPE header = packet_getHeader(_this);
DYNTYPE data = packet_getData(_this);
if (NULL != header) {
delete(&header);
}
if (NULL != data) {
delete(&data);
}
}
__toJson(PACKET) __toJson(PACKET)
{ {

1
tests/cclassTest.c

@ -1,3 +1,4 @@
#include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#include <json/json.h> #include <json/json.h>

1
tests/cryptTest.c

@ -1,3 +1,4 @@
#include <stdio.h>
#include <mcrypt.h> #include <mcrypt.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>

2
tests/mock/class.c

@ -22,6 +22,8 @@ __jsonConst(MOCK_CLASS)
_this->value = json_object_get_int(json); _this->value = json_object_get_int(json);
} }
__clear(MOCK_CLASS) {}
__destruct(MOCK_CLASS) __destruct(MOCK_CLASS)
{ {
_called = 1; _called = 1;

49
tests/packetTest.c

@ -1,3 +1,5 @@
#include <stdio.h>
#include "runtest.h" #include "runtest.h"
#include "token/cclass.h" #include "token/cclass.h"
#include "token/packet.h" #include "token/packet.h"
@ -36,14 +38,59 @@ static
int int
testDefaultInit() testDefaultInit()
{ {
ASSERT_INSTANCE_OF(PACKET, packet);
ASSERT_NULL(packet_getHeader(packet)); ASSERT_NULL(packet_getHeader(packet));
ASSERT_NULL(packet_getData(packet)); ASSERT_NULL(packet_getData(packet));
return TEST_OK; return TEST_OK;
} }
static
int
testParamInit1()
{
__tearDown();
DYNTYPE header = dyntype_newInt(123);
packet = new(PACKET, header, NULL);
ASSERT_INSTANCE_OF(PACKET, packet);
ASSERT_NULL(packet_getHeader(packet));
ASSERT_NULL(packet_getData(packet));
delete(&header);
return TEST_OK;
}
static
int
testParamInit2()
{
DYNTYPE header, data;
__tearDown();
packet = new(PACKET, dyntype_newInt(123), dyntype_newInt(321));
ASSERT_INSTANCE_OF(PACKET, packet);
header = packet_getHeader(packet);
data = packet_getData(packet);
ASSERT_INSTANCE_OF(DYNTYPE, header);
ASSERT_INSTANCE_OF(DYNTYPE, data);
ASSERT_EQUAL(123, dyntype_getInt(header));
ASSERT_EQUAL(321, dyntype_getInt(data));
return TEST_OK;
}
const testfunc tests[] = { const testfunc tests[] = {
testDefaultInit
testDefaultInit,
testParamInit1,
testParamInit2
}; };
const size_t count = FUNCS_COUNT(tests); const size_t count = FUNCS_COUNT(tests);

2
tests/runtest.c

@ -24,7 +24,7 @@ isObjectNull(void * _object)
const struct CCLASS ** class = _object; const struct CCLASS ** class = _object;
ASSERT_OBJECT(_object); ASSERT_OBJECT(_object);
ASSERT_MEM_NULL(_object + CCLASS_PTR_SIZE, (*class)->size - CCLASS_PTR_SIZE);
ASSERT_MEM_NULL(_object + _CCLASS_SIZE, (*class)->size - _CCLASS_SIZE);
return TEST_OK; return TEST_OK;
} }

60
tests/runtest.h

@ -11,26 +11,68 @@ enum RESULT_TYPES {
TEST_ERROR TEST_ERROR
}; };
#define ASSERT_NULL(value) if (NULL != (value)) return TEST_FAILED
#define ASSERT_NOT_NULL(value) if (NULL == (value)) return TEST_FAILED
#define ASSERT_EQUAL(val1,val2) if ((val1) != (val2)) return TEST_FAILED
#define ASSERT_NOT_EQUAL(val1,val2) if ((val1) == (val2)) return TEST_FAILED
#define ASSERT_NULL(value) \
if (NULL != (value)) { \
printf("%s[%d]: Assertion failed that %s is NULL\n", \
__FILE__, __LINE__, #value); \
return TEST_FAILED; }
#define ASSERT_NOT_NULL(value) \
if (NULL == (value)) { \
printf("%s[%d]: Assertion failed that %s is NOT NULL\n", \
__FILE__, __LINE__, #value); \
return TEST_FAILED; }
#define ASSERT_EQUAL(val1,val2) \
if ((val1) != (val2)) { \
printf("%s[%d]: Assertion failed that %s equals %s\n", \
__FILE__, __LINE__, #val1, #val2); \
return TEST_FAILED; }
#define ASSERT_NOT_EQUAL(val1,val2) \
if ((val1) == (val2)) { \
printf("%s[%d]: Assertion failed that %s not equals %2\n", \
__FILE__, __LINE__, #val1, #val2); \
return TEST_FAILED; }
#define ASSERT_MEM_EQUAL(val1,val2,size) \ #define ASSERT_MEM_EQUAL(val1,val2,size) \
if(0 != memcmp((val1), (val2), (size))) return TEST_FAILED
if(0 != memcmp((val1), (val2), (size))) { \
printf("%s[%d]: Assertion failed that memory at %s equals %s for %lu bytes\n", \
__FILE__, __LINE__, #val1, #val2, size); \
return TEST_FAILED; }
#define ASSERT_MEM_NOT_EQUAL(val1,val2,size) \ #define ASSERT_MEM_NOT_EQUAL(val1,val2,size) \
if(0 == memcmp((val1), (val2), (size))) return TEST_FAILED
#define ASSERT_MEM_NULL(val, size) if (! isMemNull((val), (size))) return TEST_FAILED
if(0 == memcmp((val1), (val2), (size))) { \
printf("%s[%d]: Assertion failed that memory at %s not equals %s for %lu bytes\n", \
__FILE__, __LINE__, #val1, #val2, size); \
return TEST_FAILED; }
#define ASSERT_MEM_NULL(val, size) \
if (! isMemNull((val), (size))) { \
printf("%s[%d]: Assertion failed that memory at %s is NULL for %lu bytes\n", \
__FILE__, __LINE__, #val, size); \
return TEST_FAILED; }
#define ASSERT_MEM_NOT_NULL(val, size) \ #define ASSERT_MEM_NOT_NULL(val, size) \
if (isMemNull((val), (size))) return TEST_FAILED
if (isMemNull((val), (size))) { \
printf("%s[%d]: Assertion failed that memory at %s is NOT NULL for %lu bytes\n", \
__FILE__, __LINE__, #val, size); \
return TEST_FAILED; }
#define ASSERT_STRING_EQUAL(val1,val2) \ #define ASSERT_STRING_EQUAL(val1,val2) \
if(0 != strcmp((val1), (val2))) return TEST_FAILED if(0 != strcmp((val1), (val2))) return TEST_FAILED
#define ASSERT_STRING_NOT_EQUAL(val1,val2) \ #define ASSERT_STRING_NOT_EQUAL(val1,val2) \
if(0 == strcmp((val1), (val2))) return TEST_FAILED if(0 == strcmp((val1), (val2))) return TEST_FAILED
#define ASSERT_OBJECT(val) if (! isObject((val))) return TEST_FAILED #define ASSERT_OBJECT(val) if (! isObject((val))) return TEST_FAILED
#define ASSERT_OBJECT_NULL(val) if (! isObjectNull((val))) return TEST_FAILED #define ASSERT_OBJECT_NULL(val) if (! isObjectNull((val))) return TEST_FAILED
#define ASSERT_OBJECT_NOT_NULL(val) if (isObjectNull((val))) return TEST_FAILED #define ASSERT_OBJECT_NOT_NULL(val) if (isObjectNull((val))) return TEST_FAILED
#define ASSERT_INSTANCE_OF(class, val) \ #define ASSERT_INSTANCE_OF(class, val) \
if (! instanceOf(class, val)) return TEST_FAILED
if (! instanceOf(class, val)) { \
printf("%s[%d]: Assertion failed that %s is instance of %s\n", \
__FILE__, __LINE__, #val, #class); \
return TEST_FAILED; }
typedef int (* const testfunc)(void); typedef int (* const testfunc)(void);

Loading…
Cancel
Save