/*
Copyright 2009 Nathan Phillip Brink, Ethan Zonca, Matthew Orlando
This file is a part of DistRen.
DistRen is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
DistRen is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with DistRen. If not, see .
*/
#include "asprintf.h"
#include "user_mgr.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct user_mgr_info
{
struct user *user_array;
int current_users;
int user_array_size;
} user_mgr_info;
int resize_user_array()
{
int counter;
int counter2;
// create array twice the size of the current amount of users
user_mgr_info.user_array_size = user_mgr_info.current_users * 2;
struct user *new_user_array = malloc(sizeof(struct user) * user_mgr_info.user_array_size);
// this copies the original user_array over to the new one
// using two counters allows the array to be resized at any time
// leaving exactly 1 open space between each user when it is done;
counter2 = 0;
for(counter = 0; counter < user_mgr_info.current_users; counter++)
{
if(user_mgr_info.user_array[counter].username != 0)
{
new_user_array[counter2*2] = user_mgr_info.user_array[counter];
counter2++;
}
}
// cleanup old array
free(user_mgr_info.user_array);
// change the pointer to point to the new user array
user_mgr_info.user_array = new_user_array;
return 1;
}
struct user *findUser(char *nameOfUser)
{
int high;
int low;
int middle;
int result;
high = user_mgr_info.user_array_size - 1;
low = 0;
for(middle = (low+high)/2; 1 == 1; middle = (low+high)/2)
{
// in case middle lands on a part of the array with no user
while(user_mgr_info.user_array[middle].username == 0)
{
if(result < 0)
middle--;
else
middle++;
}
// this is where the array is cut in half and the half that the nameOfUser is on is kept
result = strcmp(nameOfUser, user_mgr_info.user_array[middle].username);
if(result == 0)
return &user_mgr_info.user_array[middle];
else if(result < 0)
high = middle;
else
low = middle;
// in case the user doesn't exist
if(high-low <= 0)
return 0;
}
}
int deleteUser(struct user *user_ptr)
{
free(user_ptr->username);
memset(user_ptr, '\0', sizeof(struct user));
return 1;
}
int createUser(struct user *user_ptr, char *nameOfUser)
{
// clear old memory
memset(user_ptr, '\0', sizeof(struct user));
user_ptr->username = nameOfUser;
user_ptr->render_power = 0;
user_ptr->last_job = 0;
return 1;
}
// places the new user at position index in the array, moves other users if it needs to
int placeUser(int index, char *nameOfUser)
{
int higher;
int lower;
// I shift data in the array to create an open the space where the user should be added
// but first I figure out which way is the shortest
if(user_mgr_info.user_array[index].username != 0)
{
higher = index + 1;
while(user_mgr_info.user_array[higher].username != 0)
higher++;
lower = index - 1;
while(user_mgr_info.user_array[lower].username != 0)
lower--;
// here the data is shifted to open up a space
if(index - lower < higher - index)
for(; lower < index; lower++)
memcpy(&user_mgr_info.user_array[lower], &user_mgr_info.user_array[lower + 1], sizeof(struct user));
else
for(; higher > index; higher--)
memcpy(&user_mgr_info.user_array[higher], &user_mgr_info.user_array[higher - 1], sizeof(struct user));
}
// add the user to the array
createUser(&user_mgr_info.user_array[index], nameOfUser);
return 1;
}
int addUser(char *nameOfUser)
{
int high;
int low;
int middle;
int result;
high = user_mgr_info.user_array_size - 1;
low = 0;
for(middle = (low+high)/2; 1 == 1; middle = (low+high)/2)
{
// in case middle lands on a part of the array with no user
while(user_mgr_info.user_array[middle].username == 0)
{
if(result < 0)
middle--;
else
middle++;
}
// this is where the array is cut in half and the half that the nameOfUser is on is kept
result = strcmp(nameOfUser, user_mgr_info.user_array[middle].username);
if(result == 0)
return 0;
else if(result < 0)
high = middle;
else
low = middle;
// once there are less than 10 possible places for the user to be placed
// break out of this loop and begin next loop
if(high-low <= 10)
break;
}
// this function starts at the low index number, and goes up until it finds a
// username that is bigger than it alphabetically, and tells the userPlacer
// that it needs to go 1 before that spot
for(; low <= high; low++)
{
while(user_mgr_info.user_array[low].username == 0)
low++;
result = strcmp(nameOfUser, user_mgr_info.user_array[low].username) < 0;
if(result < 0)
{
placeUser(low - 1, nameOfUser);
return 1;
}
if(result == 0)
{
fprintf(stderr, "user already exists");
return 0;
}
}
return 0;
}
int initialize_users()
{
// pull data from XML file
// if XML file is not found create new array of size 50
return 1;
}
/********************************** XMLness *****************************/
int backup_list_XML()
{
xmlTextWriterPtr writer;
char *tmp;
int counter;
writer = xmlNewTextWriterFilename("user_list.xml", 0);
xmlTextWriterStartDocument(writer, NULL, "utf-8", NULL);
// create root element user_list
xmlTextWriterStartElement(writer, (xmlChar*)"user_list");
for(counter = 0; counter < user_mgr_info.user_array_size; counter++)
{
if(user_mgr_info.user_array[counter].username != 0)
{
xmlTextWriterStartElement(writer, (xmlChar*)"user");
xmlTextWriterWriteAttribute(writer, (xmlChar*)"name", (xmlChar*)user_mgr_info.user_array[counter].username);
_distren_asprintf(&tmp, "%d", user_mgr_info.user_array[counter].last_job);
xmlTextWriterWriteAttribute(writer, (xmlChar*)"last_job", (xmlChar*)tmp);
xmlTextWriterEndElement(writer);
}
}
return 0;
}