libfreerdp-utils: purge deprecated list utils
This commit is contained in:
parent
3ee6494d36
commit
fb3f5e6bd2
@ -30,7 +30,6 @@
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
|
||||
#include "drdynvc_types.h"
|
||||
#include "dvcman.h"
|
||||
|
@ -31,7 +31,6 @@
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/addin.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/client/channels.h>
|
||||
|
||||
#include "rdpdr_main.h"
|
||||
|
@ -31,11 +31,10 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/stream.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/constants.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
#include "sample_main.h"
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
|
||||
|
@ -28,9 +28,8 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
||||
|
@ -38,10 +38,9 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/thread.h>
|
||||
#include <winpr/stream.h>
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <winpr/stream.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/event.h>
|
||||
#include <freerdp/client/tsmf.h>
|
||||
|
||||
@ -90,7 +89,7 @@ struct _TSMF_PRESENTATION
|
||||
HANDLE mutex;
|
||||
HANDLE thread;
|
||||
|
||||
LIST* stream_list;
|
||||
wArrayList* stream_list;
|
||||
};
|
||||
|
||||
struct _TSMF_STREAM
|
||||
@ -142,7 +141,7 @@ struct _TSMF_SAMPLE
|
||||
UINT64 ack_time;
|
||||
};
|
||||
|
||||
static LIST* presentation_list = NULL;
|
||||
static wArrayList* presentation_list = NULL;
|
||||
static UINT64 last_played_audio_time = 0;
|
||||
static HANDLE tsmf_mutex = NULL;
|
||||
static int TERMINATING = 0;
|
||||
@ -157,8 +156,9 @@ static UINT64 get_current_time(void)
|
||||
|
||||
static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream, int sync)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
TSMF_STREAM* s;
|
||||
LIST_ITEM* item;
|
||||
TSMF_SAMPLE* sample;
|
||||
BOOL pending = FALSE;
|
||||
TSMF_PRESENTATION* presentation = stream->presentation;
|
||||
@ -177,11 +177,13 @@ static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream, int sync)
|
||||
/* Check if some other stream has earlier sample that needs to be played first */
|
||||
if (stream->last_end_time > AUDIO_TOLERANCE)
|
||||
{
|
||||
WaitForSingleObject(presentation->mutex, INFINITE);
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
s = (TSMF_STREAM*) item->data;
|
||||
s = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
|
||||
if (s != stream && !s->eos && s->last_end_time &&
|
||||
s->last_end_time < stream->last_end_time - AUDIO_TOLERANCE)
|
||||
@ -191,7 +193,7 @@ static TSMF_SAMPLE* tsmf_stream_pop_sample(TSMF_STREAM* stream, int sync)
|
||||
}
|
||||
}
|
||||
|
||||
ReleaseMutex(presentation->mutex);
|
||||
ArrayList_Unlock(presentation->stream_list);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -279,35 +281,48 @@ TSMF_PRESENTATION* tsmf_presentation_new(const BYTE* guid, IWTSVirtualChannelCal
|
||||
return NULL;
|
||||
}
|
||||
|
||||
presentation = (TSMF_PRESENTATION*) malloc(sizeof(TSMF_PRESENTATION));
|
||||
ZeroMemory(presentation, sizeof(TSMF_PRESENTATION));
|
||||
presentation = (TSMF_PRESENTATION*) calloc(1, sizeof(TSMF_PRESENTATION));
|
||||
|
||||
memcpy(presentation->presentation_id, guid, GUID_SIZE);
|
||||
CopyMemory(presentation->presentation_id, guid, GUID_SIZE);
|
||||
presentation->channel_callback = pChannelCallback;
|
||||
|
||||
presentation->volume = 5000; /* 50% */
|
||||
presentation->muted = 0;
|
||||
|
||||
presentation->mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
presentation->stream_list = list_new();
|
||||
presentation->stream_list = ArrayList_New(TRUE);
|
||||
ArrayList_Object(presentation->stream_list)->fnObjectFree = (OBJECT_FREE_FN) tsmf_stream_free;
|
||||
|
||||
list_enqueue(presentation_list, presentation);
|
||||
ArrayList_Add(presentation_list, presentation);
|
||||
|
||||
return presentation;
|
||||
}
|
||||
|
||||
TSMF_PRESENTATION* tsmf_presentation_find_by_id(const BYTE* guid)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
BOOL found = FALSE;
|
||||
TSMF_PRESENTATION* presentation;
|
||||
|
||||
for (item = presentation_list->head; item; item = item->next)
|
||||
ArrayList_Lock(presentation_list);
|
||||
|
||||
count = ArrayList_Count(presentation_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
presentation = (TSMF_PRESENTATION*) item->data;
|
||||
presentation = (TSMF_PRESENTATION*) ArrayList_GetItem(presentation_list, index);
|
||||
|
||||
if (memcmp(presentation->presentation_id, guid, GUID_SIZE) == 0)
|
||||
return presentation;
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ArrayList_Unlock(presentation_list);
|
||||
|
||||
return (found) ? presentation : NULL;
|
||||
}
|
||||
|
||||
static void tsmf_presentation_restore_last_video_frame(TSMF_PRESENTATION* presentation)
|
||||
@ -789,69 +804,103 @@ static void tsmf_stream_change_volume(TSMF_STREAM* stream, UINT32 newVolume, UIN
|
||||
|
||||
void tsmf_presentation_volume_changed(TSMF_PRESENTATION* presentation, UINT32 newVolume, UINT32 muted)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
presentation->volume = newVolume;
|
||||
presentation->muted = muted;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
tsmf_stream_change_volume(stream, newVolume, muted);
|
||||
}
|
||||
|
||||
ArrayList_Unlock(presentation->stream_list);
|
||||
}
|
||||
|
||||
void tsmf_presentation_paused(TSMF_PRESENTATION* presentation)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
tsmf_stream_pause(stream);
|
||||
}
|
||||
|
||||
ArrayList_Unlock(presentation->stream_list);
|
||||
}
|
||||
|
||||
void tsmf_presentation_restarted(TSMF_PRESENTATION* presentation)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
tsmf_stream_restart(stream);
|
||||
}
|
||||
|
||||
ArrayList_Unlock(presentation->stream_list);
|
||||
}
|
||||
|
||||
void tsmf_presentation_start(TSMF_PRESENTATION* presentation)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
tsmf_stream_start(stream);
|
||||
}
|
||||
|
||||
ArrayList_Unlock(presentation->stream_list);
|
||||
}
|
||||
|
||||
void tsmf_presentation_stop(TSMF_PRESENTATION* presentation)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
tsmf_presentation_flush(presentation);
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
tsmf_stream_stop(stream);
|
||||
}
|
||||
|
||||
ArrayList_Unlock(presentation->stream_list);
|
||||
|
||||
tsmf_presentation_restore_last_video_frame(presentation);
|
||||
|
||||
if (presentation->last_rects)
|
||||
@ -914,15 +963,22 @@ static void tsmf_stream_flush(TSMF_STREAM* stream)
|
||||
|
||||
void tsmf_presentation_flush(TSMF_PRESENTATION* presentation)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
TSMF_STREAM * stream;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
tsmf_stream_flush(stream);
|
||||
}
|
||||
|
||||
ArrayList_Unlock(presentation->stream_list);
|
||||
|
||||
presentation->eos = 0;
|
||||
presentation->audio_start_time = 0;
|
||||
presentation->audio_end_time = 0;
|
||||
@ -930,19 +986,10 @@ void tsmf_presentation_flush(TSMF_PRESENTATION* presentation)
|
||||
|
||||
void tsmf_presentation_free(TSMF_PRESENTATION* presentation)
|
||||
{
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
tsmf_presentation_stop(presentation);
|
||||
WaitForSingleObject(presentation->mutex, INFINITE);
|
||||
list_remove(presentation_list, presentation);
|
||||
ReleaseMutex(presentation->mutex);
|
||||
|
||||
while (list_size(presentation->stream_list) > 0)
|
||||
{
|
||||
stream = (TSMF_STREAM*) list_dequeue(presentation->stream_list);
|
||||
tsmf_stream_free(stream);
|
||||
}
|
||||
list_free(presentation->stream_list);
|
||||
ArrayList_Remove(presentation_list, presentation);
|
||||
ArrayList_Free(presentation->stream_list);
|
||||
|
||||
CloseHandle(presentation->mutex);
|
||||
|
||||
@ -978,27 +1025,36 @@ TSMF_STREAM* tsmf_stream_new(TSMF_PRESENTATION* presentation, UINT32 stream_id)
|
||||
stream->sample_ack_list = Queue_New(TRUE, -1, -1);
|
||||
stream->sample_ack_list->object.fnObjectFree = free;
|
||||
|
||||
WaitForSingleObject(presentation->mutex, INFINITE);
|
||||
list_enqueue(presentation->stream_list, stream);
|
||||
ReleaseMutex(presentation->mutex);
|
||||
ArrayList_Add(presentation->stream_list, stream);
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
TSMF_STREAM* tsmf_stream_find_by_id(TSMF_PRESENTATION* presentation, UINT32 stream_id)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
UINT32 index;
|
||||
UINT32 count;
|
||||
BOOL found = FALSE;
|
||||
TSMF_STREAM* stream;
|
||||
|
||||
for (item = presentation->stream_list->head; item; item = item->next)
|
||||
ArrayList_Lock(presentation->stream_list);
|
||||
|
||||
count = ArrayList_Count(presentation->stream_list);
|
||||
|
||||
for (index = 0; index < count; index++)
|
||||
{
|
||||
stream = (TSMF_STREAM*) item->data;
|
||||
stream = (TSMF_STREAM*) ArrayList_GetItem(presentation->stream_list, index);
|
||||
|
||||
if (stream->stream_id == stream_id)
|
||||
return stream;
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
ArrayList_Unlock(presentation->stream_list);
|
||||
|
||||
return (found) ? stream : NULL;
|
||||
}
|
||||
|
||||
void tsmf_stream_set_format(TSMF_STREAM* stream, const char* name, wStream* s)
|
||||
@ -1054,9 +1110,7 @@ void tsmf_stream_free(TSMF_STREAM* stream)
|
||||
tsmf_stream_stop(stream);
|
||||
tsmf_stream_flush(stream);
|
||||
|
||||
WaitForSingleObject(presentation->mutex, INFINITE);
|
||||
list_remove(presentation->stream_list, stream);
|
||||
ReleaseMutex(presentation->mutex);
|
||||
ArrayList_Remove(presentation->stream_list, stream);
|
||||
|
||||
Queue_Free(stream->sample_list);
|
||||
Queue_Free(stream->sample_ack_list);
|
||||
@ -1089,8 +1143,7 @@ void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pC
|
||||
|
||||
ReleaseMutex(tsmf_mutex);
|
||||
|
||||
sample = (TSMF_SAMPLE*) malloc(sizeof(TSMF_SAMPLE));
|
||||
ZeroMemory(sample, sizeof(TSMF_SAMPLE));
|
||||
sample = (TSMF_SAMPLE*) calloc(1, sizeof(TSMF_SAMPLE));
|
||||
|
||||
sample->sample_id = sample_id;
|
||||
sample->start_time = start_time;
|
||||
@ -1111,28 +1164,11 @@ void tsmf_stream_push_sample(TSMF_STREAM* stream, IWTSVirtualChannelCallback* pC
|
||||
|
||||
static void tsmf_signal_handler(int s)
|
||||
{
|
||||
LIST_ITEM* p_item;
|
||||
TSMF_PRESENTATION* presentation;
|
||||
LIST_ITEM* s_item;
|
||||
TSMF_STREAM* _stream;
|
||||
|
||||
WaitForSingleObject(tsmf_mutex, INFINITE);
|
||||
TERMINATING = 1;
|
||||
ReleaseMutex(tsmf_mutex);
|
||||
|
||||
if (presentation_list)
|
||||
{
|
||||
for (p_item = presentation_list->head; p_item; p_item = p_item->next)
|
||||
{
|
||||
presentation = (TSMF_PRESENTATION*) p_item->data;
|
||||
for (s_item = presentation->stream_list->head; s_item; s_item = s_item->next)
|
||||
{
|
||||
_stream = (TSMF_STREAM*) s_item->data;
|
||||
tsmf_stream_free(_stream);
|
||||
}
|
||||
tsmf_presentation_free(presentation);
|
||||
}
|
||||
}
|
||||
ArrayList_Free(presentation_list);
|
||||
|
||||
unlink("/tmp/tsmf.tid");
|
||||
|
||||
@ -1162,7 +1198,9 @@ void tsmf_media_init(void)
|
||||
|
||||
tsmf_mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
|
||||
if (presentation_list == NULL)
|
||||
presentation_list = list_new();
|
||||
if (!presentation_list)
|
||||
{
|
||||
presentation_list = ArrayList_New(TRUE);
|
||||
ArrayList_Object(presentation_list)->fnObjectFree = (OBJECT_FREE_FN) tsmf_presentation_free;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include <winpr/collections.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
|
||||
#define RDPDR_DEVICE_IO_REQUEST_LENGTH 24
|
||||
#define RDPDR_DEVICE_IO_RESPONSE_LENGTH 16
|
||||
|
@ -1,61 +0,0 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Double-linked List Utils
|
||||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FREERDP_UTILS_LIST_H
|
||||
#define FREERDP_UTILS_LIST_H
|
||||
|
||||
#include <freerdp/api.h>
|
||||
|
||||
typedef struct _LIST_ITEM LIST_ITEM;
|
||||
|
||||
struct _LIST_ITEM
|
||||
{
|
||||
void* data;
|
||||
LIST_ITEM* prev;
|
||||
LIST_ITEM* next;
|
||||
};
|
||||
|
||||
typedef struct _LIST LIST;
|
||||
|
||||
struct _LIST
|
||||
{
|
||||
int count;
|
||||
LIST_ITEM* head;
|
||||
LIST_ITEM* tail;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
FREERDP_API LIST* list_new(void);
|
||||
FREERDP_API void list_free(LIST* list);
|
||||
FREERDP_API void list_enqueue(LIST* list, void* data);
|
||||
FREERDP_API void* list_dequeue(LIST* list);
|
||||
FREERDP_API void* list_peek(LIST* list);
|
||||
FREERDP_API void* list_next(LIST* list, void* data);
|
||||
#define list_add(_l, _d) list_enqueue(_l, _d)
|
||||
FREERDP_API void* list_remove(LIST* list, void* data);
|
||||
FREERDP_API int list_size(LIST* list);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FREERDP_UTILS_LIST_H */
|
@ -21,7 +21,6 @@
|
||||
#define FREERDP_CORE_SERVER_H
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/utils/list.h>
|
||||
#include <freerdp/utils/debug.h>
|
||||
#include <freerdp/channels/wtsvc.h>
|
||||
|
||||
|
@ -21,7 +21,6 @@ set(MODULE_PREFIX "FREERDP_UTILS")
|
||||
set(${MODULE_PREFIX}_SRCS
|
||||
event.c
|
||||
bitmap.c
|
||||
list.c
|
||||
passphrase.c
|
||||
pcap.c
|
||||
profiler.c
|
||||
|
@ -1,262 +0,0 @@
|
||||
/*
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* Double-linked List Utils
|
||||
*
|
||||
* Copyright 2011 Vic Lee
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include <freerdp/utils/list.h>
|
||||
|
||||
/**
|
||||
* Allocates a new LIST_ITEM element. This will be used to store the data provided by the caller,
|
||||
* and will be used as a new element in a list.
|
||||
*
|
||||
* @param data - pointer to the data that must be stored by the new item.
|
||||
*
|
||||
* @return An allocated LIST_ITEM element that contains the 'data' pointer.
|
||||
*/
|
||||
static LIST_ITEM* list_item_new(void* data)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
|
||||
item = (LIST_ITEM*) malloc(sizeof(LIST_ITEM));
|
||||
ZeroMemory(item, sizeof(LIST_ITEM));
|
||||
|
||||
if (item)
|
||||
item->data = data;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches an element in the list.
|
||||
* The element is verified by its pointer value - there is no way to verify the buffer's content.
|
||||
*
|
||||
* @param list - pointer to a valid LIST structure
|
||||
* @param data - pointer to the data that must be found.
|
||||
*
|
||||
* @return the LIST_ITEM element that contains the 'data' pointer. NULL if 'data' was not found.
|
||||
*/
|
||||
static LIST_ITEM* list_item_find(LIST* list, void* data)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
|
||||
for (item = list->head; item; item = item->next)
|
||||
{
|
||||
if (item->data == data)
|
||||
return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates a new LIST structure.
|
||||
* The list_*() API implements a chainlist and allows to store data of arbitrary type in FIFO mode.
|
||||
* @see list_enqueue() to add elements to the list.
|
||||
* @see list_dequeue() to remove the first element of the list and get a pointer to it.
|
||||
* @see list_peek() to retrieve the first element of the list (and keep it there).
|
||||
* @see list_free() to deallocate the list.
|
||||
* @see list_size() to get the current number of elements in the list.
|
||||
*
|
||||
* @return A pointer to the allocated LIST structure. It must be deallocated by a call to list_free().
|
||||
*
|
||||
*/
|
||||
LIST* list_new(void)
|
||||
{
|
||||
LIST* list;
|
||||
|
||||
list = (LIST*) malloc(sizeof(LIST));
|
||||
ZeroMemory(list, sizeof(LIST));
|
||||
|
||||
list->count = 0;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deallocates a LIST structure.
|
||||
* All elements of the list will be removed (but not deallocated). Only the list-specific resources are freed.
|
||||
*
|
||||
* @param list - pointer to the LIST that must be deallocated.
|
||||
*/
|
||||
void list_free(LIST* list)
|
||||
{
|
||||
while (list->head)
|
||||
list_dequeue(list);
|
||||
|
||||
free(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an element at the end of an existing list.
|
||||
*
|
||||
* @param list - pointer to the LIST that will contain the new element
|
||||
* @param data - pointer to the buffer that will be added to the list
|
||||
*/
|
||||
void list_enqueue(LIST* list, void* data)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
|
||||
item = list_item_new(data);
|
||||
|
||||
if (list->tail == NULL)
|
||||
{
|
||||
list->head = item;
|
||||
list->tail = item;
|
||||
}
|
||||
else
|
||||
{
|
||||
item->prev = list->tail;
|
||||
list->tail->next = item;
|
||||
list->tail = item;
|
||||
}
|
||||
|
||||
list->count++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the first element of a list, and returns a pointer to it.
|
||||
* The list-specific resources associated to this element are freed in the process.
|
||||
*
|
||||
* @param list - pointer to a valid LIST structure
|
||||
*
|
||||
* @return a pointer to the data of the first element of this list. NULL if the list is empty.
|
||||
*/
|
||||
void* list_dequeue(LIST* list)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
void* data = NULL;
|
||||
|
||||
item = list->head;
|
||||
|
||||
if (item != NULL)
|
||||
{
|
||||
list->head = item->next;
|
||||
|
||||
if (list->head == NULL)
|
||||
list->tail = NULL;
|
||||
else
|
||||
list->head->prev = NULL;
|
||||
|
||||
data = item->data;
|
||||
free(item);
|
||||
list->count--;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pointer to the data from the first element of the list.
|
||||
* The element itself is not removed from the list by this call.
|
||||
*
|
||||
* @param list - pointerto a valid LIST structure
|
||||
*
|
||||
* @return a pointer to the data of the first element of this list. NULL if the list is empty.
|
||||
*/
|
||||
void* list_peek(LIST* list)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
|
||||
item = list->head;
|
||||
return item ? item->data : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the data provided in parameter, and returns a pointer to the element next to it.
|
||||
* If the item is not found, or if it is the last in the list, the function will return NULL.
|
||||
*
|
||||
* @param list - pointer to the list that must be searched.
|
||||
* @param data - pointer to the buffer that must be found. The comparison is done on the pointer value - not the buffer's content.
|
||||
*
|
||||
* @return a pointer to the data of the element that resides after the 'data' parameter in the list.
|
||||
* NULL if 'data' was not found in the list, or if it is the last element.
|
||||
*
|
||||
* @see list_item_find() for more information on list item searches.
|
||||
*/
|
||||
void* list_next(LIST* list, void* data)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
|
||||
item = list_item_find(list, data);
|
||||
data = NULL;
|
||||
|
||||
if (item != NULL)
|
||||
{
|
||||
if (item->next != NULL)
|
||||
data = item->next->data;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the data provided in parameter, and removes it from the list if it is found.
|
||||
*
|
||||
* @param list - pointer to the list that must be searched.
|
||||
* @param data - pointer to the buffer that must be found. The comparison is done on the pointer value - not the buffer's content.
|
||||
*
|
||||
* @return the 'data' pointer, if the element was found, and successfully removed from the list.
|
||||
* NULL if the element was not found.
|
||||
*/
|
||||
void* list_remove(LIST* list, void* data)
|
||||
{
|
||||
LIST_ITEM* item;
|
||||
|
||||
item = list_item_find(list, data);
|
||||
|
||||
if (item != NULL)
|
||||
{
|
||||
if (item->prev != NULL)
|
||||
item->prev->next = item->next;
|
||||
if (item->next != NULL)
|
||||
item->next->prev = item->prev;
|
||||
if (list->head == item)
|
||||
list->head = item->next;
|
||||
if (list->tail == item)
|
||||
list->tail = item->prev;
|
||||
free(item);
|
||||
list->count--;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current size of the list (number of elements).
|
||||
* This number is kept up to date by the list_enqueue and list_dequeue functions.
|
||||
*
|
||||
* @param list - pointer to a valide LIST structure.
|
||||
*
|
||||
* @return the number of elements in that list.
|
||||
*/
|
||||
int list_size(LIST* list)
|
||||
{
|
||||
return list->count;
|
||||
}
|
Loading…
Reference in New Issue
Block a user