Files @ e0e769795651
Branch filter:

Location: DistRen/src/server/user_mgr.c

LordOfWar
started on XML backup for distrens user manager
/*
  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 <http://www.gnu.org/licenses/>.
*/

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/encoding.h>
#include <libxml/xmlwriter.h>
#include <libxml/xmlreader.h>

#include "user_mgr.h"

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;

}