Merge branch 'herbglitch/config' into 'master'

Herbglitch/config

See merge request Archeus_00/arc!4
This commit is contained in:
herbglitch 2023-01-21 23:59:58 +00:00
commit 774393cba3
27 changed files with 2066 additions and 960 deletions

View file

@ -0,0 +1,37 @@
#ifndef ARC_ENGINE_ECS_H_
#define ARC_ENGINE_ECS_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "arc/std/vector.h"
#include <stdint.h>
/**
* @brief a type that keeps permanice of data for when loading and unloading config files
*/
typedef struct ARC_ECS ARC_ECS;
/**
* @brief entity type for ARC_ECS
*/
typedef uint64_t ARC_ECSEntity;
/**
* @brief creates ARC_Config type
*
* @param ecs ARC_ECS
*/
void ARC_ECS_Create(ARC_ECS **ecs);
/**
* @brief destroys ARC_ECS type
*/
void ARC_ECS_Destroy(ARC_ECS *ecs);
#ifdef __cplusplus
}
#endif
#endif //ARC_ENGINE_ECS_H_

View file

@ -26,7 +26,7 @@ typedef struct ARC_EngineData {
//NOTE: most work below is temp, and will change once I figure out a better way to write this header //NOTE: most work below is temp, and will change once I figure out a better way to write this header
void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanfn); void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanfn, ARC_Point windowSize);
void ARC_EngineData_Destroy(ARC_EngineData *data); void ARC_EngineData_Destroy(ARC_EngineData *data);

View file

@ -0,0 +1,19 @@
#ifndef ARC_GRAPHICS_COLOR_H_
#define ARC_GRAPHICS_COLOR_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
typedef struct ARC_Color {
uint8_t r, g, b, a;
} ARC_Color;
#ifdef __cplusplus
}
#endif
#endif // !ARC_GRAPHICS_COLOR_H_

View file

@ -0,0 +1,19 @@
#ifndef ARC_GRAPHICS_LINE_H_
#define ARC_GRAPHICS_LINE_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "arc/graphics/color.h"
#include "arc/graphics/renderer.h"
#include "arc/math/rectangle.h"
#include <stdint.h>
void ARC_Line_Render(int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2, ARC_Renderer *renderer, ARC_Color *color);
#ifdef __cplusplus
}
#endif
#endif // !ARC_GRAPHICS_LINE_H_

View file

@ -0,0 +1,19 @@
#ifndef ARC_GRAPHICS_RECT_H_
#define ARC_GRAPHICS_RECT_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "arc/graphics/color.h"
#include "arc/graphics/renderer.h"
#include "arc/math/rectangle.h"
#include <stdint.h>
void ARC_Rect_Render(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color);
#ifdef __cplusplus
}
#endif
#endif // !ARC_GRAPHICS_RECT_H_

View file

@ -8,8 +8,7 @@
struct ARC_Sprite { struct ARC_Sprite {
ARC_Spritesheet *spritesheet; ARC_Spritesheet *spritesheet;
ARC_Rect *frames; ARC_Array *frames;
uint32_t *frameSize;
uint32_t *frameIndex; uint32_t *frameIndex;
}; };

View file

@ -7,18 +7,73 @@ extern "C" {
#include "arc/graphics/renderer.h" #include "arc/graphics/renderer.h"
#include "arc/graphics/spritesheet.h" #include "arc/graphics/spritesheet.h"
#include "arc/math/point.h"
#include "arc/math/rectangle.h" #include "arc/math/rectangle.h"
#include "arc/std/array.h"
/**
* @brief a sprite type
*
* @note the actual type should be define by overriding for a graphics api
*/
typedef struct ARC_Sprite ARC_Sprite; typedef struct ARC_Sprite ARC_Sprite;
void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Rect *bounds); /**
* @brief creates ARC_Sprite type
*
* @param sprite ARC_Sprite that is being created
* @param spritesheet ARC_Spritesheet that ARC_Sprite will be pulled from
* @param bounds ARC_Array of bounds of sprite on spritesheet
*/
void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *bounds);
/**
* @brief destroys ARC_Sprite type
*
* @param sprite ARC_Sprite to destroy
*/
void ARC_Sprite_Destroy(ARC_Sprite *sprite); void ARC_Sprite_Destroy(ARC_Sprite *sprite);
/**
* @brief copies ARC_Sprite to a new ARC_Sprite
*
* @param newSprite ARC_Sprite that is being copied to and created
* @param oldSprite ARC_Sprite contents that are being copied
*/
void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite);
/**
* @brief renders ARC_Sprite type
*
* @param sprite ARC_Sprite that will be rendered
* @param renderer ARC_Renderer that is handling rendering
* @param renderBounds area of renderer that ARC_Sprite will be rendered to
*/
void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds); void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds);
/**
* @brief renders ARC_Sprite type with rotation
*
* @param sprite ARC_Sprite that will be rendered
* @param renderer ARC_Renderer that is handling rendering
* @param renderBounds area of renderer that ARC_Sprite will be rendered to
* @param angle angle to rotate ARC_Sprite
* @param center point to rotate ARC_Sprite around
*/
void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle);
/**
* @brief switches ARC_Sprite's frames to next for animation
*
* @param sprite ARC_Sprite that is having its frame updated
*/
void ARC_Sprite_IterateFrame(ARC_Sprite *sprite); void ARC_Sprite_IterateFrame(ARC_Sprite *sprite);
/**
* @brief returns the current bounds based on the ARC_Sprite's frames
*
* @param sprite ARC_Sprite to get bounds from
*/
ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite); ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite);
#ifdef __cplusplus #ifdef __cplusplus

View file

@ -11,4 +11,8 @@ typedef struct ARC_UPoint {
uint32_t x, y; uint32_t x, y;
} ARC_UPoint; } ARC_UPoint;
typedef struct ARC_FPoint {
float x, y;
} ARC_FPoint;
#endif // ARC_MATH_POINT_H_ #endif // ARC_MATH_POINT_H_

View file

@ -17,4 +17,8 @@ typedef struct ARC_URect {
uint32_t h; uint32_t h;
} ARC_URect; } ARC_URect;
int32_t ARC_Rect_Intersects(ARC_Rect *rect1, ARC_Rect *rect2);
int32_t ARC_Rect_LineIntersects(ARC_Rect *rect, int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2);
#endif // ARC_MATH_POINT_H_ #endif // ARC_MATH_POINT_H_

14
include/arc/std/array.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef ARC_STD_ARRAY_H_
#define ARC_STD_ARRAY_H_
#include <stdint.h>
/**
* @brief a type that holds an array of data and its size
*/
typedef struct ARC_Array {
uint32_t *size;
void *data;
} ARC_Array;
#endif //ARC_STD_ARRAY_H_

View file

@ -9,10 +9,6 @@ extern "C" {
#include "arc/std/string.h" #include "arc/std/string.h"
#include <stdint.h> #include <stdint.h>
#ifndef ARC_HOME_PATH
#define ARC_HOME_PATH "./res/"
#endif //ARC_HOME_PATH
#define ARC_KEY_BUCKET_SIZE 0x20 #define ARC_KEY_BUCKET_SIZE 0x20
#define ARC_GROUP_BUCKET_SIZE 0x20 #define ARC_GROUP_BUCKET_SIZE 0x20
#define ARC_GROUP_DATA_BUCKET_SIZE 0x20 #define ARC_GROUP_DATA_BUCKET_SIZE 0x20
@ -26,55 +22,84 @@ typedef struct ARC_Config ARC_Config;
* @brief a function to read a key from string to a ARC_ConfigTypeTemplate * @brief a function to read a key from string to a ARC_ConfigTypeTemplate
* *
* @param config ARC_Config to store data to * @param config ARC_Config to store data to
* @param data string of what is to be read in * @param string ARC_String of data that is being read in
* @param subdata location of stubstring in data for what is to be read in * @param value value that is read in
* @param value value of read in variable *
* @note use ARC_Config_StoreValue(ARC_Config *config, ARC_String *name, void *value); to store a value to the config
* if there is an error, set arc_errno
*
* @return 0 if value not a reference, 1 if value is a reference
*/ */
typedef int32_t (* ARC_ConfigKeyRead)(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); typedef uint8_t (* ARC_ConfigKeyRead)(ARC_Config* config, ARC_String *string, void **value);
/** /**
* @brief a function to delete a value from a key in ARC_Config * @brief a function to delete a value from a key in ARC_Config
* *
* @param config ARC_Config that can be used to check for references in data * @param config ARC_Config that can be used to check for references in data
* @param data string of what is going to be deleted (used to check if value is a reference)
* @param subdata location of substring in data for what is going to be deleted (used to check if value is a reference)
* @param value pointer of data to be deleted * @param value pointer of data to be deleted
*
* @note this function can be NULL if memory does not need to be cleaned for this type
* if there is an error, set arc_errno
*/ */
typedef int32_t (* ARC_ConfigKeyDelete)(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); typedef void (* ARC_ConfigKeyDelete)(ARC_Config* config, ARC_String *string, void *value);
/** /**
* @brief adds a usable key to ARC_Config * @brief adds a usable key to ARC_Config
* *
* @param config ARC_Config we are adding keys to * @param config ARC_Config to add keys to
* @param type string of key type * @param type string of key type
* @param keyRead function for reading/creating key from string * @param keyRead function for reading/creating key from string
* @param keyDelete function for deleting stored key * @param keyDelete function for deleting stored key
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
int32_t ARC_ConfigKey_Add(ARC_Config *config, char *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete); void ARC_Config_AddKey(ARC_Config *config, ARC_String *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete);
/**
* @brief adds a key from a cstring
* @param config ARC_Config to add keys to
* @param type cstring of key type
* @param length length of cstring
* @param keyRead function for reading/creating key from string
* @param keyDelete function for deleting stored key
*/
void ARC_Config_AddKeyCString(ARC_Config *config, const char *type, uint64_t length, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete);
/** /**
* @brief external callback to add keys to config * @brief external callback to add keys to config
*/ */
typedef int32_t (* ARC_ConfigKey_AddFunc)(ARC_Config *config); typedef void (* ARC_ConfigKey_AddFunc)(ARC_Config *config);
/** /**
* @brief creates ARC_Config type * @brief creates ARC_Config type
* *
* @param config ARC_Config we are initializing * @param config ARC_Config to initialize
* @param keysAdd callback to add ConfigKeys to config->keys, can be NULL
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
int32_t ARC_Config_Create(ARC_Config **config, ARC_ConfigKey_AddFunc keysAdd); void ARC_Config_Create(ARC_Config **config);
/** /**
* @brief destroys ARC_Config type * @brief destroys ARC_Config type
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
int32_t ARC_Config_Destroy(ARC_Config *config); void ARC_Config_Destroy(ARC_Config *config);
/**
* @brief sets current group in config
*
* @note ARC_Config_Get will use this set group
*
* @param config ARC_Config we are setting current group in
* @param groupname name of group that will be set
*/
void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupname);
/**
* @brief get a value from a given keyname
*
* @note name may be prefaced with <group>:: to specify group
*
* @param config ARC_Config to get value from
* @param keyname name of key to get from config
* @param value data retrieved from config
*/
void ARC_Config_Get(ARC_Config *config, ARC_String *keyname, void **value);
/** /**
* @brief commands that can be used in ARC_Config_FileIO * @brief commands that can be used in ARC_Config_FileIO
@ -87,48 +112,8 @@ int32_t ARC_Config_Destroy(ARC_Config *config);
* *
* @param config ARC_Config where io operations will take place * @param config ARC_Config where io operations will take place
* @param path file path for io * @param path file path for io
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
int32_t ARC_Config_FileIO(ARC_Config *config, const char *path, uint8_t command); void ARC_Config_FileIO(ARC_Config *config, ARC_String *path, uint8_t command);
/**
* @brief sets current group in config
*
* @note ARC_Config_Get will use this set group
*
* @param config ARC_Config we are setting current group in
* @param groupname name of group that will be set
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/
int32_t ARC_Config_SetGroup(ARC_Config *config, char *groupname);
/**
* @brief get a value from a given keyname
*
* @note name may be prefaced with <group>:: to specify group
*
* @param config ARC_Config to get value from
* @param keyname name of key to get from config
* @param value data retrieved from config
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/
int32_t ARC_Config_Get(ARC_Config *config, char *keyname, void **value);
/**
* @brief get a reference value from a given substring
*
* @note this function is meant to help with creation and deletion functions for types
*
* @param config ARC_Config to get value from
* @param data string that holds the substring that will be used
* @param subdata location of stubstring in data for what is to be read in
*
* @return a valid pointer on sucess, NULL on fail
*/
void *ARC_Config_GetReference(ARC_Config *config, char *data, ARC_StringSubstr *subdata);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -11,33 +11,39 @@ extern "C" {
#include "arc/std/string.h" #include "arc/std/string.h"
typedef struct ARC_Config ARC_Config; typedef struct ARC_Config ARC_Config;
int32_t ARC_Defaults_ConfigKey_Create(ARC_Config *config); void ARC_Defaults_ConfigKey_Create(ARC_Config *config);
int32_t ARC_ConfigKey_Read_Uint8_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Uint8_t (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Int8_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Int8_t (ARC_Config *config, ARC_String *string, void **value);
//int32_t ARC_ConfigKey_Read_Char (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Uint16_t (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Uint16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Int16_t (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Int16_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Uint32_t (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Uint32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Int32_t (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Int32_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Uint64_t (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Int (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Int64_t (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Uint64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Char (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Int64_t (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Int (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_Long (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Long (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Read_String (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); uint8_t ARC_ConfigKey_Read_Float (ARC_Config *config, ARC_String *string, void **value);
uint8_t ARC_ConfigKey_Read_Double (ARC_Config *config, ARC_String *string, void **value);
uint8_t ARC_ConfigKey_Read_String (ARC_Config *config, ARC_String *string, void **value);
// uint8_t ARC_ConfigKey_Read_StringArray(ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_ConfigKey_Delete_Uint8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Uint8_t (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Int8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Int8_t (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Char (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Uint16_t (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Uint16_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Int16_t (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Int16_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Uint32_t (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Uint32_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Int32_t (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Int32_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Uint64_t (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Int (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Int64_t (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Uint64_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Char (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Int64_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Int (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_Long (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Long (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_ConfigKey_Delete_String (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value); void ARC_ConfigKey_Delete_Float (ARC_Config *config, ARC_String *string, void *value);
void ARC_ConfigKey_Delete_Double (ARC_Config *config, ARC_String *string, void *value);
void ARC_ConfigKey_Delete_String (ARC_Config *config, ARC_String *string, void *value);
// void ARC_ConfigKey_Delete_StringArray(ARC_Config *config, ARC_String *string, void *value);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -31,10 +31,8 @@ struct ARC_HashtableNode {
* @param key value to hash * @param key value to hash
* @param keysize should be sizeof(key) before key is a void ptr * @param keysize should be sizeof(key) before key is a void ptr
* @param hashval value of hash, does not need to be within range of buckets * @param hashval value of hash, does not need to be within range of buckets
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
typedef int32_t (* ARC_Hashtable_Hash)(void *key, size_t *keysize, uint32_t *hashval); typedef void (* ARC_Hashtable_Hash)(void *key, size_t *keysize, uint32_t *hashval);
/** /**
* @brief key comparison function ptr * @brief key comparison function ptr
@ -42,19 +40,17 @@ typedef int32_t (* ARC_Hashtable_Hash)(void *key, size_t *keysize, uint32_t *has
* @param key1 first key * @param key1 first key
* @param key2 second key * @param key2 second key
* *
* @return 0 on sucess * @return 0 when keys match
*/ */
typedef int32_t (* ARC_Hashtable_KeyCompare)(void *key1, size_t *key1size, void *key2, size_t *key2size); typedef int8_t (* ARC_Hashtable_KeyCompare)(void *key1, size_t *key1size, void *key2, size_t *key2size);
/** /**
* @brief callback to allow memory freeing of nodes * @brief callback to allow memory freeing of nodes
* *
* @param node node to be destroyed * @param node node to be destroyed
* @param userdata any data the user wants to access in the callback * @param userdata any data the user wants to access in the callback
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
typedef int32_t (* ARC_HashtableNode_DestroyExternal)(ARC_HashtableNode *node, void *userdata); typedef void (* ARC_HashtableNode_DestroyExternal)(ARC_HashtableNode *node, void *userdata);
/** /**
* @brief cteates ARC_Hashtable type * @brief cteates ARC_Hashtable type
@ -72,10 +68,8 @@ void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hasht
* @param htable htable that will be destroyed * @param htable htable that will be destroyed
* @param external function to allow external freeing of nodes, can be NULL * @param external function to allow external freeing of nodes, can be NULL
* @param userdata any data the user wants access to in the callback * @param userdata any data the user wants access to in the callback
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata); void ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata);
/** /**
* @brief adds value to hastable * @brief adds value to hastable
@ -84,10 +78,8 @@ int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyEx
* @param key key for node that is being added * @param key key for node that is being added
* @param keysize sizeof key before it is passed into a void * * @param keysize sizeof key before it is passed into a void *
* @param data data for node that is being added * @param data data for node that is being added
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data); void ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data);
/** /**
* @brief gets value from hashtable by key * @brief gets value from hashtable by key
@ -96,10 +88,8 @@ int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void
* @param key key to get value from table * @param key key to get value from table
* @param keysize sizeof key before it is passed into a void * * @param keysize sizeof key before it is passed into a void *
* @param data data retrieved from table * @param data data retrieved from table
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data); void ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data);
/** /**
* @brief removes value from hashtable * @brief removes value from hashtable
@ -109,10 +99,8 @@ int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void
* @param keysize sizeof key before it is passed into a void * * @param keysize sizeof key before it is passed into a void *
* @param external function to allow external freeing of data, can be NULL * @param external function to allow external freeing of data, can be NULL
* @param userdata any data the user wants access to in the callback * @param userdata any data the user wants access to in the callback
*
* @return 0 on sucess, ARC_ERRNO_ on fail
*/ */
int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata); void ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -6,6 +6,7 @@ extern "C" {
#endif #endif
#include <stdint.h> #include <stdint.h>
#include "arc/std/string.h"
/** /**
* @brief get string and size from file * @brief get string and size from file
@ -13,11 +14,8 @@ extern "C" {
* @param path a string to path of target file * @param path a string to path of target file
* @param data pointer to where string will be created * @param data pointer to where string will be created
* this will need to be freed once done using it * this will need to be freed once done using it
* @param size size of string
*
* @return int 0 on success, ARC_ERRNO_ on fail
*/ */
int32_t ARC_IO_FileToStr(const char *path, char **data, uint64_t *size); void ARC_IO_FileToStr(ARC_String *path, ARC_String **data);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -10,92 +10,194 @@ extern "C" {
/** /**
* @brief substring position within a string * @brief substring position within a string
*/ */
typedef struct ARC_StringSubstr { typedef struct ARC_String {
uint64_t index; char *data;
uint64_t length; uint64_t length;
} ARC_StringSubstr; } ARC_String;
/** /**
* @brief substring position within a string, stored as 4 bytes * @brief creates ARC_String type
*
* @param string ARC_String to create
* @param data cstring that will be stored in ARC_String
* @param length length of ARC_String
*/ */
typedef struct ARC_StringSubstr32_t { void ARC_String_Create(ARC_String **string, char *data, uint64_t length);
uint32_t index;
uint32_t length;
} ARC_StringSubstr32_t;
/** /**
* @brief substring position within a string, stored as 1 byte * @brief creates ARC_String type with strinlen
*
* @param string ARC_String to create
* @param data cstring that will be stored in ARC_String
*/ */
typedef struct ARC_StringSubstr8_t { void ARC_String_CreateWithStrlen(ARC_String **string, char *data);
uint8_t index;
uint8_t length; /**
} ARC_StringSubstr8_t; * @brief destroys ARC_String type
*
* @param string string that will be destroyed
*/
void ARC_String_Destroy(ARC_String *string);
/**
* @brief copy a ARC_String
*
* @param copy copy of oldString, will be set to NULL on error
* @param original original string that is being copied
*/
void ARC_String_Copy(ARC_String **copy, ARC_String *original);
/**
* @brief copy a subtring from a givin ARC_String
*
* @param substring new coppied substring, will be null on error
* @param original string to copy substring from
* @param start starting index in relation on original
* @param length length of substring that is being created
*/
void ARC_String_CopySubstring(ARC_String **substring, ARC_String *original, uint64_t start, uint64_t length);
/**
* @brief copy a subtring from a givin ARC_String
*
* @param newString string that doesn't have substring in it, will be null on error
* @param original string to remove substring from
* @param substring substring to remove
*/
void ARC_String_RemoveSubstring(ARC_String **newString, ARC_String *original, ARC_String *substring);
/**
* @brief checks if two strings are the same
*
* @param first string to check against second
* @param second string to check against first
*
* @return 1 if match, 0 if they don't match
*/
uint8_t ARC_String_Equals(ARC_String *first, ARC_String *second);
/**
* @brief check if ARC_String and cstring match
*
* @param string ARC_string to check
* @param cstring cstring to check
* @param length length of cstring
*/
uint8_t ARC_String_EqualsCString(ARC_String *string, const char *cstring, uint64_t length);
/** /**
* @brief checks if string is alphabetic * @brief checks if string is alphabetic
* *
* @param val string to check * @param string string to check
* @param length length of string to check
* *
* @return 1 if alphabetic, 0 if not alphabetic * @return 1 if alphabetic, 0 if not alphabetic
*/ */
uint8_t ARC_String_Alpha(char *val, uint64_t length); uint8_t ARC_String_Alpha(ARC_String *string);
/** /**
* @brief converst substring from string to uint64_t * @brief converst substring from string to uint64_t
* *
* @param data string to get substring from * @param string string to convert to uint64_t
* @param substr substring to convert to long
* *
* @return uint64_t converted number * @return uint64_t converted number
*/ */
uint64_t ARC_String_ToUint64_t(const char *data, ARC_StringSubstr *substr); uint64_t ARC_String_ToUint64_t(ARC_String *string);
/**
* @brief converst substring from string to int64_t
*
* @param string string to convert to int64_t
*
* @return int64_t converted number
*/
int64_t ARC_String_ToInt64_t(ARC_String *string);
/**
* @brief converst substring from string to double
*
* @param string string to convert to double
*
* @return double converted number
*/
double ARC_String_ToDouble(ARC_String *string);
/** /**
* @brief takes a given string, and assigns index and length for position of first matching substring * @brief takes a given string, and assigns index and length for position of first matching substring
* *
* @param data the string to find substring in * @param string the string that will be searched
* @param substr the string to find * @param substr substring to find within string
* @param index the index of substring within the string will be ~uint64_t if not found
* *
* @return int ARC_ERRNO_ error code * @return ~(uint64_t)0 on error, anything else on success
*/ */
int32_t ARC_String_Find(char *data, char *substr, uint64_t *index); uint64_t ARC_String_Find(ARC_String *string, ARC_String *substring);
/**
* @brief takes given cstring and gives position of first matching
*
* @param string the string that will be searched
* @param cstring the cstring to find within string
* @param length the length of cstring
*
* @return ~(uint64_t)0 on error, anything else on success
*/
uint64_t ARC_String_FindCString(ARC_String *string, const char *cstring, uint64_t length);
/** /**
* @brief takes a given string, and assigns index and length for position of last matching substring * @brief takes a given string, and assigns index and length for position of last matching substring
* *
* @param data the string to find substring in * @param string the string that will be searched
* @param substr the string to find * @param substr substring to find within string
* @param index the index of substring within the string will be ~uint64_t if not found
* *
* @return int ARC_ERRNO_ error code * @return ~(uint64_t)0 on error, anything else on success
*/ */
int32_t ARC_String_FindBack(char *data, char *substr, uint64_t *index); uint64_t ARC_String_FindBack(ARC_String *string, ARC_String *substring);
/** /**
* @brief strips the ends based on a given substing * @brief strips the ends based on a given char
* *
* @param data the string to find the substring in * @param original the string which whill have the matching char stripped from
* @param substr the substring to strip ends by, defaults to " " if NULL * @param stripped where to store the string which has witespace stripped
* @param subdata the substring of data, will use given substring data, or strlen if length == 0 * will be null if there is an error
* also will hold the return values * @param charToStrip the char that will be stripped from the ends
*
* @return int ARC_ERRNO_ error code
*/ */
int32_t ARC_StringSubstr_StripEnds(char *data, char *substr, ARC_StringSubstr *subdata); void ARC_String_StripEnds(ARC_String *original, ARC_String **stripped, char charToStrip);
/** /**
* @brief strips the ends based on a given substing * @brief strips whitespace from a ARC_String
* *
* @param data the string to find the substring in * @param original the string which whill have whitespace stripped from
* @param substr the substring to strip ends by, defaults to " " if NULL * @param stripped where to store the string which has witespace stripped
* @param subdata the substring of data, will use given substring data, or strlen if length == 0 * will be null if there is an error
* also will hold the return values
*
* @return int ARC_ERRNO_ error code
*/ */
int32_t ARC_StringSubstr_StripWhitespaceEnds(char *data, ARC_StringSubstr *subdata); void ARC_String_StripWhitespace(ARC_String *original, ARC_String **stripped);
/**
* @brief strips the whitespace from the ends of a string
*
* @param original the string which whill have the whitespace stripped from its ends
* @param stripped where to store the string which has witespace stripped from the ends
* will be null if there is an error
*/
void ARC_String_StripEndsWhitespace(ARC_String *original, ARC_String **stripped);
/**
* @brief merges two strings together
*
* @param first first part of string to combine
* @param second second part of string to combine
* @param combined new ARC_String of combined strings frist + second
*/
void ARC_String_Merge(ARC_String *first, ARC_String *second, ARC_String **combined);
/**
* @brief copy a subtring from a givin ARC_String
*
* @param newString new string without specified section, will be NULL on error
* @param original string to remove section from
* @param removeIndex starting index in relation on original of what is to be removed
* @param removeLength length of section that is being removed
*/
void ARC_String_RemoveSection(ARC_String **newString, ARC_String *original, uint64_t removeIndex, uint64_t removeLength);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -0,0 +1,11 @@
#include "arc/engine/ecs.h"
#include "arc/std/vector.h"
struct ARC_ECS {
ARC_Vector *components;
};
struct ARC_ECSComponent {
ARC_Vector *functions;
ARC_Vector *data;
};

View file

@ -18,7 +18,7 @@
#include "arc/input/sdl/keyboard.h" #include "arc/input/sdl/keyboard.h"
#endif // ARC_SDL #endif // ARC_SDL
void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanfn){ void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanfn, ARC_Point windowSize){
*data = (ARC_EngineData *)malloc(sizeof(ARC_EngineData)); *data = (ARC_EngineData *)malloc(sizeof(ARC_EngineData));
(*data)->window = NULL; (*data)->window = NULL;
(*data)->renderer = NULL; (*data)->renderer = NULL;
@ -31,7 +31,7 @@ void ARC_EngineData_Create(ARC_EngineData **data, ARC_Handler_CleanDataFn cleanf
ARC_MouseInfo mouseInfo; ARC_MouseInfo mouseInfo;
ARC_KeyboardInfo keyboardInfo; ARC_KeyboardInfo keyboardInfo;
(*data)->windowSize = (ARC_Point){ 2560, 1440 }; (*data)->windowSize = windowSize;
#ifdef ARC_SDL #ifdef ARC_SDL
windowInfo = (ARC_WindowInfo){ "title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, (*data)->windowSize.x, (*data)->windowSize.y, 0 }; windowInfo = (ARC_WindowInfo){ "title", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, (*data)->windowSize.x, (*data)->windowSize.y, 0 };

View file

@ -3,6 +3,7 @@
#include <SDL_image.h> #include <SDL_image.h>
#include <stdio.h> #include <stdio.h>
#include "arc/std/array.h"
#include "arc/std/string.h" #include "arc/std/string.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include "arc/graphics/sdl/renderer.h" #include "arc/graphics/sdl/renderer.h"
@ -18,33 +19,28 @@
SDL_Renderer *global_renderer; SDL_Renderer *global_renderer;
typedef struct ARC_Array { uint8_t ARC_Point_Read (ARC_Config *config, ARC_String *string, void **value);
uint32_t *size; uint8_t ARC_Rect_Read (ARC_Config *config, ARC_String *string, void **value);
void *data; uint8_t ARC_RectArray_Read (ARC_Config *config, ARC_String *string, void **value);
} ARC_Array; uint8_t ARC_SDL_Texture_Read(ARC_Config *config, ARC_String *string, void **value);
uint8_t ARC_Spritesheet_Read(ARC_Config *config, ARC_String *string, void **value);
uint8_t ARC_Sprite_Read (ARC_Config *config, ARC_String *string, void **value);
int32_t ARC_Point_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); void ARC_Point_Delete (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_Rect_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); void ARC_Rect_Delete (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_RectArray_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); void ARC_RectArray_Delete (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_SDL_Texture_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); void ARC_SDL_Texture_Delete(ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_Spritesheet_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); void ARC_Spritesheet_Delete(ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_Sprite_Read (ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value); void ARC_Sprite_Delete (ARC_Config *config, ARC_String *string, void *value);
int32_t ARC_Point_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
int32_t ARC_Rect_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
int32_t ARC_RectArray_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
int32_t ARC_SDL_Texture_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
int32_t ARC_Spritesheet_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
int32_t ARC_Sprite_Delete (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value);
void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer){ void ARC_GraphicsConfig_Init(ARC_Config *config, ARC_Renderer *renderer){
global_renderer = renderer->renderer; global_renderer = renderer->renderer;
ARC_ConfigKey_Add(config, (char *)"ARC_Point" , (ARC_ConfigKeyRead) ARC_Point_Read , (ARC_ConfigKeyDelete) ARC_Point_Delete ); ARC_Config_AddKeyCString(config, (char *)"ARC_Point" , 9, ARC_Point_Read , ARC_Point_Delete );
ARC_ConfigKey_Add(config, (char *)"ARC_Rect" , (ARC_ConfigKeyRead) ARC_Rect_Read , (ARC_ConfigKeyDelete) ARC_Rect_Delete ); ARC_Config_AddKeyCString(config, (char *)"ARC_Rect" , 8, ARC_Rect_Read , ARC_Rect_Delete );
ARC_ConfigKey_Add(config, (char *)"ARC_RectArray" , (ARC_ConfigKeyRead) ARC_RectArray_Read , (ARC_ConfigKeyDelete) ARC_RectArray_Delete ); ARC_Config_AddKeyCString(config, (char *)"ARC_Rect[]" , 10, ARC_RectArray_Read , ARC_RectArray_Delete );
ARC_ConfigKey_Add(config, (char *)"SDL_Texture" , (ARC_ConfigKeyRead) ARC_SDL_Texture_Read, (ARC_ConfigKeyDelete) ARC_SDL_Texture_Delete); ARC_Config_AddKeyCString(config, (char *)"SDL_Texture" , 11, ARC_SDL_Texture_Read, ARC_SDL_Texture_Delete);
ARC_ConfigKey_Add(config, (char *)"ARC_Spritesheet", (ARC_ConfigKeyRead) ARC_Spritesheet_Read, (ARC_ConfigKeyDelete) ARC_Spritesheet_Delete); ARC_Config_AddKeyCString(config, (char *)"ARC_Spritesheet", 15, ARC_Spritesheet_Read, ARC_Spritesheet_Delete);
ARC_ConfigKey_Add(config, (char *)"ARC_Sprite" , (ARC_ConfigKeyRead) ARC_Sprite_Read , (ARC_ConfigKeyDelete) ARC_Sprite_Delete ); ARC_Config_AddKeyCString(config, (char *)"ARC_Sprite" , 10, ARC_Sprite_Read , ARC_Sprite_Delete );
} }
int32_t ARC_SDL_Texture_Load(const char *path, SDL_Texture **texture){ int32_t ARC_SDL_Texture_Load(const char *path, SDL_Texture **texture){
@ -63,100 +59,209 @@ int32_t ARC_SDL_Texture_Load(const char *path, SDL_Texture **texture){
return 0; return 0;
} }
int32_t ARC_Point_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint64_t getIndexAndErrorCheck(ARC_String *string, char *search, uint64_t searchLength){
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); uint64_t separator = ARC_String_FindCString(string, ",", 1);
if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; }
subdata->index++;
subdata->length -= 2;
uint64_t split; if(separator == ~(uint64_t)0){
*value = malloc(sizeof(ARC_Rect)); arc_errno = ARC_ERRNO_DATA;
}
//x return separator;
int32_t err = ARC_String_Find(((char *)data) + subdata->index, (char *)",", &split); }
if(err){ return err; }
if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; }
ARC_StringSubstr temp = { subdata->index, split };
((SDL_Point *) *value)->x = (int)ARC_String_ToUint64_t(data, &temp);
//y uint8_t ARC_Point_Read(ARC_Config *config, ARC_String *string, void **value){
temp = (ARC_StringSubstr){ temp.index + split + 1, subdata->length - split - 1 }; ARC_Config_Get(config, string, value);
((SDL_Point *) *value)->y = (int)ARC_String_ToUint64_t(data, &temp); if(*value){
return 1;
}
if(string->data[0] != '{' || string->data[string->length - 1] != '}'){
ARC_DEBUG_LOG(arc_errno, "in ARC_Point_Read(config, string, value); no matching curly braces: %s", string->data);
arc_errno = ARC_ERRNO_DATA;
return 0; return 0;
} }
int32_t ARC_Rect_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint64_t separator = getIndexAndErrorCheck(string, ",", 1);
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); if(arc_errno){
if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; } return 0;
subdata->index++; }
subdata->length -= 2;
uint64_t split; ARC_String *xString, *yString;
*value = malloc(sizeof(ARC_Rect)); ARC_String_CopySubstring(&xString, string, 1 , separator - 1 );
ARC_String_CopySubstring(&yString, string, separator + 1, string->length - (separator + 2));
SDL_Point *point = (SDL_Point *)malloc(sizeof(SDL_Point));
point->x = (int32_t)ARC_String_ToInt64_t(xString);
point->y = (int32_t)ARC_String_ToInt64_t(yString);
ARC_String_Destroy(xString);
ARC_String_Destroy(yString);
*value = point;
return 0;
}
uint8_t ARC_Rect_Read(ARC_Config *config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
if(string->data[0] != '{' || string->data[string->length - 1] != '}'){
arc_errno = ARC_ERRNO_DATA;
ARC_DEBUG_LOG(arc_errno, "in ARC_Rect_Read(config, string, value); no matching curly braces: %s", string->data);
return 0;
}
ARC_String *current;
ARC_String_CopySubstring(&current, string, 1, string->length - 2);
ARC_String *temp, *tempStripped;
int32_t x, y, w, h;
int64_t separator;
//x //x
int32_t err = ARC_String_Find(((char *)data) + subdata->index, (char *)",", &split); separator = getIndexAndErrorCheck(current, ",", 1);
if(err){ return err; } if(arc_errno){
if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } return 0;
ARC_StringSubstr temp = { subdata->index, split }; }
((ARC_Rect *) *value)->x = (int)ARC_String_ToUint64_t(data, &temp);
int32_t ttt = ((ARC_Rect *) *value)->x; ARC_String_CopySubstring(&temp, current, 0, separator - 1);
ARC_String_StripEndsWhitespace(temp, &tempStripped);
x = ARC_String_ToInt64_t(tempStripped);
ARC_String_Destroy(temp);
ARC_String_Destroy(tempStripped);
temp = current;
ARC_String_CopySubstring(&current, temp, separator + 1, temp->length - (separator + 1));
ARC_String_Destroy(temp);
//y //y
temp.index = subdata->index + split + 1; separator = getIndexAndErrorCheck(current, ",", 1);
err = ARC_String_Find(((char *)data) + temp.index, (char *)",", &split); if(arc_errno){
if(err){ return err; } return 0;
if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } }
temp.length = split;
((SDL_Rect *) *value)->y = (int)ARC_String_ToUint64_t(data, &temp); ARC_String_CopySubstring(&temp, current, 0, separator - 1);
ttt = ((ARC_Rect *) *value)->y; ARC_String_StripEndsWhitespace(temp, &tempStripped);
y = ARC_String_ToInt64_t(tempStripped);
ARC_String_Destroy(temp);
ARC_String_Destroy(tempStripped);
temp = current;
ARC_String_CopySubstring(&current, temp, separator + 1, temp->length - (separator + 1));
ARC_String_Destroy(temp);
//w //w
temp.index = temp.index + split + 1; separator = getIndexAndErrorCheck(current, ",", 1);
err = ARC_String_Find(((char *)data) + temp.index, (char *)",", &split); if(arc_errno){
if(err){ return err; }
if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; }
temp.length = split;
((SDL_Rect *) *value)->w = (int)ARC_String_ToUint64_t(data, &temp);
ttt = ((ARC_Rect *) *value)->w;
//h
temp = (ARC_StringSubstr){ temp.index + split + 1, subdata->length - split - 1 };
((SDL_Rect *) *value)->h = (int)ARC_String_ToUint64_t(data, &temp);
ttt = ((ARC_Rect *) *value)->h;
return 0; return 0;
} }
int32_t ARC_RectArray_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ ARC_String_CopySubstring(&temp, current, 0, separator - 1);
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); ARC_String_StripEndsWhitespace(temp, &tempStripped);
if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; } w = ARC_String_ToInt64_t(tempStripped);
subdata->index++; ARC_String_Destroy(temp);
subdata->length -= 2; ARC_String_Destroy(tempStripped);
uint32_t arraySize = 1; temp = current;
int32_t encapsulated = 0; ARC_String_CopySubstring(&current, temp, separator + 1, temp->length - (separator + 1));
for(uint32_t i = subdata->index; i < subdata->index + subdata->length; i++){ ARC_String_Destroy(temp);
if(data[i] == '{'){
//h
separator = current->length;
if(arc_errno){
return 0;
}
ARC_String_CopySubstring(&temp, current, 0, separator);
ARC_String_StripEndsWhitespace(temp, &tempStripped);
h = ARC_String_ToInt64_t(tempStripped);
ARC_String_Destroy(temp);
ARC_String_Destroy(tempStripped);
ARC_String_Destroy(current);
*value = malloc(sizeof(ARC_Rect));
((ARC_Rect *) *value)->x = x;
((ARC_Rect *) *value)->y = y;
((ARC_Rect *) *value)->w = w;
((ARC_Rect *) *value)->h = h;
return 0;
}
void ARC_RectArray_ReadRect(ARC_Config* config, ARC_String *stripped, uint64_t index, uint64_t length, uint64_t *arrayIndex, void **value){
ARC_String *substr, *temp;
ARC_String_CopySubstring(&temp, stripped, index, length);
ARC_String_StripEndsWhitespace(temp, &substr);
ARC_String_Destroy(temp);
// reading in reference
ARC_Rect *tempRect;
ARC_Config_Get(config, substr, (void **) &tempRect);
if(tempRect){
ARC_String_Destroy(substr);
((ARC_Rect *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempRect;
++*arrayIndex;
return;
}
//reading in value
ARC_Rect_Read(config, substr, (void **) &tempRect);
if(arc_errno){
ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_ReadRect(config, string, index, length, arrayIndex, value); failed to read rect: %s", substr->data);
ARC_String_Destroy(substr);
return;
}
((ARC_Rect *)((ARC_Array *) *value)->data)[*arrayIndex] = *tempRect;
++*arrayIndex;
ARC_Rect_Delete(config, substr, (void *)tempRect);
ARC_String_Destroy(substr);
}
uint8_t ARC_RectArray_Read(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
if(string->data[0] != '{' || string->data[string->length - 1] != '}'){
arc_errno = ARC_ERRNO_DATA;
ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_Read(config, string, value); no matching curly braces: %s", string->data);
return 0;
}
ARC_String *temp, *stripped;
ARC_String_CopySubstring(&temp, string, 1, string->length - 2);
ARC_String_StripEndsWhitespace(temp, &stripped);
ARC_String_Destroy(temp);
uint64_t arraySize = 1;
int64_t encapsulated = 0;
for(uint64_t i = 0; i < stripped->length; i++){
if(stripped->data[i] == '{'){
encapsulated++; encapsulated++;
continue; continue;
} }
if(data[i] == '}'){ if(stripped->data[i] == '}'){
encapsulated--; encapsulated--;
continue; continue;
} }
if(!encapsulated && data[i] == ','){ if(!encapsulated && stripped->data[i] == ','){
arraySize++; arraySize++;
} }
} }
if(encapsulated){ if(encapsulated){
arc_errno = ARC_ERRNO_DATA; arc_errno = ARC_ERRNO_DATA;
ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_Read(config, data, subdata, value); after looping encapsulated was %d", encapsulated); ARC_DEBUG_LOG(arc_errno, "in ARC_RectArray_Read(config, data, subdata, value); after looping encapsulated was %ld", encapsulated);
return arc_errno; ARC_String_Destroy(stripped);
return 0;
} }
*value = malloc(sizeof(ARC_Array)); *value = malloc(sizeof(ARC_Array));
@ -164,40 +269,27 @@ int32_t ARC_RectArray_Read(ARC_Config* config, const char *data, ARC_StringSubst
((ARC_Array *) *value)->size = malloc(sizeof(uint32_t)); ((ARC_Array *) *value)->size = malloc(sizeof(uint32_t));
*((ARC_Array *) *value)->size = arraySize; *((ARC_Array *) *value)->size = arraySize;
ARC_StringSubstr temp = { subdata->index, 0 }; uint64_t index = 0;
arraySize = 0; arraySize = 0;
encapsulated = 0; encapsulated = 0;
for(uint64_t i = subdata->index; i < subdata->index + subdata->length; i++){ for(uint64_t i = 0; i < stripped->length; i++){
if(data[i] == '{'){ if(stripped->data[i] == '{'){
encapsulated++; encapsulated++;
continue; continue;
} }
if(data[i] == '}'){ if(stripped->data[i] == '}'){
encapsulated--; encapsulated--;
continue; continue;
} }
if(!encapsulated && data[i] == ','){ if(!encapsulated && stripped->data[i] == ','){
temp.length = i - temp.index; ARC_RectArray_ReadRect(config, stripped, index, i - index, &arraySize, value);
ARC_Rect *tempRect = (ARC_Rect *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!tempRect){
ARC_Rect_Read(config, data, &temp, (void **) &tempRect);
if(arc_errno){ if(arc_errno){
return arc_errno; return 0;
}
} }
((ARC_Rect *)((ARC_Array *) *value)->data)[arraySize] = *tempRect; index = i + 1;
ARC_Rect_Delete(config, data, &temp, (void *)tempRect);
if(arc_errno){
return arc_errno;
}
arraySize++;
temp = (ARC_StringSubstr){ i + 1, 0 };
if(arraySize == *((ARC_Array *) *value)->size){ if(arraySize == *((ARC_Array *) *value)->size){
break; break;
@ -205,247 +297,269 @@ int32_t ARC_RectArray_Read(ARC_Config* config, const char *data, ARC_StringSubst
} }
} }
temp.length = (subdata->index + subdata->length) - temp.index; if(arraySize != *((ARC_Array *) *value)->size){
ARC_Rect *tempRect = (ARC_Rect *)ARC_Config_GetReference(config, (char *)data, &temp); ARC_RectArray_ReadRect(config, stripped, index, stripped->length - index, &arraySize, value);
if(!tempRect){
int32_t ttt = ARC_Rect_Read(config, data, &temp, (void **) &tempRect);
if(arc_errno){
return arc_errno;
}
}
((ARC_Rect *)((ARC_Array *) *value)->data)[arraySize] = *tempRect;
ARC_Rect ttt = ((ARC_Rect *)((ARC_Array *) *value)->data)[arraySize];
ARC_Rect_Delete(config, data, &temp, (void *)tempRect);
if(arc_errno){
return arc_errno;
} }
ARC_String_Destroy(stripped);
return 0; return 0;
} }
int32_t ARC_SDL_Texture_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata);
ARC_StringSubstr_StripEnds((char *)data, (char *)"\"", subdata);
char path[subdata->length + 1]; uint8_t ARC_SDL_Texture_Read(ARC_Config* config, ARC_String *string, void **value){
strncpy(path, data + subdata->index, subdata->length); ARC_Config_Get(config, string, value);
path[subdata->length] = 0; if(*value){
return 1;
return ARC_SDL_Texture_Load(path, (SDL_Texture **)value);
} }
int32_t ARC_Spritesheet_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ ARC_String *tempStr, *textureStr;
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); ARC_String_StripEndsWhitespace(string, &tempStr);
if(data[subdata->index] != '{'){
SDL_Texture *texture = (SDL_Texture *)ARC_Config_GetReference(config, (char *)data, subdata);
if(!texture && data[subdata->index] != '"'){ return ARC_ERRNO_DATA; }
if(!texture){ ARC_String_CopySubstring(&textureStr, tempStr, 1, tempStr->length - 2);
int32_t err = ARC_SDL_Texture_Read(config, data, subdata, (void **)&texture); ARC_String_Destroy(tempStr);
if(err){ return ARC_ERRNO_DATA; }
}
*value = malloc(sizeof(ARC_Spritesheet)); ARC_SDL_Texture_Load(textureStr->data, (SDL_Texture **)value);
((ARC_Spritesheet *) *value)->texture = texture;
((ARC_Spritesheet *) *value)->size = NULL; ARC_String_Destroy(textureStr);
return 0; return 0;
} }
if(data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; } void ARC_Spritesheet_ReadTexture(ARC_Config *config, ARC_String *string, uint32_t *size, void **value){
subdata->index++; SDL_Texture *texture;
subdata->length -= 2; //remove the starting { and ending }
//Texture ARC_String *tempStr, *textureStr;
uint64_t split; ARC_String_StripEndsWhitespace(string, &tempStr);
int32_t err = ARC_String_Find(((char *)data) + subdata->index, (char *)",", &split);
if(err){ return err; }
if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; }
ARC_StringSubstr temp = { subdata->index, split }; //check for reference
ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp); ARC_Config_Get(config, tempStr, (void **)&texture);
SDL_Texture *texture = (SDL_Texture *)ARC_Config_GetReference(config, (char *)data, &temp); if(!texture && (tempStr->data[0] != '"' || tempStr->data[string->length - 1] != '"')){
if(!texture && data[temp.index] != '"'){ return ARC_ERRNO_DATA; } arc_errno = ARC_ERRNO_DATA;
}
ARC_String_CopySubstring(&textureStr, tempStr, 1, tempStr->length - 2);
ARC_String_Destroy(tempStr);
//try reading in the texture
if(!texture){ if(!texture){
err = ARC_SDL_Texture_Read(config, data, &temp, (void **)&texture); ARC_SDL_Texture_Read(config, string, (void **)&texture);
if(err){ return ARC_ERRNO_DATA; } if(arc_errno){
*value = NULL;
}
} }
//uint32_t size ARC_String_Destroy(textureStr);
temp = (ARC_StringSubstr){ subdata->index + split + 1, subdata->length - split - 1 };
ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp);
uint32_t *size = (uint32_t *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!size){
ARC_ConfigKey_Read_Uint64_t(config, data, &temp, (void **)&size);
if(err){ return ARC_ERRNO_DATA; }
}
*value = malloc(sizeof(ARC_Spritesheet)); *value = malloc(sizeof(ARC_Spritesheet));
((ARC_Spritesheet *) *value)->texture = texture; ((ARC_Spritesheet *) *value)->texture = texture;
((ARC_Spritesheet *) *value)->size = size; ((ARC_Spritesheet *) *value)->size = size;
}
uint8_t ARC_Spritesheet_Read(ARC_Config* config, ARC_String *string, void **value){
if(string->data[0] != '{' || string->data[string->length - 1] != '}'){
ARC_Spritesheet_ReadTexture(config, string, NULL, value);
return 0;
}
uint64_t split = getIndexAndErrorCheck(string, ",", 1);
if(arc_errno){
return 0;
}
ARC_String *temp, *textureStr, *sizeStr;
ARC_String_CopySubstring(&temp, string, 1, split - 2);
ARC_String_StripEndsWhitespace(temp, &textureStr);
ARC_String_Destroy(temp);
ARC_String_CopySubstring(&temp, string, split + 1, string->length - (split + 1));
ARC_String_StripEndsWhitespace(temp, &sizeStr);
ARC_String_Destroy(temp);
uint32_t *size;
ARC_Config_Get(config, string, (void **)&size);
if(!size){
ARC_ConfigKey_Read_Uint32_t(config, sizeStr, (void **)&size);
if(arc_errno){
ARC_String_Destroy(sizeStr);
ARC_String_Destroy(textureStr);
return ARC_ERRNO_DATA;
}
}
ARC_Spritesheet_ReadTexture(config, textureStr, size, value);
ARC_String_Destroy(sizeStr);
ARC_String_Destroy(textureStr);
return 0; return 0;
} }
int32_t ARC_Sprite_Read(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_Sprite_Read(ARC_Config* config, ARC_String *string, void **value){
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); ARC_Config_Get(config, string, value);
if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; } if(*value){
subdata->index++; return 1;
subdata->length -= 2; //remove the starting { and ending } }
uint64_t split; if(string->data[0] != '{' || string->data[string->length - 1] != '}'){
int32_t err = ARC_String_Find(((char *)data) + subdata->index, (char *)",", &split); ARC_Spritesheet_ReadTexture(config, string, NULL, value);
if(err){ return err; } return 0;
if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } }
uint64_t split = getIndexAndErrorCheck(string, ",", 1);
if(arc_errno){
return 0;
}
ARC_String *temp, *spritesheetStr, *framesStr;
ARC_String_CopySubstring(&temp, string, 1, split - 2);
ARC_String_StripEndsWhitespace(temp, &spritesheetStr);
ARC_String_Destroy(temp);
ARC_String_CopySubstring(&temp, string, split + 1, string->length - (split + 2));
ARC_String_StripEndsWhitespace(temp, &framesStr);
ARC_String_Destroy(temp);
//spritesheet //spritesheet
ARC_StringSubstr temp = { subdata->index, split }; ARC_Spritesheet *spritesheet;
ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp); ARC_Config_Get(config, spritesheetStr, (void **)&spritesheet);
ARC_Spritesheet *spritesheet = (ARC_Spritesheet *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!spritesheet){ if(!spritesheet){
err = ARC_Spritesheet_Read(config, data, &temp, (void **)&spritesheet); ARC_Spritesheet_Read(config, spritesheetStr, (void **)&spritesheet);
if(err){ return ARC_ERRNO_DATA; } if(arc_errno){
ARC_String_Destroy(spritesheetStr);
ARC_String_Destroy(framesStr );
return 0;
}
} }
//bounds //bounds
uint8_t isRectArray = 0; ARC_Array *frames;
temp = (ARC_StringSubstr){ subdata->index + split + 1, subdata->length - split - 1 }; ARC_Config_Get(config, framesStr, (void **)&frames);
ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp);
ARC_Array *bounds = (ARC_Array *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!bounds){ if(!frames){
err = ARC_RectArray_Read(config, data, &temp, (void **)&bounds); ARC_RectArray_Read(config, framesStr, (void **)&frames);
if(err){ return ARC_ERRNO_DATA; } if(arc_errno){
isRectArray = 1; ARC_String_Destroy(spritesheetStr);
ARC_String_Destroy(framesStr );
return 0;
}
} }
//scale bounds on spritesheet size ARC_String_Destroy(spritesheetStr);
// TODO: possible bug for sheets that use the same bounds ARC_String_Destroy(framesStr );
// Scale frames to match spritesheet size
// TODO: possible bug for sheets that use same frames
if(spritesheet->size){ if(spritesheet->size){
for(uint32_t i = 0; i < *bounds->size; i++){ for(uint32_t i = 0; i < *frames->size; i++){
((ARC_Rect *)bounds->data)[i].x *= *spritesheet->size; ((ARC_Rect *)frames->data)[i].x *= *spritesheet->size;
((ARC_Rect *)bounds->data)[i].y *= *spritesheet->size; ((ARC_Rect *)frames->data)[i].y *= *spritesheet->size;
((ARC_Rect *)bounds->data)[i].w *= *spritesheet->size; ((ARC_Rect *)frames->data)[i].w *= *spritesheet->size;
((ARC_Rect *)bounds->data)[i].h *= *spritesheet->size; ((ARC_Rect *)frames->data)[i].h *= *spritesheet->size;
} }
} }
//sprite
*value = malloc(sizeof(ARC_Sprite)); *value = malloc(sizeof(ARC_Sprite));
((ARC_Sprite *) *value)->frameIndex = malloc(sizeof(uint32_t)); ((ARC_Sprite *) *value)->frameIndex = malloc(sizeof(uint32_t));
((ARC_Sprite *) *value)->spritesheet = spritesheet; ((ARC_Sprite *) *value)->spritesheet = spritesheet;
((ARC_Sprite *) *value)->frames = bounds->data; ((ARC_Sprite *) *value)->frames = frames;
((ARC_Sprite *) *value)->frameSize = bounds->size;
*((ARC_Sprite *) *value)->frameIndex = 0; *((ARC_Sprite *) *value)->frameIndex = 0;
ARC_Rect *ttt = (ARC_Rect *)bounds->data;
ARC_Rect ttf = ttt[0];
if(isRectArray){
free(bounds);
}
return 0; return 0;
} }
int32_t ARC_Point_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ void ARC_Point_Delete(ARC_Config* config, ARC_String *string, void *value){
if((ARC_Point *)value){ free((ARC_Point *)value); } free((ARC_Point *)value);
return 0;
} }
int32_t ARC_Rect_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ void ARC_Rect_Delete(ARC_Config* config, ARC_String *string, void *value){
if((ARC_Rect *)value){ free((ARC_Rect *)value); } free((ARC_Rect *)value);
return 0;
} }
int32_t ARC_RectArray_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ void ARC_RectArray_Delete(ARC_Config* config, ARC_String *string, void *value){
if((ARC_Array *)value){ free((ARC_Array *)value); } free((ARC_Array *)value);
return 0;
} }
int32_t ARC_SDL_Texture_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ void ARC_SDL_Texture_Delete(ARC_Config* config, ARC_String *string, void *value){
//if((SDL_Texture *) value){ SDL_DestroyTexture((SDL_Texture *) value); } SDL_DestroyTexture((SDL_Texture *) value);
return 0;
} }
int32_t ARC_Spritesheet_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){
ARC_Spritesheet *spritesheet = (ARC_Spritesheet *) value; void ARC_Spritesheet_Delete(ARC_Config* config, ARC_String *string, void *value){
if(!data){ //there is no data, kill everything, most likely was called by a data type being destroyed ARC_Spritesheet *sheetValue = (ARC_Spritesheet *)value;
free(spritesheet);
return 0; //check if read in as a Textrue reference
void *temp;
ARC_Config_Get(config, string, &temp);
if(temp){
free(sheetValue);
return;
} }
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); uint64_t split = getIndexAndErrorCheck(string, ",", 1);
if(data[subdata->index] != '{'){ if(arc_errno){
SDL_Texture *texture = (SDL_Texture *)ARC_Config_GetReference(config, (char *)data, subdata); free(sheetValue);
if(!texture){ return;
ARC_SDL_Texture_Delete(config, data, subdata, (void *)spritesheet->texture);
} }
// if(spritesheet){ //check if texture and size are references
// free(spritesheet); ARC_String *tempStr, *textureStr, *sizeStr;
// } ARC_String_CopySubstring(&tempStr, string, 1, split - 1);
ARC_String_StripEndsWhitespace(tempStr, &textureStr);
ARC_String_Destroy(tempStr);
return 0; ARC_String_CopySubstring(&tempStr, string, split + 1, string->length - (split + 1));
ARC_String_StripEndsWhitespace(tempStr, &sizeStr);
ARC_String_Destroy(tempStr);
ARC_Config_Get(config, sizeStr, (void **)&temp);
ARC_String_Destroy(sizeStr);
if(temp){
free(sheetValue->size);
} }
uint64_t split; ARC_Config_Get(config, textureStr, (void **)&temp);
int32_t err = ARC_String_Find(((char *)data) + subdata->index, (char *)",", &split); ARC_String_Destroy(textureStr);
if(err){ return err; } if(temp){
if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } free(sheetValue->size);
ARC_StringSubstr temp = { subdata->index, split };
ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp);
SDL_Texture *texture = (SDL_Texture *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!texture){ ARC_SDL_Texture_Delete(config, data, &temp, (void *)spritesheet->texture); }
temp = (ARC_StringSubstr){ subdata->index + split + 1, subdata->length - split - 1 };
ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp);
uint32_t *size = (uint32_t *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!size){ ARC_ConfigKey_Delete_Uint64_t(config, data, &temp, (void *)spritesheet->size); }
free(spritesheet);
return 0;
} }
int32_t ARC_Sprite_Delete(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ free(sheetValue);
ARC_Sprite *sprite = (ARC_Sprite *) value;
if(!data){
free(sprite);
return 0;
} }
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); void ARC_Sprite_Delete(ARC_Config* config, ARC_String *string, void *value){
if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; } ARC_Sprite *spriteValue = (ARC_Sprite *)value;
subdata->index++;
subdata->length -= 2; //remove the starting { and ending }
uint64_t split; //check if read in as a Textrue reference
int32_t err = ARC_String_Find(((char *)data) + subdata->index, (char *)",", &split); void *temp;
if(err){ return err; } uint64_t split = getIndexAndErrorCheck(string, ",", 1);
if(split == ~((uint64_t)0) || split > subdata->length){ return ARC_ERRNO_DATA; } if(arc_errno){
free(spriteValue);
//spritesheet return;
ARC_StringSubstr temp = { subdata->index, split };
ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp);
ARC_Spritesheet *spritesheet = (ARC_Spritesheet *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!spritesheet){ ARC_Spritesheet_Delete(config, data, &temp, (void *)sprite->spritesheet); }
//bounds
temp = (ARC_StringSubstr){ subdata->index + split + 1, subdata->length - split - 1 };
ARC_StringSubstr_StripWhitespaceEnds((char *)data, &temp);
SDL_Rect *bounds = (SDL_Rect *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!bounds){
free(sprite->frames);
free(sprite->frameSize);
} }
free(sprite->frameIndex); //check if texture and size are references
free(sprite); ARC_String *tempStr, *spritesheetStr, *framesStr;
return 0; ARC_String_CopySubstring(&tempStr, string, 1, split - 1);
ARC_String_StripEndsWhitespace(tempStr, &spritesheetStr);
ARC_String_Destroy(tempStr);
ARC_String_CopySubstring(&tempStr, string, split + 1, string->length - (split + 1));
ARC_String_StripEndsWhitespace(tempStr, &framesStr);
ARC_String_Destroy(tempStr);
ARC_Config_Get(config, spritesheetStr, (void **)&temp);
ARC_String_Destroy(spritesheetStr);
if(temp){
free(spriteValue->spritesheet);
}
ARC_Config_Get(config, framesStr, (void **)&temp);
ARC_String_Destroy(framesStr);
if(temp){
free(spriteValue->frames);
}
free(spriteValue);
} }
#endif //ARC_SDL #endif //ARC_SDL

11
src/graphics/sdl/line.c Normal file
View file

@ -0,0 +1,11 @@
#include "arc/graphics/line.h"
#ifdef ARC_SDL
#include "arc/graphics/sdl/renderer.h"
#include <stdlib.h>
void ARC_Line_Render(int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2, ARC_Renderer *renderer, ARC_Color *color){
SDL_SetRenderDrawColor(renderer->renderer, color->r, color->g, color->b, color->a);
SDL_RenderDrawLine(renderer->renderer, *x1, *y1, *x2, *y2);
}
#endif // ARC_SDL

View file

@ -0,0 +1,11 @@
#include "arc/graphics/rectangle.h"
#ifdef ARC_SDL
#include "arc/graphics/sdl/renderer.h"
#include <stdlib.h>
void ARC_Rect_Render(ARC_Rect *rect, ARC_Renderer *renderer, ARC_Color *color){
SDL_SetRenderDrawColor(renderer->renderer, color->r, color->g, color->b, color->a);
SDL_RenderDrawRect(renderer->renderer, (SDL_Rect *) rect);
}
#endif // ARC_SDL

View file

@ -3,10 +3,11 @@
#include "arc/graphics/sdl/sprite.h" #include "arc/graphics/sdl/sprite.h"
#include "arc/graphics/sdl/spritesheet.h" #include "arc/graphics/sdl/spritesheet.h"
#include "arc/graphics/sdl/renderer.h" #include "arc/graphics/sdl/renderer.h"
#include "arc/math/point.h"
#include "arc/math/rectangle.h" #include "arc/math/rectangle.h"
#include <stdlib.h> #include <stdlib.h>
void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Rect *frames){ void ARC_Sprite_Create(ARC_Sprite **sprite, ARC_Spritesheet *spritesheet, ARC_Array *frames){
*sprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite)); *sprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite));
(*sprite)->spritesheet = spritesheet; (*sprite)->spritesheet = spritesheet;
(*sprite)->frames = frames; (*sprite)->frames = frames;
@ -18,21 +19,33 @@ void ARC_Sprite_Destroy(ARC_Sprite *sprite){
free(sprite); free(sprite);
} }
void ARC_Sprite_Copy(ARC_Sprite **newSprite, ARC_Sprite *oldSprite){
*newSprite = (ARC_Sprite *)malloc(sizeof(ARC_Sprite));
(*newSprite)->spritesheet = oldSprite->spritesheet;
(*newSprite)->frames = oldSprite->frames;
(*newSprite)->frameIndex = (uint32_t *)malloc(sizeof(uint32_t));
*(*newSprite)->frameIndex = *oldSprite->frameIndex;
}
void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds){ void ARC_Sprite_Render(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds){
ARC_Rect *temp = &sprite->frames[*sprite->frameIndex]; ARC_Rect *temp = (ARC_Rect *)sprite->frames->data + *sprite->frameIndex;
SDL_RenderCopy(renderer->renderer, sprite->spritesheet->texture, (SDL_Rect *)&sprite->frames[*sprite->frameIndex], (SDL_Rect *)renderBounds); SDL_RenderCopy(renderer->renderer, sprite->spritesheet->texture, (SDL_Rect *)sprite->frames->data + *sprite->frameIndex, (SDL_Rect *)renderBounds);
}
void ARC_Sprite_RenderRotated(ARC_Sprite *sprite, ARC_Renderer *renderer, ARC_Rect *renderBounds, ARC_Point *center, double angle){
SDL_RenderCopyEx(renderer->renderer, sprite->spritesheet->texture, (SDL_Rect *)sprite->frames->data + *sprite->frameIndex, (SDL_Rect *)renderBounds, angle, (SDL_Point *)center, SDL_FLIP_NONE);
} }
void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){ void ARC_Sprite_IterateFrame(ARC_Sprite *sprite){
++*sprite->frameIndex; ++*sprite->frameIndex;
if(*sprite->frameIndex == *sprite->frameSize){ if(*sprite->frameIndex == *sprite->frames->size){
*sprite->frameIndex = 0; *sprite->frameIndex = 0;
} }
} }
ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){ ARC_Rect *ARC_Sprite_GetBounds(ARC_Sprite *sprite){
return sprite->frames + *sprite->frameIndex; return (ARC_Rect *)sprite->frames->data + *sprite->frameIndex;
} }
#endif // ARC_SDL #endif // ARC_SDL

18
src/math/rectangle.c Normal file
View file

@ -0,0 +1,18 @@
#include "arc/math/rectangle.h"
//VERY TEMP
#include <SDL.h>
int32_t ARC_Rect_Intersects(ARC_Rect *rect1, ARC_Rect *rect2){
if(rect1->x <= rect2->x + rect2->w && rect1->x + rect1->w >= rect2->x &&
rect1->y <= rect2->y + rect2->h && rect1->y + rect1->h >= rect2->y){
return 1;
}
return 0;
}
int32_t ARC_Rect_LineIntersects(ARC_Rect *rect, int32_t *x1, int32_t *y1, int32_t *x2, int32_t *y2){
//TODO: Replace soon
return SDL_IntersectRectAndLine((SDL_Rect *) rect, x1, y1, x2, y2);
}

View file

@ -1,8 +1,11 @@
#include "arc/std/config.h" #include "arc/std/config.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include "arc/std/hashtable.h"
#include "arc/std/io.h" #include "arc/std/io.h"
#include "arc/std/string.h"
#include <stdio.h> #include <stdio.h>
#include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
@ -20,72 +23,53 @@ typedef struct ARC_ConfigKey {
} ARC_ConfigKey; } ARC_ConfigKey;
typedef struct ARC_ConfigTypeTemplate { typedef struct ARC_ConfigTypeTemplate {
ARC_ConfigKey *key; ARC_ConfigKeyDelete Delete;
void *data; void *data;
} ARC_ConfigTypeTemplate; } ARC_ConfigTypeTemplate;
typedef struct ARC_DeleteUserData { typedef struct ARC_ConfigDeleteKeyArgs {
ARC_Config *config; ARC_Config *config;
ARC_String *string;
} ARC_ConfigDeleteKeyArgs;
const char* data; int8_t ARC_Config_KeyComp(void *key1, size_t *key1size, void *key2, size_t *key2size);
ARC_StringSubstr *subdata;
} ARC_DeleteUserData;
int32_t ARC_Config_KeyComp(void *key1, size_t *key1size, void *key2, size_t *key2size){ void ARC_Config_CreateGroup(ARC_Config *config, ARC_String *name);
if(*key1size - *key2size){ return -1; } void ARC_Config_DestroyGroup(ARC_HashtableNode *group, void *userdata);
return strncmp((const char *)key1, (const char *)key2, *key1size);
void ARC_Config_DestroyGroupNode(ARC_HashtableNode *node , void *userdata);
void ARC_Config_RemoveKey(ARC_HashtableNode *node, void *userdata);
void ARC_Config_AddKey(ARC_Config *config, ARC_String *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete){
ARC_ConfigKey *newKey = (ARC_ConfigKey *)malloc(sizeof(ARC_ConfigKey));
newKey->Read = keyRead;
newKey->Delete = keyDelete;
char *typeval = (char *)malloc(sizeof(char) * type->length);
strncpy(typeval, type->data, type->length);
ARC_Hashtable_Add(config->keys, (void *)typeval, type->length, newKey);
} }
int32_t ARC_ConfigKey_Add(ARC_Config *config, char *type, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete){ void ARC_Config_AddKeyCString(ARC_Config *config, const char *type, uint64_t length, ARC_ConfigKeyRead keyRead, ARC_ConfigKeyDelete keyDelete){
ARC_ConfigKey *temp = (ARC_ConfigKey *)malloc(sizeof(ARC_ConfigKey)); ARC_ConfigKey *newKey = (ARC_ConfigKey *)malloc(sizeof(ARC_ConfigKey));
temp->Read = keyRead; newKey->Read = keyRead;
temp->Delete = keyDelete; newKey->Delete = keyDelete;
return ARC_Hashtable_Add(config->keys, (void *)type, strlen(type), (void *)temp);
char *typeval = (char *)malloc(sizeof(char) * length);
strncpy(typeval, type, length);
ARC_Hashtable_Add(config->keys, (void *)typeval, length, newKey);
} }
int32_t ARC_ConfigKey_Destroy(ARC_HashtableNode *node, void *userdata){ void ARC_Config_Create(ARC_Config **config){
if(!node->data){ return ARC_ERRNO_NULL; }
free((ARC_ConfigKey *)node->data);
return 0;
}
int32_t ARC_ConfigGroup_Create(ARC_Config *config, const char *name){
ARC_Hashtable *data;
ARC_Hashtable_Create(&data, ARC_GROUP_DATA_BUCKET_SIZE, NULL, ARC_Config_KeyComp);
char *group = (char *) malloc(sizeof(char) * strlen(name));
strncpy(group, name, strlen(name));
return ARC_Hashtable_Add(config->groups, (void *)group, strlen(name), (void *)data);
}
int32_t ARC_ConfigGroupNode_Destroy(ARC_HashtableNode *node, void *userdata){
free((char *)node->key);
ARC_ConfigTypeTemplate *temp = (ARC_ConfigTypeTemplate *)node->data;
if(temp->key){
ARC_DeleteUserData *deldata = (ARC_DeleteUserData *)userdata;
temp->key->Delete(deldata->config, deldata->data, deldata->subdata, temp->data);
}
free(temp);
return 0;
}
int32_t ARC_ConfigGroup_Destroy(ARC_HashtableNode *group, void *userdata){
free((char *)group->key);
return ARC_Hashtable_Destroy((ARC_Hashtable *)group->data, ARC_ConfigGroupNode_Destroy, userdata);
}
int32_t ARC_Config_Create(ARC_Config **config, ARC_ConfigKey_AddFunc keysAdd){
*config = (ARC_Config *)malloc(sizeof(ARC_Config)); *config = (ARC_Config *)malloc(sizeof(ARC_Config));
(*config)->currgroup = NULL; (*config)->currgroup = NULL;
ARC_Hashtable *groups; ARC_Hashtable *groups;
ARC_Hashtable_Create(&groups, ARC_GROUP_BUCKET_SIZE, NULL, ARC_Config_KeyComp); ARC_Hashtable_Create(&groups, ARC_GROUP_BUCKET_SIZE, NULL, ARC_Config_KeyComp);
(*config)->groups = groups; (*config)->groups = groups;
ARC_ConfigGroup_Create(*config, ""); ARC_Config_CreateGroup(*config, NULL);
ARC_Hashtable *keys; ARC_Hashtable *keys;
ARC_Hashtable_Create(&keys, ARC_KEY_BUCKET_SIZE, NULL, ARC_Config_KeyComp); ARC_Hashtable_Create(&keys, ARC_KEY_BUCKET_SIZE, NULL, ARC_Config_KeyComp);
@ -94,323 +78,528 @@ int32_t ARC_Config_Create(ARC_Config **config, ARC_ConfigKey_AddFunc keysAdd){
#ifdef ARC_DEFAULT_CONFIG #ifdef ARC_DEFAULT_CONFIG
ARC_Defaults_ConfigKey_Create(*config); ARC_Defaults_ConfigKey_Create(*config);
#endif #endif
if(keysAdd){ keysAdd(*config); }
return 0;
} }
int32_t ARC_Config_Destroy(ARC_Config *config){ void ARC_Config_Destroy(ARC_Config *config){
ARC_DeleteUserData deldata = { .config = config, .data = NULL, .subdata = NULL }; ARC_ConfigDeleteKeyArgs keyArgs = {
int32_t err = ARC_Hashtable_Destroy(config->groups, ARC_ConfigGroup_Destroy, (void *)&deldata); .config = config,
if(err){ return err; } .string = NULL,
};
err = ARC_Hashtable_Destroy(config->keys, ARC_ConfigKey_Destroy, NULL);
if(err){ return err; }
ARC_Hashtable_Destroy(config->groups, ARC_Config_DestroyGroup, (void *)&keyArgs);
ARC_Hashtable_Destroy(config->keys , ARC_Config_RemoveKey , NULL );
free(config); free(config);
return 0;
} }
int32_t ARC_Config_Get(ARC_Config *config, char *keyname, void **value){ //TODO: fix NULL group
uint64_t len = 0; void ARC_Config_SetGroup(ARC_Config *config, ARC_String *groupname){
ARC_ConfigTypeTemplate *temp; if(!config){
int32_t err = ARC_String_Find(keyname, (char *)"::", &len);
if(err){ return err; }
if(len != ~((uint64_t)0)){
char group[len + 1];
strncpy(group, keyname, len);
group[len] = '\0';
ARC_Hashtable *currgroup = config->currgroup;
err = ARC_Config_SetGroup(config, group);
if(err){ return err; }
char *namestr = (len + 2) + keyname;
char name[strlen(namestr)];
strcpy(name, namestr);
err = ARC_Hashtable_Get(config->currgroup, (void *)name, strlen(name), (void **)&temp);
if(err){ return err; }
config->currgroup = currgroup;
*value = temp->data;
return 0;
}
err = ARC_Hashtable_Get(config->currgroup, (void *)keyname, strlen(keyname), (void **)&temp);
if(err){ return err; }
*value = temp->data;
return 0;
}
int32_t ARC_Config_Remove(ARC_Config *config, const char *keyname, const char* data, ARC_StringSubstr *subdata){
ARC_DeleteUserData deldata = { .config = config, .data = data, .subdata = subdata };
return ARC_Hashtable_Remove(config->currgroup, (void *)keyname, strlen(keyname), ARC_ConfigGroupNode_Destroy, (void *)&deldata);
}
int32_t ARC_Config_SetGroup(ARC_Config *config, char *groupstr){
int err = ARC_Hashtable_Get(config->groups, groupstr, strlen(groupstr), (void **)&(config->currgroup));
if(err && err != ARC_ERRNO_NULL){ return err; }
if(!(config->currgroup)){
err = ARC_ConfigGroup_Create(config, groupstr);
if(err){ return err; }
err = ARC_Hashtable_Get(config->groups, groupstr, strlen(groupstr), (void **)&(config->currgroup));
if(err){ return err; }
}
return 0;
}
void ARC_ConfigPath_Create(char *data, ARC_StringSubstr *subpath, char **path){
if(*(data + subpath->index) == '~'){
*path = (char *) malloc(sizeof(char) * (subpath->length + strlen(ARC_HOME_PATH) + 1));
strcpy(*path, ARC_HOME_PATH);
strncpy((*path) + strlen(ARC_HOME_PATH) - 1, data + subpath->index, subpath->length);
(*path)[subpath->length + strlen(ARC_HOME_PATH)] = '\0';
return; return;
} }
*path = (char *) malloc(sizeof(char) * (subpath->length + 1)); if(groupname == NULL){
strncpy(*path, data + subpath->index, subpath->length); ARC_Hashtable_Get(config->groups, (void *)" ", 1, (void **)&(config->currgroup));
(*path)[subpath->length] = '\0'; return;
} }
void ARC_ConfigPath_Destroy(char *url){ ARC_Hashtable_Get(config->groups, (void *)groupname->data, groupname->length, (void **)&(config->currgroup));
free(url); if(arc_errno && arc_errno != ARC_ERRNO_NULL){
return;
} }
int32_t ARC_Config_Recurse(ARC_Config *config, char *data, uint64_t *size, char *groupstr, ARC_StringSubstr *subkey, uint8_t *command); if(config->currgroup){
return;
int32_t ARC_ConfigKey_Command(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey){
ARC_StringSubstr subcommand = { subkey->index + 1, 0 };
int32_t err = ARC_String_Find(data + subcommand.index, " ", &(subcommand.length));
if(err){ return err; }
if(subcommand.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
subkey->index += subcommand.length + 1;
ARC_StringSubstr_StripEnds(data, NULL, &subcommand);
if(strncmp("load", data + subcommand.index, strlen("load")) && strncmp("unload", data + subcommand.index, strlen("unload"))){ return ARC_ERRNO_DATA; }
ARC_StringSubstr subpath = { subkey->index, 0 };
err = ARC_String_Find(data + subpath.index, (char *)"\"", &(subpath.index));
if(err){ return err; }
if(subpath.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
subkey->index += subpath.length + 2; //we want to skip over the first \" that is why it is 2 not 1
subpath = (ARC_StringSubstr) { subkey->index, 0 };
err = ARC_String_Find(data + subpath.index, (char *)"\"", &(subpath.length));
if(err){ return err; }
if(subpath.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
subkey->index += subpath.length + 1;
char *path;
ARC_ConfigPath_Create(data, &subpath, &path);
if (!strncmp( "load", data + subcommand.index, strlen( "load"))){ err = ARC_Config_FileIO(config, path, ARC_CONFIG_FILE_IO_LOAD ); }
else if(!strncmp("unload", data + subcommand.index, strlen("unload"))){ err = ARC_Config_FileIO(config, path, ARC_CONFIG_FILE_IO_UNLOAD); }
else { return ARC_ERRNO_DATA; }
ARC_ConfigPath_Destroy(path);
return err;
} }
int32_t ARC_ConfigKey_Comment(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey){ ARC_Config_CreateGroup(config, groupname);
uint64_t commentlen = 0; if(arc_errno){
if(data[subkey->index + 1] == '*'){ return;
int32_t err = ARC_String_Find(data + subkey->index, (char *)"*/", &commentlen);
if(err){ return err; }
subkey->index += commentlen + 1;
return 0;
} }
int32_t err = ARC_String_Find(data + subkey->index, (char *)"\n", &commentlen); ARC_Hashtable_Get(config->groups, (void *)groupname->data, groupname->length, (void **)&(config->currgroup));
if(err){ return err; }
subkey->index += commentlen + 1;
return 0;
} }
int32_t ARC_ConfigKey_Group(ARC_Config *config, char *data, uint64_t *size, ARC_StringSubstr *subkey, uint8_t *command){ void ARC_Config_Get(ARC_Config *config, ARC_String *keyname, void **value){
ARC_StringSubstr subgroup = { subkey->index, 0 }; ARC_ConfigTypeTemplate *temp = NULL;
int32_t err = ARC_String_Find(data + subgroup.index, "{", &(subgroup.length));
if(err){ return err; }
if(subgroup.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
subkey->index += subgroup.length + 1;
ARC_StringSubstr_StripEnds(data, NULL, &subgroup); uint64_t length = ARC_String_FindCString(keyname, "::", 2);
if(arc_errno){
char groupstr[subgroup.length + 1]; //TODO: Debug info here
strncpy(groupstr, data + subgroup.index, subgroup.length); ARC_DEBUG_ERR("in ARC_Config_Get(config, keyname, value); length threw error");
groupstr[subgroup.length] = '\0'; *value = NULL;
return;
return ARC_Config_Recurse(config, data, size, groupstr, subkey, command);
} }
int32_t ARC_ConfigKey_Load(ARC_Config *config, char *data, uint64_t *size, char *keyname, ARC_StringSubstr *subkey){ if(length != ~((uint64_t)0)){
length--;
ARC_String *group = NULL;
if(length != 0){
ARC_String_CopySubstring(&group, keyname, 0, length);
}
ARC_Hashtable *currgroup = config->currgroup;
ARC_Config_SetGroup(config, group);
if(arc_errno){
ARC_DEBUG_ERR("in ARC_Config_Get(config, keyname, value); setting group threw error");
ARC_String_Destroy(group);
*value = NULL;
return;
}
ARC_String *name;
ARC_String_CopySubstring(&name, keyname, length + 2, keyname->length - (length + 2));
ARC_Hashtable_Get(config->currgroup, (void *)name->data, name->length, (void **)&temp);
ARC_String_Destroy(name);
config->currgroup = currgroup;
if(group){
ARC_String_Destroy(group);
}
*value = temp->data;
return;
}
if(!keyname){
*value = NULL;
return;
}
ARC_Hashtable_Get(config->currgroup, (void *)keyname->data, keyname->length, (void **)&temp);
if(arc_errno || temp == NULL){
*value = NULL;
return;
}
*value = temp->data;
}
void ARC_Config_Recurse(ARC_Config *config, ARC_String **data, ARC_String *groupstr, uint8_t *command);
void ARC_Config_SetKeyGroup(ARC_Config *config, ARC_String **data, uint8_t *command){
uint64_t index = ARC_String_FindCString(*data, " ", 1);
uint64_t nextIndex = ARC_String_FindCString(*data, "{", 1);
if(index == ~(uint64_t)0 || nextIndex == ~(uint64_t)0){
arc_errno = ARC_ERRNO_DATA;
}
if(arc_errno){
return;
}
ARC_String *name, *temp;
ARC_String_CopySubstring(&temp, *data, index, nextIndex - index - 1);
ARC_String_StripEndsWhitespace(temp, &name);
ARC_String_Destroy(temp);
temp = *data;
ARC_String_CopySubstring(data, temp, nextIndex + 1, (*data)->length - (nextIndex + 1));
ARC_String_Destroy(temp);
ARC_Config_Recurse(config, data, name, command);
ARC_String_Destroy(name);
}
void ARC_Config_LoadFromKey(ARC_Config *config, ARC_String *keyType, ARC_String *name, ARC_String *value){
ARC_ConfigKey *key; ARC_ConfigKey *key;
int32_t err = ARC_Hashtable_Get(config->keys, (void *)keyname, strlen(keyname), (void **)&key); ARC_Hashtable_Get(config->keys, keyType->data, keyType->length, (void **)&key);
if(err){ return err; } if(key == NULL){
arc_errno = ARC_ERRNO_DATA;
ARC_StringSubstr subname = { subkey->index, 0 };
err = ARC_String_Find(data + subname.index, (char *)"=", &(subname.length));
if(err){ return err; }
if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
subkey->index += subname.length + 1;
ARC_StringSubstr_StripEnds(data, NULL, &subname);
ARC_StringSubstr subvalue = { subkey->index, 0 };
err = ARC_String_Find(data + subvalue.index, (char *)";", &(subvalue.length));
if(err){ return err; }
if(subvalue.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
subkey->index += subvalue.length + 1;
ARC_StringSubstr_StripEnds(data, NULL, &subvalue);
ARC_ConfigTypeTemplate *templateVal = NULL;
char *name = malloc(sizeof(char) * subname.length + 1);
strncpy(name, data + subname.index, sizeof(char) * subname.length);
name[subname.length] = '\0';
templateVal = (ARC_ConfigTypeTemplate *) malloc(sizeof(ARC_ConfigTypeTemplate));
templateVal->key = NULL;
templateVal->data = ARC_Config_GetReference(config, data, &subvalue);
if(!templateVal->data){
err = key->Read(config, data, &subvalue, &(templateVal->data));
if(err){ return err; }
templateVal->key = key;
} }
return ARC_Hashtable_Add(config->currgroup, (void *)name, strlen(name), (void *)templateVal); if(arc_errno){
return;
} }
int32_t ARC_ConfigKey_Unload(ARC_Config *config, char *data, uint64_t *size, char *keyname, ARC_StringSubstr *subkey){ ARC_ConfigTypeTemplate *templateVal = (ARC_ConfigTypeTemplate *) malloc(sizeof(ARC_ConfigTypeTemplate));
ARC_StringSubstr subname = { subkey->index, 0 }; templateVal->Delete = NULL;
int32_t err = ARC_String_Find(data + subname.index, (char *)"=", &(subname.length)); templateVal->data = NULL;
if(err){ return err; }
if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
subkey->index += subname.length + 1;
ARC_StringSubstr_StripEnds(data, NULL, &subname); uint8_t reference = key->Read(config, value, &(templateVal->data));
char name[subname.length + 1]; if(!reference){
strncpy(name, data + subname.index, subname.length); templateVal->Delete = key->Delete;
name[subname.length] = '\0'; }
subname = (ARC_StringSubstr){ subkey->index, 0 }; if(arc_errno){
err = ARC_String_Find(data + subname.index, (char *)";", &(subname.length)); return;
if(err){ return err; } }
if(subname.length == ~((uint64_t)0)){ return ARC_ERRNO_DATA; }
subkey->index += subname.length + 1; char *nameval = (char *)malloc(sizeof(char) * name->length + 1);
strncpy(nameval, name->data, name->length);
return ARC_Config_Remove(config, name, data, &subname); nameval[name->length] = '\0';
ARC_Hashtable_Add(config->currgroup, nameval, name->length, (void *)templateVal);
}
void ARC_Config_UnloadFromKey(ARC_Config *config, ARC_String *keyType, ARC_String *name, ARC_String *value){
ARC_ConfigDeleteKeyArgs keyArgs = {
.config = config,
.string = value,
};
ARC_Hashtable_Remove(config->currgroup, name->data, name->length, ARC_Config_DestroyGroupNode, &keyArgs);
}
void ARC_Config_GetNameAndValue(ARC_String *data, ARC_String **name, ARC_String **value){
uint64_t index = ARC_String_FindCString(data, "=", 1);
if(arc_errno || index == ~(uint64_t)0){
*name = NULL;
*value = NULL;
return;
}
ARC_String_CopySubstring(name, data, 0, index - 1);
index++;
ARC_String *dataTemp = *name;
ARC_String_StripEndsWhitespace(dataTemp, name);
ARC_String_Destroy(dataTemp);
ARC_String_CopySubstring(&dataTemp, data, index, data->length - index);
ARC_String_StripEndsWhitespace(dataTemp, value);
ARC_String_Destroy(dataTemp);
}
void ARC_Config_Recurse(ARC_Config *config, ARC_String **data, ARC_String *groupstr, uint8_t *command){
ARC_Config_SetGroup(config, groupstr);
if(arc_errno){
return;
} }
int32_t ARC_Config_Recurse(ARC_Config *config, char *data, uint64_t *size, char *groupstr, ARC_StringSubstr *subkey, uint8_t *command){
int32_t err = ARC_Config_SetGroup(config, groupstr);
if(err){ return err; }
ARC_Hashtable *group = config->currgroup; ARC_Hashtable *group = config->currgroup;
while(subkey->index < *size){ while(*data && (*data)->length){
if(data[subkey->index] == ' ' || data[subkey->index] == '\n' || data[subkey->index] == '\t' || data[subkey->index] == '\r'){ ARC_String *dataTemp = *data;
subkey->index++; ARC_String_StripEndsWhitespace(dataTemp, data);
continue; ARC_String_Destroy(dataTemp);
}
if(data[subkey->index] == '}'){ // break out of current group
if((*data)->data[0] == '}'){
config->currgroup = NULL; config->currgroup = NULL;
subkey->index++;
return 0; dataTemp = *data;
ARC_String_CopySubstring(data, dataTemp, 1, dataTemp->length - 1);
ARC_String_Destroy(dataTemp);
return;
} }
if(data[subkey->index] == '#'){ // set group
err = ARC_ConfigKey_Command(config, data, size, subkey);
if(err){ return err; }
continue;
}
if(data[subkey->index] == '/'){
err = ARC_ConfigKey_Comment(config, data, size, subkey);
if(err){ return err; }
continue;
}
err = ARC_String_Find(data + subkey->index, (char *)" ", &(subkey->length));
if(err){ return err; }
if(subkey->length == ~((uint64_t)0)){ return 0; }
if(!(config->currgroup)){ if(!(config->currgroup)){
config->currgroup = group; config->currgroup = group;
} }
char keyname[subkey->length + 1]; // get keys type
strncpy(keyname, data + subkey->index, subkey->length); uint64_t index = ARC_String_FindCString(*data, " ", 1);
keyname[subkey->length] = '\0'; if(arc_errno || index == ~(uint64_t)0){
subkey->index += subkey->length + 1; return;
}
ARC_String *keyType, *keyTypeTemp;
ARC_String_CopySubstring(&keyTypeTemp, *data, 0, index);
ARC_String_StripEndsWhitespace(keyTypeTemp, &keyType);
ARC_String_Destroy(keyTypeTemp);
if(ARC_String_EqualsCString(keyType, "group", 5)){
ARC_Config_SetKeyGroup(config, data, command);
ARC_String_Destroy(keyType);
config->currgroup = group;
if(arc_errno){
return;
}
if(subkey->length == strlen("group") && !strcmp(keyname, "group")){
err = ARC_ConfigKey_Group(config, data, size, subkey, command);
if(err){ return err; }
continue; continue;
} }
// get and copy up to the ;
ARC_String *nameAndValue;
uint64_t nextIndex = ARC_String_FindCString(*data, ";", 1);
if(nextIndex == ~(uint64_t)0){
arc_errno = ARC_ERRNO_DATA;
}
if(arc_errno){
ARC_String_Destroy(keyType);
return;
}
ARC_String_CopySubstring(&nameAndValue, *data, index, nextIndex - (index + 1));
if(arc_errno){
ARC_String_Destroy(keyType);
return;
}
// remove up to the ; from data string
dataTemp = *data;
ARC_String_CopySubstring(data, dataTemp, nextIndex, (*data)->length - nextIndex);
ARC_String_Destroy(dataTemp);
if(arc_errno){
ARC_String_Destroy(keyType);
ARC_String_Destroy(nameAndValue);
return;
}
// get name and value of string
ARC_String *name, *value;
ARC_Config_GetNameAndValue(nameAndValue, &name, &value);
ARC_String_Destroy(nameAndValue);
if(arc_errno){
ARC_String_Destroy(keyType);
return;
}
// load from key
if(*command == ARC_CONFIG_FILE_IO_LOAD){ if(*command == ARC_CONFIG_FILE_IO_LOAD){
err = ARC_ConfigKey_Load(config, data, size, keyname, subkey); ARC_Config_LoadFromKey(config, keyType, name, value);
if(err){ return err; }
ARC_String_Destroy(keyType);
ARC_String_Destroy(name );
ARC_String_Destroy(value );
if(arc_errno){
return;
}
continue; continue;
} }
// unload from key
if(*command == ARC_CONFIG_FILE_IO_UNLOAD){ if(*command == ARC_CONFIG_FILE_IO_UNLOAD){
err = ARC_ConfigKey_Unload(config, data, size, keyname, subkey); ARC_Config_UnloadFromKey(config, keyType, name, value);
if(err){ return err;}
ARC_String_Destroy(keyType);
ARC_String_Destroy(name );
ARC_String_Destroy(value );
if(arc_errno){
return;
}
continue; continue;
} }
return ARC_ERRNO_DATA; // config file wasn't loaded correctly
ARC_String_Destroy(keyType);
ARC_String_Destroy(name );
ARC_String_Destroy(value );
arc_errno = ARC_ERRNO_DATA;
return;
} }
config->currgroup = group; config->currgroup = group;
return 0;
} }
int32_t ARC_Config_FileIO(ARC_Config *config, const char *pathstr, uint8_t command){ void ARC_Config_StripComment(ARC_String *original, ARC_String **stripped, ARC_String *lineStart, ARC_String *lineEnd){
char *path, *data; ARC_String *current = NULL;
uint64_t size; ARC_String_Copy(&current, original);
ARC_StringSubstr subpath = { 0, strlen(pathstr) };
ARC_ConfigPath_Create((char *)pathstr, &subpath, &path);
int32_t err = ARC_IO_FileToStr(path, &data, &size); uint64_t index = ARC_String_Find(original, lineStart);
if(err){ while(index != ~(uint64_t)0){
ARC_DEBUG_LOG(err, "ARC_IO_FileToStr(%s, &data, &size);\n", path); ARC_String *commentString;
ARC_ConfigPath_Destroy(path); ARC_String_CopySubstring(&commentString, current, index + lineStart->length, current->length - (index + lineStart->length));
return err;
uint64_t endIndex = ARC_String_Find(commentString, lineEnd);
ARC_String_Destroy(commentString);
if(endIndex == ~(uint64_t)0){
ARC_DEBUG_ERR("ARC_Config_RemoveComments(original, commentRemoved); No newline found when stripping single line comment");
arc_errno = ARC_ERRNO_DATA;
ARC_String_Destroy(current);
*stripped = NULL;
break;
} }
ARC_ConfigPath_Destroy(path); ARC_String *currentTemp = current;
ARC_String_RemoveSection(&current, currentTemp, index, endIndex + lineStart->length + lineEnd->length);
ARC_String_Destroy(currentTemp);
ARC_StringSubstr subkey = { 0, 0 }; index = ARC_String_Find(current, lineStart);
err = ARC_Config_Recurse(config, data, &size, "", &subkey, &command);
if(err){ return err; }
free(data);
return 0;
} }
void *ARC_Config_GetReference(ARC_Config *config, char *data, ARC_StringSubstr *subdata){ *stripped = current;
if(ARC_String_Alpha(data + subdata->index, 1) && *(data + subdata->index) != ':'){ return NULL; } }
char refname[subdata->length + 1]; void ARC_Config_RemoveComments(ARC_String *original, ARC_String **commentRemoved){
strncpy(refname, data + subdata->index, subdata->length); ARC_String *lineStart, *lineEnd;
refname[subdata->length] = 0;
//Single Line Comment
void *value; ARC_String_Create(&lineStart, "//", 2);
int32_t err = ARC_Config_Get(config, refname, &value); ARC_String_Create(&lineEnd , "\n", 1);
return (err)? NULL : value;
ARC_String *singleLineStripped;
ARC_Config_StripComment(original, &singleLineStripped, lineStart, lineEnd);
ARC_String_Destroy(lineStart);
ARC_String_Destroy(lineEnd );
if(arc_errno){
commentRemoved = NULL;
return;
}
//Multi Line Comment
ARC_String_Create(&lineStart, "/*", 2);
ARC_String_Create(&lineEnd , "*/", 2);
ARC_Config_StripComment(singleLineStripped, commentRemoved, lineStart, lineEnd);
ARC_String_Destroy(singleLineStripped);
ARC_String_Destroy(lineStart);
ARC_String_Destroy(lineEnd );
}
void ARC_Config_RunCommand(ARC_Config *config, ARC_String *command){
ARC_String *space;
ARC_String_Create(&space, " " , 1);
uint64_t index = ARC_String_Find(command, space);
if(index == ~(uint64_t)0){
arc_errno = ARC_ERRNO_DATA;
ARC_String_Destroy(space);
return;
}
ARC_String *commandOpt;
ARC_String_CopySubstring(&commandOpt, command, 0, index);
ARC_String *commandArgTemp, *commandArg;
ARC_String_CopySubstring(&commandArgTemp, command, index + space->length, command->length - (index + space->length));
ARC_String_StripWhitespace(commandArgTemp, &commandArg);
ARC_String_Destroy(commandArgTemp);
if(ARC_String_EqualsCString(command, "load", 4)){
ARC_Config_FileIO(config, commandArg, ARC_CONFIG_FILE_IO_LOAD);
}
else if(ARC_String_EqualsCString(command, "unload", 6)){
ARC_Config_FileIO(config, commandArg, ARC_CONFIG_FILE_IO_UNLOAD);
}
else {
arc_errno = ARC_ERRNO_DATA;
}
ARC_String_Destroy(commandOpt);
ARC_String_Destroy(commandArg);
ARC_String_Destroy(space );
}
void ARC_Config_RemoveAndRunCommands(ARC_Config *config, ARC_String *original, ARC_String **commandRemoved){
ARC_String *current;
ARC_String_Copy(&current, original);
ARC_String *lineStart, *lineEnd;
ARC_String_Create(&lineStart, "#" , 1);
ARC_String_Create(&lineEnd , "\n", 1);
uint64_t index = ARC_String_Find(current, lineStart);
while(index != ~(uint64_t)0){
uint64_t endIndex = ARC_String_Find(current, lineEnd);
if(endIndex == ~(uint64_t)0){
arc_errno = ARC_ERRNO_DATA;
ARC_String_Destroy(current );
ARC_String_Destroy(lineStart);
ARC_String_Destroy(lineEnd );
*commandRemoved = NULL;
return;
}
ARC_String *command;
ARC_String_CopySubstring(&command, current, index + lineStart->length, endIndex - (index + lineStart->length));
ARC_Config_RunCommand(config, command);
ARC_String *currentTemp = current;
ARC_String_RemoveSubstring(&current, currentTemp, command);
ARC_String_Destroy(command);
ARC_String_Destroy(currentTemp);
}
ARC_String_Destroy(lineStart);
ARC_String_Destroy(lineEnd );
*commandRemoved = current;
}
void ARC_Config_FileIO(ARC_Config *config, ARC_String *path, uint8_t command){
ARC_String *data;
ARC_IO_FileToStr(path, &data);
if(arc_errno){
ARC_DEBUG_LOG(arc_errno, "ARC_IO_FileToStr(%s, &data, &size);\n", path->data);
return;
}
char *tempData = (char *)malloc(sizeof(char) * (data->length + 1));
strncpy(tempData, data->data, data->length);
tempData[data->length] = '\n';
ARC_String *temp = data;
ARC_String_Create(&temp, tempData, data->length + 1);
free(tempData);
ARC_String_Destroy(data);
ARC_Config_RemoveComments(temp, &data);
ARC_String_Destroy(temp);
temp = data;
ARC_Config_RemoveAndRunCommands(config, temp, &data);
ARC_String_Destroy(temp);
temp = data;
ARC_String_StripEndsWhitespace(temp, &data);
ARC_String_Destroy(temp);
ARC_Config_Recurse(config, &data, NULL, &command);
if(data){
ARC_String_Destroy(data);
}
}
int8_t ARC_Config_KeyComp(void *key1, size_t *key1size, void *key2, size_t *key2size){
if(*key1size - *key2size){
return -1;
}
return strncmp((const char *)key1, (const char *)key2, *key1size);
}
void ARC_Config_CreateGroup(ARC_Config *config, ARC_String *name){
ARC_Hashtable *data;
ARC_Hashtable_Create(&data, ARC_GROUP_DATA_BUCKET_SIZE, NULL, ARC_Config_KeyComp);
if(name){
char *nameval = (char *)malloc(sizeof(char) * name->length);
strncpy(nameval, name->data, name->length);
ARC_Hashtable_Add(config->groups, nameval, name->length, (void *)data);
return;
}
char *emptyGroup = (char *)malloc(sizeof(char));
emptyGroup[0] = ' ';
ARC_Hashtable_Add(config->groups, emptyGroup, 1, (void *)data);
}
void ARC_Config_DestroyGroup(ARC_HashtableNode *group, void *userdata){
free((char *)group->key);
return ARC_Hashtable_Destroy((ARC_Hashtable *)group->data, ARC_Config_DestroyGroupNode, userdata);
}
void ARC_Config_DestroyGroupNode(ARC_HashtableNode *node, void *userdata){
free((char *)node->key);
ARC_ConfigTypeTemplate *temp = (ARC_ConfigTypeTemplate *)node->data;
if(temp->Delete && temp->data && userdata){
ARC_ConfigDeleteKeyArgs *args = (ARC_ConfigDeleteKeyArgs *)userdata;
temp->Delete(args->config, args->string, temp->data);
}
free(temp);
node->data = NULL;
}
void ARC_Config_RemoveKey(ARC_HashtableNode *node, void *userdata){
free((char *)node->key);
if(!node->data){
arc_errno = ARC_ERRNO_NULL;
return;
}
free((ARC_ConfigKey *)node->data);
} }

View file

@ -1,116 +1,316 @@
#include "arc/std/string.h"
#ifdef ARC_DEFAULT_CONFIG #ifdef ARC_DEFAULT_CONFIG
#include "arc/std/defaults/config.h" #include "arc/std/defaults/config.h"
#include "arc/std/array.h"
#include "arc/std/config.h" #include "arc/std/config.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
int32_t ARC_Defaults_ConfigKey_Create(ARC_Config *config){ void ARC_Defaults_ConfigKey_Create(ARC_Config *config){
ARC_ConfigKey_Add(config, "uint8_t" , ARC_ConfigKey_Read_Uint8_t , ARC_ConfigKey_Delete_Uint8_t ); ARC_Config_AddKeyCString(config, "uint8_t" , 7, ARC_ConfigKey_Read_Uint8_t , ARC_ConfigKey_Delete_Uint8_t );
ARC_ConfigKey_Add(config, "int8_t" , ARC_ConfigKey_Read_Int8_t , ARC_ConfigKey_Delete_Int8_t ); ARC_Config_AddKeyCString(config, "int8_t" , 6, ARC_ConfigKey_Read_Int8_t , ARC_ConfigKey_Delete_Int8_t );
// ARC_ConfigKey_Add(config, "char" , ARC_ConfigKey_Read_Char , ARC_ConfigKey_Delete_Char ); ARC_Config_AddKeyCString(config, "uint16_t", 8, ARC_ConfigKey_Read_Uint16_t , ARC_ConfigKey_Delete_Uint16_t );
ARC_ConfigKey_Add(config, "uint16_t", ARC_ConfigKey_Read_Uint16_t, ARC_ConfigKey_Delete_Uint16_t); ARC_Config_AddKeyCString(config, "int16_t" , 7, ARC_ConfigKey_Read_Int16_t , ARC_ConfigKey_Delete_Int16_t );
ARC_ConfigKey_Add(config, "int16_t" , ARC_ConfigKey_Read_Int16_t , ARC_ConfigKey_Delete_Int16_t ); ARC_Config_AddKeyCString(config, "uint32_t", 8, ARC_ConfigKey_Read_Uint32_t , ARC_ConfigKey_Delete_Uint32_t );
ARC_ConfigKey_Add(config, "uint32_t", ARC_ConfigKey_Read_Uint32_t, ARC_ConfigKey_Delete_Uint32_t); ARC_Config_AddKeyCString(config, "int32_t" , 7, ARC_ConfigKey_Read_Int32_t , ARC_ConfigKey_Delete_Int32_t );
ARC_ConfigKey_Add(config, "int32_t" , ARC_ConfigKey_Read_Int32_t , ARC_ConfigKey_Delete_Int32_t ); ARC_Config_AddKeyCString(config, "uint64_t", 8, ARC_ConfigKey_Read_Uint64_t , ARC_ConfigKey_Delete_Uint64_t );
ARC_ConfigKey_Add(config, "int" , ARC_ConfigKey_Read_Int , ARC_ConfigKey_Delete_Int ); ARC_Config_AddKeyCString(config, "int64_t" , 7, ARC_ConfigKey_Read_Int64_t , ARC_ConfigKey_Delete_Int64_t );
ARC_ConfigKey_Add(config, "uint64_t", ARC_ConfigKey_Read_Uint64_t, ARC_ConfigKey_Delete_Uint64_t); // ARC_Config_AddKeyCString(config, "char" , 4, ARC_ConfigKey_Read_Char , ARC_ConfigKey_Delete_Char );
ARC_ConfigKey_Add(config, "int64_t" , ARC_ConfigKey_Read_Int64_t , ARC_ConfigKey_Delete_Int64_t ); ARC_Config_AddKeyCString(config, "int" , 3, ARC_ConfigKey_Read_Int , ARC_ConfigKey_Delete_Int );
ARC_ConfigKey_Add(config, "long" , ARC_ConfigKey_Read_Long , ARC_ConfigKey_Delete_Long ); ARC_Config_AddKeyCString(config, "long" , 4, ARC_ConfigKey_Read_Long , ARC_ConfigKey_Delete_Long );
ARC_ConfigKey_Add(config, "string" , ARC_ConfigKey_Read_String , ARC_ConfigKey_Delete_String ); ARC_Config_AddKeyCString(config, "float" , 5, ARC_ConfigKey_Read_Float , ARC_ConfigKey_Delete_Float );
return 0; ARC_Config_AddKeyCString(config, "double" , 6, ARC_ConfigKey_Read_Double , ARC_ConfigKey_Delete_Double );
ARC_Config_AddKeyCString(config, "string" , 6, ARC_ConfigKey_Read_String , ARC_ConfigKey_Delete_String );
// ARC_Config_AddKeyCString(config, "string[]", ARC_ConfigKey_Read_StringArray, ARC_ConfigKey_Delete_StringArray);
}
uint8_t ARC_ConfigKey_Read_Uint8_t(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
} }
int32_t ARC_ConfigKey_Read_Uint8_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
*value = (uint8_t *) malloc(sizeof(uint8_t)); *value = (uint8_t *) malloc(sizeof(uint8_t));
*((uint8_t *)(*value)) = (uint8_t) ARC_String_ToUint64_t(data, subdata); *((uint8_t *)(*value)) = (uint8_t) ARC_String_ToUint64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_Int8_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
uint8_t ARC_ConfigKey_Read_Int8_t(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (int8_t *) malloc(sizeof(int8_t)); *value = (int8_t *) malloc(sizeof(int8_t));
*((int8_t *)(*value)) = (int8_t) ARC_String_ToUint64_t(data, subdata); *((int8_t *)(*value)) = (int8_t) ARC_String_ToInt64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_Char(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_ConfigKey_Read_Uint16_t(ARC_Config* config, ARC_String *string, void **value){
*value = (char *) malloc(sizeof(char)); ARC_Config_Get(config, string, value);
*((char *)(* value)) = (char) *(data + subdata->index); if(*value){
return 0; return 1;
} }
int32_t ARC_ConfigKey_Read_Uint16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
*value = (uint16_t *) malloc(sizeof(uint16_t)); *value = (uint16_t *) malloc(sizeof(uint16_t));
*((uint16_t *)(*value)) = (uint16_t) ARC_String_ToUint64_t(data, subdata); *((uint16_t *)(*value)) = (uint16_t) ARC_String_ToUint64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_Int16_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_ConfigKey_Read_Int16_t(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (int16_t *) malloc(sizeof(int16_t)); *value = (int16_t *) malloc(sizeof(int16_t));
*((int16_t *)(*value)) = (int16_t) ARC_String_ToUint64_t(data, subdata); *((int16_t *)(*value)) = (int16_t) ARC_String_ToInt64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_Uint32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_ConfigKey_Read_Uint32_t(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (uint32_t *) malloc(sizeof(uint32_t)); *value = (uint32_t *) malloc(sizeof(uint32_t));
*((uint32_t *)(*value)) = (uint32_t) ARC_String_ToUint64_t(data, subdata); *((uint32_t *)(*value)) = (uint32_t) ARC_String_ToUint64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_Int32_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_ConfigKey_Read_Int32_t(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (int32_t *) malloc(sizeof(int32_t)); *value = (int32_t *) malloc(sizeof(int32_t));
*((int32_t *)(*value)) = (int32_t) ARC_String_ToUint64_t(data, subdata); *((int32_t *)(*value)) = (int32_t) ARC_String_ToInt64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_Int(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_ConfigKey_Read_Uint64_t(ARC_Config* config, ARC_String *string, void **value){
*value = (int *) malloc(sizeof(int)); ARC_Config_Get(config, string, value);
*((int *)(*value)) = (int) ARC_String_ToUint64_t(data, subdata); if(*value){
return 0; return 1;
} }
int32_t ARC_ConfigKey_Read_Uint64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
*value = (uint64_t *) malloc(sizeof(uint64_t)); *value = (uint64_t *) malloc(sizeof(uint64_t));
*((uint64_t *)(*value)) = ARC_String_ToUint64_t(data, subdata); *((uint64_t *)(*value)) = (uint64_t) ARC_String_ToUint64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_Int64_t(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_ConfigKey_Read_Int64_t(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (int64_t *) malloc(sizeof(int64_t)); *value = (int64_t *) malloc(sizeof(int64_t));
*((int64_t *)(*value)) = (int64_t) ARC_String_ToUint64_t(data, subdata); *((int64_t *)(*value)) = (int64_t) ARC_String_ToInt64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_Long(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_ConfigKey_Read_Char_t(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
if(string->length != 1){
arc_errno = ARC_ERRNO_DATA;
return 0;
}
*value = (char *) malloc(sizeof(char));
*((char *)(*value)) = string->data[0];
return 0;
}
uint8_t ARC_ConfigKey_Read_Int(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (int *) malloc(sizeof(int));
*((int *)(*value)) = (int) ARC_String_ToInt64_t(string);
return 0;
}
uint8_t ARC_ConfigKey_Read_Long(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (long *) malloc(sizeof(long)); *value = (long *) malloc(sizeof(long));
*((long *)(*value)) = (long) ARC_String_ToUint64_t(data, subdata); *((long *)(*value)) = (long) ARC_String_ToInt64_t(string);
return 0; return 0;
} }
int32_t ARC_ConfigKey_Read_String(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){ uint8_t ARC_ConfigKey_Read_Float(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (float *) malloc(sizeof(float));
*((float *)(*value)) = (float) ARC_String_ToDouble(string);
return 0;
}
uint8_t ARC_ConfigKey_Read_Double(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
*value = (double *) malloc(sizeof(double));
*((double *)(*value)) = (double) ARC_String_ToDouble(string);
return 0;
}
uint8_t ARC_ConfigKey_Read_String(ARC_Config* config, ARC_String *string, void **value){
ARC_Config_Get(config, string, value);
if(*value){
return 1;
}
ARC_String_Copy((ARC_String **)value, string);
return 0;
}
/*
void ARC_ConfigKey_Read_StringArray(ARC_Config* config, const char *data, ARC_StringSubstr *subdata, void **value){
ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata); ARC_StringSubstr_StripWhitespaceEnds((char *)data, subdata);
if(data[subdata->index] != '"' || data[subdata->index + subdata->length] != '"'){ return ARC_ERRNO_DATA; } if(data[subdata->index] != '{' || data[subdata->index + subdata->length - 1] != '}'){ return ARC_ERRNO_DATA; }
ARC_StringSubstr_StripEnds((char *)data, (char *)"\"", subdata); subdata->index++;
*value = (char *) malloc(sizeof(char) * (subdata->length + 1)); subdata->length -= 2;
strncpy((char *)(*value), data + subdata->index, subdata->length);
((char *)(*value))[subdata->length] = '\0'; uint32_t arraySize = 1;
return 0; for(uint32_t i = subdata->index; i < subdata->index + subdata->length; i++){
if(data[i] == ','){
arraySize++;
}
} }
int32_t ARC_ConfigKey_Delete_Uint8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint8_t *)value){ free((uint8_t *)value); } return 0; } *value = malloc(sizeof(char *));
int32_t ARC_ConfigKey_Delete_Int8_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int8_t *)value){ free((int8_t *)value); } return 0; } ((ARC_Array *) *value)->data = malloc(sizeof(char *) * arraySize);
int32_t ARC_ConfigKey_Delete_Char (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((char *)value){ free((char *)value); } return 0; } ((ARC_Array *) *value)->size = malloc(sizeof(uint32_t));
int32_t ARC_ConfigKey_Delete_Uint16_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint16_t *)value){ free((uint16_t *)value); } return 0; } *((ARC_Array *) *value)->size = arraySize;
int32_t ARC_ConfigKey_Delete_Int16_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int16_t *)value){ free((int16_t *)value); } return 0; }
int32_t ARC_ConfigKey_Delete_Uint32_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint32_t *)value){ free((uint32_t *)value); } return 0; } ARC_StringSubstr temp = { subdata->index, 0 };
int32_t ARC_ConfigKey_Delete_Int32_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int32_t *)value){ free((int32_t *)value); } return 0; } arraySize = 0;
int32_t ARC_ConfigKey_Delete_Int (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int *)value){ free((int *)value); } return 0; } for(uint64_t i = subdata->index; i < subdata->index + subdata->length; i++){
int32_t ARC_ConfigKey_Delete_Uint64_t(ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((uint64_t *)value){ free((uint64_t *)value); } return 0; } if(data[i] != ','){
int32_t ARC_ConfigKey_Delete_Int64_t (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((int64_t *)value){ free((int64_t *)value); } return 0; } continue;
int32_t ARC_ConfigKey_Delete_Long (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((long *)value){ free((long *)value); } return 0; } }
int32_t ARC_ConfigKey_Delete_String (ARC_Config* config, const char* data, ARC_StringSubstr *subdata, void *value){ if((char *)value){ free((char *)value); } return 0; }
temp.length = i - temp.index;
char *tempStr = (char *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!tempStr){
ARC_ConfigKey_Read_String(config, data, &temp, (void **) &tempStr);
if(arc_errno){
return arc_errno;
}
}
((char **)((ARC_Array *) *value)->data)[arraySize] = tempStr;
// ARC_ConfigKey_Delete_String(config, data, &temp, (void *)tempStr);
// if(arc_errno){
// return arc_errno;
// }
arraySize++;
temp = (ARC_StringSubstr){ i + 1, 0 };
if(arraySize == *((ARC_Array *) *value)->size){
break;
}
}
temp.length = (subdata->index + subdata->length) - temp.index;
char *tempStr = (char *)ARC_Config_GetReference(config, (char *)data, &temp);
if(!tempStr){
ARC_ConfigKey_Read_String(config, data, &temp, (void **) &tempStr);
if(arc_errno){
return arc_errno;
}
}
((char **)((ARC_Array *) *value)->data)[arraySize] = tempStr;
// ARC_ConfigKey_Delete_String(config, data, &temp, (void *)tempStr);
// if(arc_errno){
// return arc_errno;
// }
return 0;
}
*/
void ARC_ConfigKey_Delete_Uint8_t(ARC_Config *config, ARC_String *string, void *value){
free((uint8_t *)value);
}
void ARC_ConfigKey_Delete_Int8_t(ARC_Config *config, ARC_String *string, void *value){
free((int8_t *)value);
}
void ARC_ConfigKey_Delete_Uint16_t(ARC_Config *config, ARC_String *string, void *value){
free((uint16_t *)value);
}
void ARC_ConfigKey_Delete_Int16_t(ARC_Config *config, ARC_String *string, void *value){
free((int16_t *)value);
}
void ARC_ConfigKey_Delete_Uint32_t(ARC_Config *config, ARC_String *string, void *value){
free((uint32_t *)value);
}
void ARC_ConfigKey_Delete_Int32_t(ARC_Config *config, ARC_String *string, void *value){
free((int32_t *)value);
}
void ARC_ConfigKey_Delete_Uint64_t(ARC_Config *config, ARC_String *string, void *value){
free((uint64_t *)value);
}
void ARC_ConfigKey_Delete_Int64_t(ARC_Config *config, ARC_String *string, void *value){
free((int64_t *)value);
}
void ARC_ConfigKey_Delete_Char(ARC_Config *config, ARC_String *string, void *value){
free((char *)value);
}
void ARC_ConfigKey_Delete_Int(ARC_Config *config, ARC_String *string, void *value){
free((int *)value);
}
void ARC_ConfigKey_Delete_Long(ARC_Config *config, ARC_String *string, void *value){
free((long *)value);
}
void ARC_ConfigKey_Delete_Float(ARC_Config *config, ARC_String *string, void *value){
free((float *)value);
}
void ARC_ConfigKey_Delete_Double(ARC_Config *config, ARC_String *string, void *value){
free((double *)value);
}
void ARC_ConfigKey_Delete_String(ARC_Config *config, ARC_String *string, void *value){
ARC_String_Destroy((ARC_String *)value);
}
#endif //ARC_DEFAULT_CONFIG #endif //ARC_DEFAULT_CONFIG

View file

@ -11,7 +11,7 @@ struct ARC_Hashtable {
ARC_Hashtable_KeyCompare compare; ARC_Hashtable_KeyCompare compare;
}; };
int32_t CRC32(void *key, size_t *keysize, uint32_t *hashval){ void CRC32(void *key, size_t *keysize, uint32_t *hashval){
*hashval = 0xffffffff; *hashval = 0xffffffff;
for(size_t i = 0; i < *keysize; i++){ for(size_t i = 0; i < *keysize; i++){
@ -25,10 +25,9 @@ int32_t CRC32(void *key, size_t *keysize, uint32_t *hashval){
} }
*hashval = ~*hashval; *hashval = ~*hashval;
return 0;
} }
int32_t ARC_Default_Key_Compare(void *key1, size_t *key1size, void *key2, size_t *key2size){ int8_t ARC_Default_Key_Compare(void *key1, size_t *key1size, void *key2, size_t *key2size){
return key1 - key2; return key1 - key2;
} }
@ -40,17 +39,18 @@ void ARC_HashtableNode_Create(ARC_HashtableNode **node, void *key, size_t *keysi
(*node)->node = NULL; (*node)->node = NULL;
} }
int32_t ARC_HashtableNode_Destroy(ARC_HashtableNode *node, ARC_HashtableNode_DestroyExternal external, void *userdata){ void ARC_HashtableNode_Destroy(ARC_HashtableNode *node, ARC_HashtableNode_DestroyExternal external, void *userdata){
if(node == NULL){ return 0; } if(node == NULL){
return;
}
ARC_HashtableNode_Destroy(node->node, external, userdata); ARC_HashtableNode_Destroy(node->node, external, userdata);
if(external){ if(external){
int32_t err = external(node, userdata); external(node, userdata);
if(err){ return err; }
} }
free(node); free(node);
return 0;
} }
void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hashtable_Hash hash, ARC_Hashtable_KeyCompare compare){ void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hashtable_Hash hash, ARC_Hashtable_KeyCompare compare){
@ -61,89 +61,93 @@ void ARC_Hashtable_Create(ARC_Hashtable **htable, uint32_t bucketsize, ARC_Hasht
(*htable)->compare = (compare)? compare : ARC_Default_Key_Compare; (*htable)->compare = (compare)? compare : ARC_Default_Key_Compare;
} }
int32_t ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata){ void ARC_Hashtable_Destroy(ARC_Hashtable *htable, ARC_HashtableNode_DestroyExternal external, void *userdata){
for(uint32_t i = 0; i < htable->size; i++){ for(uint32_t i = 0; i < htable->size; i++){
if(htable->nodes[i]){ if(htable->nodes[i]){
int32_t err = ARC_HashtableNode_Destroy(htable->nodes[i], external, userdata); ARC_HashtableNode_Destroy(htable->nodes[i], external, userdata);
if(err){ return err; }
} }
} }
free(htable->nodes); free(htable->nodes);
free(htable); free(htable);
return 0;
} }
int32_t ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data){ void ARC_Hashtable_Add(ARC_Hashtable *htable, void *key, size_t keysize, void *data){
uint32_t size = 0; uint32_t size = 0;
int32_t err = htable->hash(key, &keysize, &size); htable->hash(key, &keysize, &size);
if(err){ return err; }
ARC_HashtableNode *bucket = htable->nodes[size % htable->size]; ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
if(!bucket){ if(!bucket){
ARC_HashtableNode_Create(&bucket, key, &keysize, data); ARC_HashtableNode_Create(&bucket, key, &keysize, data);
htable->nodes[size % htable->size] = bucket; htable->nodes[size % htable->size] = bucket;
return 0; return;
} }
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){ return ARC_ERRNO_EXISTS; } if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
arc_errno = ARC_ERRNO_EXISTS;
return;
}
while(bucket->node){ while(bucket->node){
if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){ return ARC_ERRNO_EXISTS; } if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){
arc_errno = ARC_ERRNO_EXISTS;
return;
}
bucket = bucket->node; bucket = bucket->node;
} }
ARC_HashtableNode_Create(&(bucket->node), key, &keysize, data); ARC_HashtableNode_Create(&(bucket->node), key, &keysize, data);
return 0;
} }
int32_t ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data){ void ARC_Hashtable_Get(ARC_Hashtable *htable, void *key, size_t keysize, void **data){
uint32_t size = 0; uint32_t size = 0;
int32_t err = htable->hash(key, &keysize, &size); htable->hash(key, &keysize, &size);
if(err){ return err; }
ARC_HashtableNode *bucket = htable->nodes[size % htable->size]; ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
if(!bucket){ if(!bucket){
*data = NULL; *data = NULL;
return ARC_ERRNO_NULL; arc_errno = ARC_ERRNO_NULL;
return;
} }
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){ if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
*data = bucket->data; *data = bucket->data;
return 0; return;
} }
while(bucket->node){ while(bucket->node){
if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){ if(!htable->compare(bucket->node->key, &bucket->node->keysize, key, &keysize)){
*data = bucket->node->data; *data = bucket->node->data;
return 0; return;
} }
bucket = bucket->node; bucket = bucket->node;
} }
return ARC_ERRNO_NULL; arc_errno = ARC_ERRNO_NULL;
} }
int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata){ void ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, ARC_HashtableNode_DestroyExternal external, void *userdata){
uint32_t size = 0; uint32_t size = 0;
int32_t err = htable->hash(key, &keysize, &size); htable->hash(key, &keysize, &size);
if(err){ return err; }
ARC_HashtableNode *bucket = htable->nodes[size % htable->size]; ARC_HashtableNode *bucket = htable->nodes[size % htable->size];
if(!bucket){ return ARC_ERRNO_NULL; } if(!bucket){
arc_errno = ARC_ERRNO_NULL;
return;
}
if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){ if(!htable->compare(bucket->key, &bucket->keysize, key, &keysize)){
ARC_HashtableNode *temp = bucket; ARC_HashtableNode *temp = bucket;
htable->nodes[size % htable->size] = bucket->node; htable->nodes[size % htable->size] = bucket->node;
if(external){ if(external){
err = external(temp, userdata); external(temp, userdata);
if(err){ return err; }
} }
free(temp); free(temp);
return 0; return;
} }
while(bucket->node){ while(bucket->node){
@ -152,16 +156,15 @@ int32_t ARC_Hashtable_Remove(ARC_Hashtable *htable, void *key, size_t keysize, A
bucket->node = bucket->node->node; bucket->node = bucket->node->node;
if(external){ if(external){
err = external(temp, userdata); external(temp, userdata);
if(err){ return err; }
} }
free(temp); free(temp);
return 0; return;
} }
bucket = bucket->node; bucket = bucket->node;
} }
return ARC_ERRNO_NULL; arc_errno = ARC_ERRNO_NULL;
} }

View file

@ -1,28 +1,37 @@
#include "arc/std/io.h" #include "arc/std/io.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include "arc/std/string.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
int32_t ARC_IO_FileToStr(const char *path, char **data, uint64_t *size){ void ARC_IO_FileToStr(ARC_String *path, ARC_String **data){
FILE *file = fopen(path, "rb"); FILE *file = fopen(path->data, "rb");
if(!file){ return ARC_ERRNO_NULL; } if(!file){
return;
arc_errno = ARC_ERRNO_NULL;
}
fseek(file, 0L, SEEK_END); fseek(file, 0L, SEEK_END);
*size = ftell(file); uint64_t length = ftell(file);
rewind(file); rewind(file);
*data = (char *) calloc(1, *size + 1); char *fileData = (char *) calloc(1, length + 1);
if(!*data){ if(fileData == NULL){
fclose(file); fclose(file);
return ARC_ERRNO_NULL; arc_errno = ARC_ERRNO_NULL;
*data = NULL;
return;
} }
if(1 != fread(*data, *size, 1, file)){ if(1 != fread(fileData, length, 1, file)){
fclose(file); fclose(file);
return ARC_ERRNO_COPY; arc_errno = ARC_ERRNO_COPY;
*data = NULL;
return;
} }
fclose(file); fclose(file);
return 0; ARC_String_Create(data, fileData, length);
free(fileData);
} }

View file

@ -1,115 +1,393 @@
#include "arc/std/string.h" #include "arc/std/string.h"
#include "arc/std/errno.h" #include "arc/std/errno.h"
#include <stdint.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
uint8_t ARC_String_Alpha(char *val, uint64_t length){ void ARC_String_Create(ARC_String **string, char *data, uint64_t length){
for(; length; length--){ *string = (ARC_String *)malloc(sizeof(ARC_String));
if(val[length - 1] >= 'a' && val[length - 1] <= 'z'){ continue; } (*string)->data = (char *)malloc(length + 1);
if(val[length - 1] >= 'A' && val[length - 1] <= 'Z'){ continue; } (*string)->length = length;
strncpy((*string)->data, data, length);
(*string)->data[length] = '\0';
}
void ARC_String_CreateWithStrlen(ARC_String **string, char *data){
*string = (ARC_String *)malloc(sizeof(ARC_String));
(*string)->length = strlen(data);
(*string)->data = (char *)malloc((*string)->length + 1);
strncpy((*string)->data, data, (*string)->length);
(*string)->data[(*string)->length] = '\0';
}
void ARC_String_Destroy(ARC_String *string){
free(string->data);
free(string);
}
void ARC_String_Copy(ARC_String **copy, ARC_String *original){
if(!original){
arc_errno = ARC_ERRNO_NULL;
*copy = NULL;
return;
}
ARC_String_Create(copy, original->data, original->length);
}
void ARC_String_CopySubstring(ARC_String **substring, ARC_String *original, uint64_t start, uint64_t length){
if(!original){
arc_errno = ARC_ERRNO_NULL;
*substring = NULL;
return;
}
if(length == 0){
*substring = NULL;
return;
}
if(start + length > original->length){
arc_errno = ARC_ERRNO_DATA;
*substring = NULL;
return;
}
char data[length];
for(uint32_t i = 0; i < length; i++){
data[i] = 0;
}
strncpy(data, original->data + start, length);
ARC_String_Create(substring, data, length);
}
void ARC_String_RemoveSubstring(ARC_String **newString, ARC_String *original, ARC_String *substring){
uint64_t index = ARC_String_Find(original, substring);
if(arc_errno){
newString = NULL;
return;
}
ARC_String_RemoveSection(newString, original, index, original->length);
}
uint8_t ARC_String_Equals(ARC_String *first, ARC_String *second){
if(first->length != second->length){
return 0;
}
if(strncmp(first->data, second->data, first->length)){
return 0;
}
return 1; return 1;
} }
uint8_t ARC_String_EqualsCString(ARC_String *string, const char *cstring, uint64_t length){
if(string->length != length){
return 0; return 0;
} }
uint64_t ARC_String_ToUint64_t(const char *data, ARC_StringSubstr *substr){ if(strncmp(string->data, cstring, string->length)){
char temp[substr->length + 1]; return 0;
strncpy(temp, data + substr->index, substr->length);
temp[substr->length] = '\0';
return (uint64_t) strtoul(temp, NULL, 10);
} }
int32_t ARC_String_Find(char *data, char *substr, uint64_t *index){ return 1;
if(!data || !substr){ return ARC_ERRNO_NULL; } }
uint64_t max = strlen(data); uint8_t ARC_String_Alpha(ARC_String *string){
uint64_t sub = strlen(substr); for(uint64_t length = string->length; length; length--){
if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; } if(string->data[length - 1] >= 'a' && string->data[length - 1] <= 'z'){
continue;
}
max -= sub - 1; if(string->data[length - 1] >= 'A' && string->data[length - 1] <= 'Z'){
continue;
}
return 1;
}
return 0;
}
uint64_t ARC_String_ToUint64_t(ARC_String *string){
return (uint64_t) strtoul(string->data, NULL, 10);
}
int64_t ARC_String_ToInt64_t(ARC_String *string){
return (int64_t) strtol(string->data, NULL, 10);
}
double ARC_String_ToDouble(ARC_String *string){
return strtod(string->data, NULL);
}
uint64_t ARC_String_Find(ARC_String *string, ARC_String *substring){
if(!string || !substring){
arc_errno = ARC_ERRNO_NULL;
return ~(uint64_t)0;
}
if(substring->length > string->length){
return ~(uint64_t)0;
}
uint64_t max = string->length - (substring->length - 1);
for(uint64_t i = 0; max; i++, max--){ for(uint64_t i = 0; max; i++, max--){
if(!strncmp(data + i, substr, sub)){ if(!strncmp(string->data + i, substring->data, substring->length)){
*index = i; return i;
return 0;
} }
} }
*index = ~((uint64_t)0); return ~(uint64_t)0;
return 0;
} }
int32_t ARC_String_FindBack(char *data, char *substr, uint64_t *index){ uint64_t ARC_String_FindCString(ARC_String *string, const char *cstring, uint64_t length){
if(!data || !substr){ return ARC_ERRNO_NULL; } if(!string || !cstring){
arc_errno = ARC_ERRNO_NULL;
return ~(uint64_t)0;
}
uint64_t max = strlen(data); if(string->length < length){
uint64_t sub = strlen(substr); return ~(uint64_t)0;
if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; } }
max -= sub - 1; uint64_t max = string->length - (length - 1);
for(uint64_t i = 0; i < max; i++){
if(!strncmp(string->data + i, cstring, length)){
return i + 1;
}
}
return ~(uint64_t)0;
}
uint64_t ARC_String_FindBack(ARC_String *string, ARC_String *substring){
if(!string || !substring){
arc_errno = ARC_ERRNO_NULL;
return ~(uint64_t)0;
}
if(substring->length > string->length){
return ~(uint64_t)0;
}
uint64_t max = string->length - (substring->length - 1);
for(; max; max--){ for(; max; max--){
if(!strncmp(data + (max - 1), substr, sub)){ if(!strncmp(string->data + (max - 1), substring->data, substring->length)){
*index = max; return max;
return 0;
} }
} }
*index = ~((uint64_t)0); return ~(uint64_t)0;
return 0;
} }
int32_t ARC_StringSubstr_StripEnds(char *data, char *substr, ARC_StringSubstr *subdata){ void ARC_String_StripEnds(ARC_String *original, ARC_String **stripped, char charToStrip){
if(!subdata){ return ARC_ERRNO_NULL; } if(!original){
if(!substr){ substr = (char *)" "; } arc_errno = ARC_ERRNO_NULL;
*stripped = NULL;
return;
}
subdata->length = (subdata->length)? subdata->length : strlen(data); if(!original->length){
uint64_t max = subdata->length; arc_errno = ARC_ERRNO_DATA;
uint64_t sub = strlen(substr); *stripped = NULL;
if(!max || !sub || sub > max){ return ARC_ERRNO_DATA; } return;
}
max -= sub - 1; uint64_t length = original->length - 1;
for(; max; max--){ for(; length; length--){
if(strncmp(data + subdata->index + (max - 1), substr, sub)){ if(strncmp(original->data + (length - 1), &charToStrip, 1)){
subdata->length = max;
break; break;
} }
} }
max = subdata->length - (sub - 1); if(!length){
for(uint64_t i = 0; max; i++, max--){ arc_errno = ARC_ERRNO_DATA;
if(strncmp(data + subdata->index + i, substr, sub)){ *stripped = NULL;
subdata->index += i; return;
subdata->length -= i;
return 0;
}
} }
return 0; uint64_t start = 0;
} for(; start <= length; start++){
if(strncmp(original->data + start, &charToStrip, 1)){
int32_t ARC_StringSubstr_StripWhitespaceEnds(char *data, ARC_StringSubstr *subdata){
if(!subdata){ return ARC_ERRNO_NULL; }
subdata->length = (subdata->length)? subdata->length : strlen(data);
uint64_t max = subdata->length;
if(!max){ return ARC_ERRNO_DATA; }
for(; max; max--){
if(data[subdata->index + (max - 1)] != ' ' && data[subdata->index + (max - 1)] != '\n' && data[subdata->index + (max - 1)] != '\t' && data[subdata->index + (max - 1)] != '\r'){
subdata->length = max;
break; break;
} }
} }
max = subdata->length; if(start == length){
for(uint64_t i = 0; max; i++, max--){ arc_errno = ARC_ERRNO_DATA;
if(data[subdata->index + i] != ' ' && data[subdata->index + i] != '\n' && data[subdata->index + i] != '\t' && data[subdata->index + i] != '\r'){ *stripped = NULL;
subdata->index += i; return;
subdata->length -= i;
return 0;
}
} }
return 0; length -= start;
ARC_String_Create(stripped, original->data + start, length);
}
void ARC_String_StripWhitespace(ARC_String *original, ARC_String **stripped){
if(!original){
arc_errno = ARC_ERRNO_NULL;
*stripped = NULL;
return;
}
if(!original->length){
arc_errno = ARC_ERRNO_DATA;
*stripped = NULL;
return;
}
uint64_t length = 0;
for(uint64_t i = 0; i < original->length; i++){
if(original->data[i] == ' '){
continue;
}
if(original->data[i] == '\n'){
continue;
}
if(original->data[i] == '\t'){
continue;
}
if(original->data[i] == '\r'){
continue;
}
length++;
}
if(!length){
arc_errno = ARC_ERRNO_DATA;
*stripped = NULL;
return;
}
length++;
char data[length];
for(uint32_t i = 0; i < length; i++){
data[i] = 0;
}
uint64_t start = 0;
for(uint64_t i = 0; i < length; i++){
if(original->data[i] == ' '){
continue;
}
if(original->data[i] == '\n'){
continue;
}
if(original->data[i] == '\t'){
continue;
}
if(original->data[i] == '\r'){
continue;
}
data[start] = original->data[i];
start++;
}
ARC_String_Create(stripped, data, length);
}
void ARC_String_StripEndsWhitespace(ARC_String *original, ARC_String **stripped){
uint64_t index;
for(uint64_t i = 0; i < original->length; i++){
if(original->data[i] == ' '){
continue;
}
if(original->data[i] == '\n'){
continue;
}
if(original->data[i] == '\t'){
continue;
}
if(original->data[i] == '\r'){
continue;
}
index = i;
break;
}
uint64_t endIndex;
for(uint64_t i = original->length; i > 0; i--){
if(original->data[i - 1] == ' '){
continue;
}
if(original->data[i - 1] == '\n'){
continue;
}
if(original->data[i - 1] == '\t'){
continue;
}
if(original->data[i - 1] == '\r'){
continue;
}
endIndex = i;
break;
}
ARC_String_CopySubstring(stripped, original, index, endIndex - index);
}
void ARC_String_Merge(ARC_String *first, ARC_String *second, ARC_String **combined){
char data[first->length + second->length];
for(uint32_t i = 0; i < first->length; i++){
data[i] = first->data[i];
}
for(uint32_t i = 0; i < second->length; i++){
data[i + first->length] = second->data[i];
}
ARC_String_Create(combined, data, first->length + second->length);
}
void ARC_String_RemoveSection(ARC_String **newString, ARC_String *original, uint64_t removeIndex, uint64_t removeLength){
if(removeIndex == 0 && removeIndex + removeLength >= original->length){
ARC_String_Copy(newString, original);
return;
}
if(removeIndex == 0){
ARC_String_CopySubstring(newString, original, removeLength, original->length - removeLength);
return;
}
if(removeIndex + removeLength >= original->length){
ARC_String_CopySubstring(newString, original, 0, removeIndex);
return;
}
ARC_String *first, *second;
ARC_String_CopySubstring(&first , original, 0 , removeIndex );
ARC_String_CopySubstring(&second, original, removeIndex + removeLength, original->length - (removeIndex + removeLength));
ARC_String_Merge(first, second, newString);
ARC_String_Destroy(first );
ARC_String_Destroy(second);
} }