Merge 1e61718a30
into 92fe263569
This commit is contained in:
commit
c425a45a7e
@ -103,28 +103,28 @@ typedef struct
|
||||
/*! Directory entry */
|
||||
typedef struct
|
||||
{
|
||||
// 0x00
|
||||
u16 name[0x106]; //!< UTF-16 encoded name
|
||||
// 0x20C
|
||||
u8 shortName[0x09]; //!< 8.3 file name
|
||||
// 0x215
|
||||
u8 unknown1; //!< ???
|
||||
// 0x216
|
||||
u8 shortExt[0x04]; //!< 8.3 file extension (set to spaces for directories)
|
||||
// 0x21A
|
||||
u8 unknown2; //!< ???
|
||||
// 0x21B
|
||||
u8 unknown3; //!< ???
|
||||
// 0x21C
|
||||
u8 isDirectory; //!< directory bit
|
||||
// 0x21D
|
||||
u8 isHidden; //!< hidden bit
|
||||
// 0x21E
|
||||
u8 isArchive; //!< archive bit
|
||||
// 0x21F
|
||||
u8 isReadOnly; //!< read-only bit
|
||||
// 0x220
|
||||
u64 fileSize; //!< file size
|
||||
// 0x00
|
||||
u16 name[0x106]; //!< UTF-16 encoded name
|
||||
// 0x20C
|
||||
u8 shortName[0x09]; //!< 8.3 file name
|
||||
// 0x215
|
||||
u8 unknown1; //!< ???
|
||||
// 0x216
|
||||
u8 shortExt[0x04]; //!< 8.3 file extension (set to spaces for directories)
|
||||
// 0x21A
|
||||
u8 unknown2; //!< ???
|
||||
// 0x21B
|
||||
u8 unknown3; //!< ???
|
||||
// 0x21C
|
||||
u8 isDirectory; //!< directory bit
|
||||
// 0x21D
|
||||
u8 isHidden; //!< hidden bit
|
||||
// 0x21E
|
||||
u8 isArchive; //!< archive bit
|
||||
// 0x21F
|
||||
u8 isReadOnly; //!< read-only bit
|
||||
// 0x220
|
||||
u64 fileSize; //!< file size
|
||||
} FS_dirent;
|
||||
|
||||
Result fsInit(void);
|
||||
|
@ -6,29 +6,29 @@
|
||||
|
||||
typedef enum
|
||||
{
|
||||
KEY_A = BIT(0),
|
||||
KEY_B = BIT(1),
|
||||
KEY_SELECT = BIT(2),
|
||||
KEY_START = BIT(3),
|
||||
KEY_DRIGHT = BIT(4),
|
||||
KEY_DLEFT = BIT(5),
|
||||
KEY_DUP = BIT(6),
|
||||
KEY_DDOWN = BIT(7),
|
||||
KEY_R = BIT(8),
|
||||
KEY_L = BIT(9),
|
||||
KEY_X = BIT(10),
|
||||
KEY_Y = BIT(11),
|
||||
KEY_ZL = BIT(14), // (new 3DS only)
|
||||
KEY_ZR = BIT(15), // (new 3DS only)
|
||||
KEY_TOUCH = BIT(20), // Not actually provided by HID
|
||||
KEY_A = BIT(0),
|
||||
KEY_B = BIT(1),
|
||||
KEY_SELECT = BIT(2),
|
||||
KEY_START = BIT(3),
|
||||
KEY_DRIGHT = BIT(4),
|
||||
KEY_DLEFT = BIT(5),
|
||||
KEY_DUP = BIT(6),
|
||||
KEY_DDOWN = BIT(7),
|
||||
KEY_R = BIT(8),
|
||||
KEY_L = BIT(9),
|
||||
KEY_X = BIT(10),
|
||||
KEY_Y = BIT(11),
|
||||
KEY_ZL = BIT(14), // (new 3DS only)
|
||||
KEY_ZR = BIT(15), // (new 3DS only)
|
||||
KEY_TOUCH = BIT(20), // Not actually provided by HID
|
||||
KEY_CSTICK_RIGHT = BIT(24), // c-stick (new 3DS only)
|
||||
KEY_CSTICK_LEFT = BIT(25), // c-stick (new 3DS only)
|
||||
KEY_CSTICK_UP = BIT(26), // c-stick (new 3DS only)
|
||||
KEY_CSTICK_DOWN = BIT(27), // c-stick (new 3DS only)
|
||||
KEY_CPAD_RIGHT = BIT(28), // circle pad
|
||||
KEY_CPAD_LEFT = BIT(29), // circle pad
|
||||
KEY_CPAD_UP = BIT(30), // circle pad
|
||||
KEY_CPAD_DOWN = BIT(31), // circle pad
|
||||
KEY_CPAD_RIGHT = BIT(28), // circle pad
|
||||
KEY_CPAD_LEFT = BIT(29), // circle pad
|
||||
KEY_CPAD_UP = BIT(30), // circle pad
|
||||
KEY_CPAD_DOWN = BIT(31), // circle pad
|
||||
|
||||
// Generic catch-all directions
|
||||
KEY_UP = KEY_DUP | KEY_CPAD_UP,
|
||||
|
@ -24,14 +24,14 @@ typedef enum {
|
||||
} MemPerm;
|
||||
|
||||
typedef struct {
|
||||
u32 base_addr;
|
||||
u32 size;
|
||||
u32 perm;
|
||||
u32 state;
|
||||
u32 base_addr;
|
||||
u32 size;
|
||||
u32 perm;
|
||||
u32 state;
|
||||
} MemInfo;
|
||||
|
||||
typedef struct {
|
||||
u32 flags;
|
||||
u32 flags;
|
||||
} PageInfo;
|
||||
|
||||
typedef enum {
|
||||
|
@ -14,15 +14,15 @@ typedef int (*rbtree_node_comparator_t)(const rbtree_node_t *lhs,
|
||||
const rbtree_node_t *rhs);
|
||||
struct rbtree_node
|
||||
{
|
||||
uintptr_t parent_color;
|
||||
rbtree_node_t *child[2];
|
||||
uintptr_t parent_color;
|
||||
rbtree_node_t *child[2];
|
||||
};
|
||||
|
||||
struct rbtree
|
||||
{
|
||||
rbtree_node_t *root;
|
||||
rbtree_node_comparator_t comparator;
|
||||
size_t size;
|
||||
rbtree_node_t *root;
|
||||
rbtree_node_comparator_t comparator;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -31,17 +31,17 @@ void gfxSet3D(bool enable)
|
||||
}
|
||||
|
||||
void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format) {
|
||||
if(screen==GFX_TOP)
|
||||
topFormat = format;
|
||||
else
|
||||
botFormat = format;
|
||||
if(screen==GFX_TOP)
|
||||
topFormat = format;
|
||||
else
|
||||
botFormat = format;
|
||||
}
|
||||
|
||||
GSP_FramebufferFormats gfxGetScreenFormat(gfxScreen_t screen) {
|
||||
if(screen==GFX_TOP)
|
||||
return topFormat;
|
||||
else
|
||||
return botFormat;
|
||||
if(screen==GFX_TOP)
|
||||
return topFormat;
|
||||
else
|
||||
return botFormat;
|
||||
}
|
||||
|
||||
void gfxSetDoubleBuffering( gfxScreen_t screen, bool doubleBuffering) {
|
||||
@ -49,18 +49,18 @@ void gfxSetDoubleBuffering( gfxScreen_t screen, bool doubleBuffering) {
|
||||
}
|
||||
|
||||
static u32 __get_bytes_per_pixel(GSP_FramebufferFormats format) {
|
||||
switch(format) {
|
||||
case GSP_RGBA8_OES:
|
||||
return 4;
|
||||
case GSP_BGR8_OES:
|
||||
return 3;
|
||||
case GSP_RGB565_OES:
|
||||
case GSP_RGB5_A1_OES:
|
||||
case GSP_RGBA4_OES:
|
||||
return 2;
|
||||
}
|
||||
switch(format) {
|
||||
case GSP_RGBA8_OES:
|
||||
return 4;
|
||||
case GSP_BGR8_OES:
|
||||
return 3;
|
||||
case GSP_RGB565_OES:
|
||||
case GSP_RGB5_A1_OES:
|
||||
case GSP_RGBA4_OES:
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 3;
|
||||
return 3;
|
||||
}
|
||||
|
||||
void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -39,14 +39,14 @@ Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy)
|
||||
if(ret!=0) {
|
||||
HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = HTTPC_InitializeConnectionSession(context->servhandle, context->httphandle);
|
||||
if(ret!=0) {
|
||||
HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
|
||||
svcCloseHandle(context->servhandle);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if(use_defaultproxy==0)return 0;
|
||||
|
||||
@ -55,7 +55,7 @@ Result httpcOpenContext(httpcContext *context, char* url, u32 use_defaultproxy)
|
||||
HTTPC_CloseContext(__httpc_servhandle, context->httphandle);
|
||||
svcCloseHandle(context->servhandle);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
srv.c _ Service manager.
|
||||
srv.c _ Service manager.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -9,15 +9,15 @@
|
||||
|
||||
|
||||
/*
|
||||
The homebrew loader can choose to supply a list of service handles that have
|
||||
been "stolen" from other processes that have been compromised. This allows us
|
||||
to access services that are normally restricted from the current process.
|
||||
The homebrew loader can choose to supply a list of service handles that have
|
||||
been "stolen" from other processes that have been compromised. This allows us
|
||||
to access services that are normally restricted from the current process.
|
||||
|
||||
For every service requested by the application, we shall first check if the
|
||||
list given to us contains the requested service and if so use it. If we don't
|
||||
find the service in that list, we ask the service manager and hope for the
|
||||
best.
|
||||
*/
|
||||
For every service requested by the application, we shall first check if the
|
||||
list given to us contains the requested service and if so use it. If we don't
|
||||
find the service in that list, we ask the service manager and hope for the
|
||||
best.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
u32 num;
|
||||
|
@ -5,30 +5,30 @@ void
|
||||
rbtree_clear(rbtree_t *tree,
|
||||
rbtree_node_destructor_t destructor)
|
||||
{
|
||||
rbtree_node_t *node = tree->root;
|
||||
rbtree_node_t *node = tree->root;
|
||||
|
||||
while(tree->root != NULL)
|
||||
{
|
||||
while(node->child[LEFT] != NULL)
|
||||
node = node->child[LEFT];
|
||||
while(tree->root != NULL)
|
||||
{
|
||||
while(node->child[LEFT] != NULL)
|
||||
node = node->child[LEFT];
|
||||
|
||||
if(node->child[RIGHT] != NULL)
|
||||
node = node->child[RIGHT];
|
||||
else
|
||||
{
|
||||
rbtree_node_t *parent = get_parent(node);
|
||||
if(node->child[RIGHT] != NULL)
|
||||
node = node->child[RIGHT];
|
||||
else
|
||||
{
|
||||
rbtree_node_t *parent = get_parent(node);
|
||||
|
||||
if(parent == NULL)
|
||||
tree->root = NULL;
|
||||
else
|
||||
parent->child[node != parent->child[LEFT]] = NULL;
|
||||
if(parent == NULL)
|
||||
tree->root = NULL;
|
||||
else
|
||||
parent->child[node != parent->child[LEFT]] = NULL;
|
||||
|
||||
if(destructor != NULL)
|
||||
(*destructor)(node);
|
||||
if(destructor != NULL)
|
||||
(*destructor)(node);
|
||||
|
||||
node = parent;
|
||||
}
|
||||
}
|
||||
node = parent;
|
||||
}
|
||||
}
|
||||
|
||||
tree->size = 0;
|
||||
tree->size = 0;
|
||||
}
|
||||
|
@ -5,26 +5,26 @@ rbtree_node_t*
|
||||
rbtree_find(const rbtree_t *tree,
|
||||
const rbtree_node_t *node)
|
||||
{
|
||||
rbtree_node_t *tmp = tree->root;
|
||||
rbtree_node_t *save = NULL;
|
||||
rbtree_node_t *tmp = tree->root;
|
||||
rbtree_node_t *save = NULL;
|
||||
|
||||
while(tmp != NULL)
|
||||
{
|
||||
int rc = (*tree->comparator)(node, tmp);
|
||||
if(rc < 0)
|
||||
{
|
||||
tmp = tmp->child[LEFT];
|
||||
}
|
||||
else if(rc > 0)
|
||||
{
|
||||
tmp = tmp->child[RIGHT];
|
||||
}
|
||||
else
|
||||
{
|
||||
save = tmp;
|
||||
tmp = tmp->child[LEFT];
|
||||
}
|
||||
}
|
||||
while(tmp != NULL)
|
||||
{
|
||||
int rc = (*tree->comparator)(node, tmp);
|
||||
if(rc < 0)
|
||||
{
|
||||
tmp = tmp->child[LEFT];
|
||||
}
|
||||
else if(rc > 0)
|
||||
{
|
||||
tmp = tmp->child[RIGHT];
|
||||
}
|
||||
else
|
||||
{
|
||||
save = tmp;
|
||||
tmp = tmp->child[LEFT];
|
||||
}
|
||||
}
|
||||
|
||||
return save;
|
||||
return save;
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ void
|
||||
rbtree_init(rbtree_t *tree,
|
||||
rbtree_node_comparator_t comparator)
|
||||
{
|
||||
tree->root = NULL;
|
||||
tree->comparator = comparator;
|
||||
tree->size = 0;
|
||||
tree->root = NULL;
|
||||
tree->comparator = comparator;
|
||||
tree->size = 0;
|
||||
}
|
||||
|
@ -6,91 +6,91 @@ do_insert(rbtree_t *tree,
|
||||
rbtree_node_t *node,
|
||||
int multi)
|
||||
{
|
||||
rbtree_node_t *original = node;
|
||||
rbtree_node_t **tmp = &tree->root;
|
||||
rbtree_node_t *parent = NULL;
|
||||
rbtree_node_t *save = NULL;
|
||||
rbtree_node_t *original = node;
|
||||
rbtree_node_t **tmp = &tree->root;
|
||||
rbtree_node_t *parent = NULL;
|
||||
rbtree_node_t *save = NULL;
|
||||
|
||||
while(*tmp != NULL)
|
||||
{
|
||||
int cmp = (*(tree->comparator))(node, *tmp);
|
||||
parent = *tmp;
|
||||
while(*tmp != NULL)
|
||||
{
|
||||
int cmp = (*(tree->comparator))(node, *tmp);
|
||||
parent = *tmp;
|
||||
|
||||
if(cmp < 0)
|
||||
tmp = &((*tmp)->child[LEFT]);
|
||||
else if(cmp > 0)
|
||||
tmp = &((*tmp)->child[RIGHT]);
|
||||
else
|
||||
{
|
||||
if(!multi)
|
||||
save = *tmp;
|
||||
if(cmp < 0)
|
||||
tmp = &((*tmp)->child[LEFT]);
|
||||
else if(cmp > 0)
|
||||
tmp = &((*tmp)->child[RIGHT]);
|
||||
else
|
||||
{
|
||||
if(!multi)
|
||||
save = *tmp;
|
||||
|
||||
tmp = &((*tmp)->child[LEFT]);
|
||||
}
|
||||
}
|
||||
tmp = &((*tmp)->child[LEFT]);
|
||||
}
|
||||
}
|
||||
|
||||
if(save != NULL)
|
||||
{
|
||||
return save;
|
||||
}
|
||||
if(save != NULL)
|
||||
{
|
||||
return save;
|
||||
}
|
||||
|
||||
*tmp = node;
|
||||
*tmp = node;
|
||||
|
||||
node->child[LEFT] = node->child[RIGHT] = NULL;
|
||||
set_parent(node, parent);
|
||||
node->child[LEFT] = node->child[RIGHT] = NULL;
|
||||
set_parent(node, parent);
|
||||
|
||||
set_red(node);
|
||||
set_red(node);
|
||||
|
||||
while(is_red((parent = get_parent(node))))
|
||||
{
|
||||
rbtree_node_t *grandparent = get_parent(parent);
|
||||
int left = (parent == grandparent->child[LEFT]);
|
||||
rbtree_node_t *uncle = grandparent->child[left];
|
||||
while(is_red((parent = get_parent(node))))
|
||||
{
|
||||
rbtree_node_t *grandparent = get_parent(parent);
|
||||
int left = (parent == grandparent->child[LEFT]);
|
||||
rbtree_node_t *uncle = grandparent->child[left];
|
||||
|
||||
if(is_red(uncle))
|
||||
{
|
||||
set_black(uncle);
|
||||
set_black(parent);
|
||||
set_red(grandparent);
|
||||
if(is_red(uncle))
|
||||
{
|
||||
set_black(uncle);
|
||||
set_black(parent);
|
||||
set_red(grandparent);
|
||||
|
||||
node = grandparent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(parent->child[left] == node)
|
||||
{
|
||||
rbtree_node_t *tmp;
|
||||
node = grandparent;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(parent->child[left] == node)
|
||||
{
|
||||
rbtree_node_t *tmp;
|
||||
|
||||
rbtree_rotate(tree, parent, left);
|
||||
rbtree_rotate(tree, parent, left);
|
||||
|
||||
tmp = parent;
|
||||
parent = node;
|
||||
node = tmp;
|
||||
}
|
||||
tmp = parent;
|
||||
parent = node;
|
||||
node = tmp;
|
||||
}
|
||||
|
||||
set_black(parent);
|
||||
set_red(grandparent);
|
||||
rbtree_rotate(tree, grandparent, !left);
|
||||
}
|
||||
}
|
||||
set_black(parent);
|
||||
set_red(grandparent);
|
||||
rbtree_rotate(tree, grandparent, !left);
|
||||
}
|
||||
}
|
||||
|
||||
set_black(tree->root);
|
||||
set_black(tree->root);
|
||||
|
||||
tree->size += 1;
|
||||
tree->size += 1;
|
||||
|
||||
return original;
|
||||
return original;
|
||||
}
|
||||
|
||||
rbtree_node_t*
|
||||
rbtree_insert(rbtree_t *tree,
|
||||
rbtree_node_t *node)
|
||||
{
|
||||
return do_insert(tree, node, 0);
|
||||
return do_insert(tree, node, 0);
|
||||
}
|
||||
|
||||
void
|
||||
rbtree_insert_multi(rbtree_t *tree,
|
||||
rbtree_node_t *node)
|
||||
{
|
||||
do_insert(tree, node, 1);
|
||||
do_insert(tree, node, 1);
|
||||
}
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
typedef enum rbtree_color
|
||||
{
|
||||
RED = 0,
|
||||
BLACK = 1,
|
||||
RED = 0,
|
||||
BLACK = 1,
|
||||
} rbtree_color_t;
|
||||
|
||||
#define COLOR_MASK (RED|BLACK)
|
||||
@ -14,48 +14,48 @@ typedef enum rbtree_color
|
||||
static inline void
|
||||
set_black(rbtree_node_t *node)
|
||||
{
|
||||
node->parent_color &= ~COLOR_MASK;
|
||||
node->parent_color |= BLACK;
|
||||
node->parent_color &= ~COLOR_MASK;
|
||||
node->parent_color |= BLACK;
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_red(rbtree_node_t *node)
|
||||
{
|
||||
node->parent_color &= ~COLOR_MASK;
|
||||
node->parent_color |= RED;
|
||||
node->parent_color &= ~COLOR_MASK;
|
||||
node->parent_color |= RED;
|
||||
}
|
||||
|
||||
static inline rbtree_color_t
|
||||
get_color(const rbtree_node_t *node)
|
||||
{
|
||||
if(node == NULL)
|
||||
return BLACK;
|
||||
return (rbtree_color_t)(node->parent_color & COLOR_MASK);
|
||||
if(node == NULL)
|
||||
return BLACK;
|
||||
return (rbtree_color_t)(node->parent_color & COLOR_MASK);
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_black(const rbtree_node_t *node)
|
||||
{
|
||||
return get_color(node) == BLACK;
|
||||
return get_color(node) == BLACK;
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_red(const rbtree_node_t *node)
|
||||
{
|
||||
return get_color(node) == RED;
|
||||
return get_color(node) == RED;
|
||||
}
|
||||
|
||||
static inline rbtree_node_t*
|
||||
get_parent(const rbtree_node_t *node)
|
||||
{
|
||||
return (rbtree_node_t*)(node->parent_color & ~COLOR_MASK);
|
||||
return (rbtree_node_t*)(node->parent_color & ~COLOR_MASK);
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_parent(rbtree_node_t *node,
|
||||
const rbtree_node_t *parent)
|
||||
{
|
||||
node->parent_color = (get_color(node)) | ((uintptr_t)parent);
|
||||
node->parent_color = (get_color(node)) | ((uintptr_t)parent);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -5,37 +5,37 @@ static inline rbtree_node_t*
|
||||
do_iterate(const rbtree_node_t *node,
|
||||
int next)
|
||||
{
|
||||
rbtree_node_t *it = (rbtree_node_t*)node;
|
||||
rbtree_node_t *it = (rbtree_node_t*)node;
|
||||
|
||||
if(it->child[next] != NULL)
|
||||
{
|
||||
it = it->child[next];
|
||||
while(it->child[!next] != NULL)
|
||||
it = it->child[!next];
|
||||
}
|
||||
else
|
||||
{
|
||||
rbtree_node_t *parent = get_parent(node);
|
||||
while(parent != NULL && it == parent->child[next])
|
||||
{
|
||||
it = parent;
|
||||
parent = get_parent(it);
|
||||
}
|
||||
if(it->child[next] != NULL)
|
||||
{
|
||||
it = it->child[next];
|
||||
while(it->child[!next] != NULL)
|
||||
it = it->child[!next];
|
||||
}
|
||||
else
|
||||
{
|
||||
rbtree_node_t *parent = get_parent(node);
|
||||
while(parent != NULL && it == parent->child[next])
|
||||
{
|
||||
it = parent;
|
||||
parent = get_parent(it);
|
||||
}
|
||||
|
||||
it = parent;
|
||||
}
|
||||
it = parent;
|
||||
}
|
||||
|
||||
return it;
|
||||
return it;
|
||||
}
|
||||
|
||||
rbtree_node_t*
|
||||
rbtree_node_next(const rbtree_node_t *node)
|
||||
{
|
||||
return do_iterate(node, RIGHT);
|
||||
return do_iterate(node, RIGHT);
|
||||
}
|
||||
|
||||
rbtree_node_t*
|
||||
rbtree_node_prev(const rbtree_node_t *node)
|
||||
{
|
||||
return do_iterate(node, LEFT);
|
||||
return do_iterate(node, LEFT);
|
||||
}
|
||||
|
@ -5,33 +5,33 @@ static inline rbtree_node_t*
|
||||
do_minmax(const rbtree_t *tree,
|
||||
int max)
|
||||
{
|
||||
rbtree_node_t *node = tree->root;
|
||||
rbtree_node_t *node = tree->root;
|
||||
|
||||
if(node == NULL)
|
||||
return NULL;
|
||||
if(node == NULL)
|
||||
return NULL;
|
||||
|
||||
while(node->child[max] != NULL)
|
||||
node = node->child[max];
|
||||
while(node->child[max] != NULL)
|
||||
node = node->child[max];
|
||||
|
||||
return node;
|
||||
return node;
|
||||
}
|
||||
|
||||
rbtree_node_t*
|
||||
rbtree_min(const rbtree_t *tree)
|
||||
{
|
||||
rbtree_node_t *node;
|
||||
rbtree_node_t *node;
|
||||
|
||||
node = do_minmax(tree, LEFT);
|
||||
node = do_minmax(tree, LEFT);
|
||||
|
||||
return node;
|
||||
return node;
|
||||
}
|
||||
|
||||
rbtree_node_t*
|
||||
rbtree_max(const rbtree_t *tree)
|
||||
{
|
||||
rbtree_node_t *node;
|
||||
rbtree_node_t *node;
|
||||
|
||||
node = do_minmax(tree, RIGHT);
|
||||
node = do_minmax(tree, RIGHT);
|
||||
|
||||
return node;
|
||||
return node;
|
||||
}
|
||||
|
@ -6,53 +6,53 @@ recolor(rbtree_t *tree,
|
||||
rbtree_node_t *parent,
|
||||
rbtree_node_t *node)
|
||||
{
|
||||
rbtree_node_t *sibling;
|
||||
rbtree_node_t *sibling;
|
||||
|
||||
while(is_black(node) && node != tree->root)
|
||||
{
|
||||
int left = (node == parent->child[LEFT]);
|
||||
while(is_black(node) && node != tree->root)
|
||||
{
|
||||
int left = (node == parent->child[LEFT]);
|
||||
|
||||
sibling = parent->child[left];
|
||||
sibling = parent->child[left];
|
||||
|
||||
if(is_red(sibling))
|
||||
{
|
||||
set_black(sibling);
|
||||
set_red(parent);
|
||||
rbtree_rotate(tree, parent, left);
|
||||
sibling = parent->child[left];
|
||||
}
|
||||
if(is_red(sibling))
|
||||
{
|
||||
set_black(sibling);
|
||||
set_red(parent);
|
||||
rbtree_rotate(tree, parent, left);
|
||||
sibling = parent->child[left];
|
||||
}
|
||||
|
||||
if(is_black(sibling->child[LEFT]) && is_black(sibling->child[RIGHT]))
|
||||
{
|
||||
set_red(sibling);
|
||||
node = parent;
|
||||
parent = get_parent(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_black(sibling->child[left]))
|
||||
{
|
||||
set_black(sibling->child[!left]);
|
||||
set_red(sibling);
|
||||
rbtree_rotate(tree, sibling, !left);
|
||||
sibling = parent->child[left];
|
||||
}
|
||||
if(is_black(sibling->child[LEFT]) && is_black(sibling->child[RIGHT]))
|
||||
{
|
||||
set_red(sibling);
|
||||
node = parent;
|
||||
parent = get_parent(node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(is_black(sibling->child[left]))
|
||||
{
|
||||
set_black(sibling->child[!left]);
|
||||
set_red(sibling);
|
||||
rbtree_rotate(tree, sibling, !left);
|
||||
sibling = parent->child[left];
|
||||
}
|
||||
|
||||
if(is_black(parent))
|
||||
set_black(sibling);
|
||||
else
|
||||
set_red(sibling);
|
||||
set_black(parent);
|
||||
set_black(sibling->child[left]);
|
||||
if(is_black(parent))
|
||||
set_black(sibling);
|
||||
else
|
||||
set_red(sibling);
|
||||
set_black(parent);
|
||||
set_black(sibling->child[left]);
|
||||
|
||||
rbtree_rotate(tree, parent, left);
|
||||
rbtree_rotate(tree, parent, left);
|
||||
|
||||
node = tree->root;
|
||||
}
|
||||
}
|
||||
node = tree->root;
|
||||
}
|
||||
}
|
||||
|
||||
if(node != NULL)
|
||||
set_black(node);
|
||||
if(node != NULL)
|
||||
set_black(node);
|
||||
}
|
||||
|
||||
rbtree_node_t*
|
||||
@ -60,81 +60,81 @@ rbtree_remove(rbtree_t *tree,
|
||||
rbtree_node_t *node,
|
||||
rbtree_node_destructor_t destructor)
|
||||
{
|
||||
rbtree_color_t color;
|
||||
rbtree_node_t *child, *parent, *original = node;
|
||||
rbtree_node_t *next;
|
||||
rbtree_color_t color;
|
||||
rbtree_node_t *child, *parent, *original = node;
|
||||
rbtree_node_t *next;
|
||||
|
||||
next = rbtree_node_next(node);
|
||||
next = rbtree_node_next(node);
|
||||
|
||||
if(node->child[LEFT] != NULL && node->child[RIGHT] != NULL)
|
||||
{
|
||||
rbtree_node_t *old = node;
|
||||
if(node->child[LEFT] != NULL && node->child[RIGHT] != NULL)
|
||||
{
|
||||
rbtree_node_t *old = node;
|
||||
|
||||
node = node->child[RIGHT];
|
||||
while(node->child[LEFT] != NULL)
|
||||
node = node->child[LEFT];
|
||||
node = node->child[RIGHT];
|
||||
while(node->child[LEFT] != NULL)
|
||||
node = node->child[LEFT];
|
||||
|
||||
parent = get_parent(old);
|
||||
if(parent != NULL)
|
||||
{
|
||||
if(parent->child[LEFT] == old)
|
||||
parent->child[LEFT] = node;
|
||||
else
|
||||
parent->child[RIGHT] = node;
|
||||
}
|
||||
else
|
||||
tree->root = node;
|
||||
parent = get_parent(old);
|
||||
if(parent != NULL)
|
||||
{
|
||||
if(parent->child[LEFT] == old)
|
||||
parent->child[LEFT] = node;
|
||||
else
|
||||
parent->child[RIGHT] = node;
|
||||
}
|
||||
else
|
||||
tree->root = node;
|
||||
|
||||
child = node->child[RIGHT];
|
||||
parent = get_parent(node);
|
||||
color = get_color(node);
|
||||
child = node->child[RIGHT];
|
||||
parent = get_parent(node);
|
||||
color = get_color(node);
|
||||
|
||||
if(parent == old)
|
||||
parent = node;
|
||||
else
|
||||
{
|
||||
if(child != NULL)
|
||||
set_parent(child, parent);
|
||||
parent->child[LEFT] = child;
|
||||
if(parent == old)
|
||||
parent = node;
|
||||
else
|
||||
{
|
||||
if(child != NULL)
|
||||
set_parent(child, parent);
|
||||
parent->child[LEFT] = child;
|
||||
|
||||
node->child[RIGHT] = old->child[RIGHT];
|
||||
set_parent(old->child[RIGHT], node);
|
||||
}
|
||||
node->child[RIGHT] = old->child[RIGHT];
|
||||
set_parent(old->child[RIGHT], node);
|
||||
}
|
||||
|
||||
node->parent_color = old->parent_color;
|
||||
node->child[LEFT] = old->child[LEFT];
|
||||
set_parent(old->child[LEFT], node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(node->child[LEFT] == NULL)
|
||||
child = node->child[RIGHT];
|
||||
else
|
||||
child = node->child[LEFT];
|
||||
node->parent_color = old->parent_color;
|
||||
node->child[LEFT] = old->child[LEFT];
|
||||
set_parent(old->child[LEFT], node);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(node->child[LEFT] == NULL)
|
||||
child = node->child[RIGHT];
|
||||
else
|
||||
child = node->child[LEFT];
|
||||
|
||||
parent = get_parent(node);
|
||||
color = get_color(node);
|
||||
parent = get_parent(node);
|
||||
color = get_color(node);
|
||||
|
||||
if(child != NULL)
|
||||
set_parent(child, parent);
|
||||
if(parent != NULL)
|
||||
{
|
||||
if(parent->child[LEFT] == node)
|
||||
parent->child[LEFT] = child;
|
||||
else
|
||||
parent->child[RIGHT] = child;
|
||||
}
|
||||
else
|
||||
tree->root = child;
|
||||
}
|
||||
if(child != NULL)
|
||||
set_parent(child, parent);
|
||||
if(parent != NULL)
|
||||
{
|
||||
if(parent->child[LEFT] == node)
|
||||
parent->child[LEFT] = child;
|
||||
else
|
||||
parent->child[RIGHT] = child;
|
||||
}
|
||||
else
|
||||
tree->root = child;
|
||||
}
|
||||
|
||||
if(color == BLACK)
|
||||
recolor(tree, parent, child);
|
||||
if(color == BLACK)
|
||||
recolor(tree, parent, child);
|
||||
|
||||
if(destructor != NULL)
|
||||
(*destructor)(original);
|
||||
if(destructor != NULL)
|
||||
(*destructor)(original);
|
||||
|
||||
tree->size -= 1;
|
||||
tree->size -= 1;
|
||||
|
||||
return next;
|
||||
return next;
|
||||
}
|
||||
|
@ -6,23 +6,23 @@ rbtree_rotate(rbtree_t *tree,
|
||||
rbtree_node_t *node,
|
||||
int left)
|
||||
{
|
||||
rbtree_node_t *tmp = node->child[left];
|
||||
rbtree_node_t *parent = get_parent(node);
|
||||
rbtree_node_t *tmp = node->child[left];
|
||||
rbtree_node_t *parent = get_parent(node);
|
||||
|
||||
node->child[left] = tmp->child[!left];
|
||||
if(tmp->child[!left] != NULL)
|
||||
set_parent(tmp->child[!left], node);
|
||||
node->child[left] = tmp->child[!left];
|
||||
if(tmp->child[!left] != NULL)
|
||||
set_parent(tmp->child[!left], node);
|
||||
|
||||
tmp->child[!left] = node;
|
||||
set_parent(tmp, parent);
|
||||
if(parent != NULL)
|
||||
{
|
||||
if(node == parent->child[!left])
|
||||
parent->child[!left] = tmp;
|
||||
else
|
||||
parent->child[left] = tmp;
|
||||
}
|
||||
else
|
||||
tree->root = tmp;
|
||||
set_parent(node, tmp);
|
||||
tmp->child[!left] = node;
|
||||
set_parent(tmp, parent);
|
||||
if(parent != NULL)
|
||||
{
|
||||
if(node == parent->child[!left])
|
||||
parent->child[!left] = tmp;
|
||||
else
|
||||
parent->child[left] = tmp;
|
||||
}
|
||||
else
|
||||
tree->root = tmp;
|
||||
set_parent(node, tmp);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user