2014-11-19 00:06:40 +08:00
|
|
|
|
#ifndef ACL_FIFO_INCLUDE_H
|
|
|
|
|
#define ACL_FIFO_INCLUDE_H
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
extern "C" {
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "acl_define.h"
|
|
|
|
|
#include "acl_slice.h"
|
|
|
|
|
#include "acl_iterator.h"
|
|
|
|
|
|
|
|
|
|
typedef struct ACL_FIFO_INFO ACL_FIFO_INFO;
|
|
|
|
|
typedef struct ACL_FIFO_ITER ACL_FIFO_ITER;
|
|
|
|
|
typedef struct ACL_FIFO ACL_FIFO;
|
|
|
|
|
|
|
|
|
|
struct ACL_FIFO_INFO {
|
|
|
|
|
void *data;
|
|
|
|
|
ACL_FIFO_INFO *prev;
|
|
|
|
|
ACL_FIFO_INFO *next;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ACL_FIFO_ITER {
|
|
|
|
|
ACL_FIFO_INFO *ptr;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ACL_FIFO {
|
|
|
|
|
ACL_FIFO_INFO *head;
|
|
|
|
|
ACL_FIFO_INFO *tail;
|
|
|
|
|
int cnt;
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD>Ӽ<EFBFBD><D3BC><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD> */
|
|
|
|
|
void (*push_back)(struct ACL_FIFO*, void*);
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD> */
|
|
|
|
|
void (*push_front)(struct ACL_FIFO*, void*);
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD> */
|
|
|
|
|
void *(*pop_back)(struct ACL_FIFO*);
|
|
|
|
|
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD> */
|
|
|
|
|
void *(*pop_front)(struct ACL_FIFO*);
|
|
|
|
|
|
|
|
|
|
/* for acl_iterator */
|
|
|
|
|
|
|
|
|
|
/* ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD> */
|
|
|
|
|
void *(*iter_head)(ACL_ITER*, struct ACL_FIFO*);
|
|
|
|
|
/* ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
void *(*iter_next)(ACL_ITER*, struct ACL_FIFO*);
|
|
|
|
|
/* ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><CEB2><EFBFBD><EFBFBD> */
|
|
|
|
|
void *(*iter_tail)(ACL_ITER*, struct ACL_FIFO*);
|
|
|
|
|
/* ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
|
|
|
|
|
void *(*iter_prev)(ACL_ITER*, struct ACL_FIFO*);
|
|
|
|
|
/* ȡ<><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ա<EFBFBD>ṹ<EFBFBD><E1B9B9><EFBFBD><EFBFBD> */
|
|
|
|
|
ACL_FIFO_INFO *(*iter_info)(ACL_ITER*, struct ACL_FIFO*);
|
|
|
|
|
|
|
|
|
|
/* private */
|
|
|
|
|
ACL_SLICE_POOL *slice;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD>Ӧ<EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ<EFBFBD>Ϸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>øú<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD>ʼ<EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO *}
|
|
|
|
|
* @example:
|
|
|
|
|
* void test(void) {
|
|
|
|
|
ACL_FIFO fifo;
|
|
|
|
|
|
|
|
|
|
acl_fifo_init(&fifo);
|
|
|
|
|
* }
|
|
|
|
|
*/
|
|
|
|
|
ACL_API void acl_fifo_init(ACL_FIFO *fifo);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @return {ACL_FIFO*}
|
|
|
|
|
*/
|
|
|
|
|
ACL_API ACL_FIFO *acl_fifo_new(void);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @param slice {ACL_SLICE_POOL*}
|
|
|
|
|
* @return {ACL_FIFO*}
|
|
|
|
|
*/
|
|
|
|
|
ACL_API ACL_FIFO *acl_fifo_new1(ACL_SLICE_POOL *slice);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>ͬ<EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO*}
|
|
|
|
|
* @param data {const void*}
|
|
|
|
|
*/
|
|
|
|
|
ACL_API int acl_fifo_delete(ACL_FIFO *fifo, const void *data);
|
|
|
|
|
ACL_API void acl_fifo_delete_info(ACL_FIFO *fifo, ACL_FIFO_INFO *info);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD>ͷ<EFBFBD><EFBFBD>Զѷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO*}
|
|
|
|
|
* @param free_fn {void (*)(void*)}, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ú<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>벻Ϊ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷŶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
*/
|
|
|
|
|
ACL_API void acl_fifo_free(ACL_FIFO *fifo, void (*free_fn)(void *));
|
|
|
|
|
ACL_API void acl_fifo_free2(ACL_FIFO *fifo, void (*free_fn)(ACL_FIFO_INFO *));
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD>Ѷ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO*}
|
|
|
|
|
* @param data {void*} <EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @return {ACL_FIFO_INFO*} <EFBFBD><EFBFBD><EFBFBD><EFBFBD> data <EFBFBD>ǿ<EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD> NULL
|
|
|
|
|
*/
|
|
|
|
|
ACL_API ACL_FIFO_INFO *acl_fifo_push_back(ACL_FIFO *fifo, void *data);
|
|
|
|
|
#define acl_fifo_push acl_fifo_push_back
|
|
|
|
|
ACL_API void acl_fifo_push_info_back(ACL_FIFO *fifo, ACL_FIFO_INFO *info);
|
|
|
|
|
#define acl_fifo_push_info acl_fifo_push_info_back
|
|
|
|
|
ACL_API ACL_FIFO_INFO *acl_fifo_push_front(ACL_FIFO *fifo, void *data);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƚ<EFBFBD><EFBFBD>ȳ<EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, ͬʱ<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO*}
|
|
|
|
|
* @return {void*}, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>
|
|
|
|
|
*/
|
|
|
|
|
ACL_API void *acl_fifo_pop_front(ACL_FIFO *fifo);
|
|
|
|
|
#define acl_fifo_pop acl_fifo_pop_front
|
|
|
|
|
ACL_API ACL_FIFO_INFO *acl_fifo_pop_info(ACL_FIFO *fifo);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ժ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȳ<EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ͬʱ<EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO*}
|
|
|
|
|
* @return {void*}, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>
|
|
|
|
|
*/
|
|
|
|
|
ACL_API void *acl_fifo_pop_back(ACL_FIFO *fifo);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO*}
|
|
|
|
|
* @return {void*}, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>
|
|
|
|
|
*/
|
|
|
|
|
ACL_API void *acl_fifo_head(ACL_FIFO *fifo);
|
|
|
|
|
ACL_API ACL_FIFO_INFO *acl_fifo_head_info(ACL_FIFO *fifo);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>β<EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO*}
|
|
|
|
|
* @return {void*}, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD>
|
|
|
|
|
*/
|
|
|
|
|
ACL_API void *acl_fifo_tail(ACL_FIFO *fifo);
|
|
|
|
|
ACL_API ACL_FIFO_INFO *acl_fifo_tail_info(ACL_FIFO *fifo);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>ض<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>̬<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܸ<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
* @param fifo {ACL_FIFO*}
|
|
|
|
|
* @return {int}, >= 0
|
|
|
|
|
*/
|
|
|
|
|
ACL_API int acl_fifo_size(ACL_FIFO *fifo);
|
|
|
|
|
|
|
|
|
|
/*-------------------- һЩ<D2BB><D0A9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݵĺ<DDB5><C4BA><EFBFBD><EFBFBD><EFBFBD> --------------------------------*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD>ǰ iter <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
|
|
|
|
* @param iter {ACL_FIFO_ITER}
|
|
|
|
|
*/
|
|
|
|
|
#define ACL_FIFO_ITER_VALUE(iter) ((iter).ptr->data)
|
|
|
|
|
#define acl_fifo_iter_value ACL_FIFO_ITER_VALUE
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> ACL_FIFO
|
|
|
|
|
* @param iter {ACL_FIFO_ITER}
|
|
|
|
|
* @param fifo {ACL_FIFO}
|
|
|
|
|
* @example:
|
|
|
|
|
-- <EFBFBD><EFBFBD><EFBFBD>DZ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֧<EFBFBD>ֵı<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
|
|
|
|
void test()
|
|
|
|
|
{
|
|
|
|
|
ACL_FIFO *fifo_ptr = acl_fifo_new();
|
|
|
|
|
ACL_FIFO_ITER iter;
|
|
|
|
|
char *data;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
|
data = acl_mymalloc(32);
|
|
|
|
|
snprintf(data, 32, "data: %d", i);
|
|
|
|
|
acl_fifo_push(fifo_ptr, data);
|
|
|
|
|
}
|
|
|
|
|
acl_fifo_foreach(iter, fifo_ptr) {
|
|
|
|
|
printf("%s\n", (char*) acl_fifo_iter_value(iter));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
acl_fifo_free(fifo_ptr, acl_myfree_fn);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-- ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ
|
|
|
|
|
void test2()
|
|
|
|
|
{
|
|
|
|
|
ACL_FIFO *fifo_ptr = acl_fifo_new();
|
|
|
|
|
ACL_ITER iter;
|
|
|
|
|
char *data;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
|
data = acl_mymalloc(32);
|
|
|
|
|
snprintf(data, 32, "data: %d", i);
|
|
|
|
|
acl_fifo_push(fifo_ptr, data);
|
|
|
|
|
}
|
|
|
|
|
acl_foreach(iter, fifo) {
|
|
|
|
|
printf("%s\n", (char*) iter.data);
|
|
|
|
|
}
|
|
|
|
|
acl_fifo_free(fifo_ptr, acl_myfree_fn);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
#define ACL_FIFO_FOREACH(iter, fifo_ptr) \
|
|
|
|
|
for ((iter).ptr = (fifo_ptr)->head; (iter).ptr; (iter).ptr = (iter).ptr->next)
|
|
|
|
|
#define acl_fifo_foreach ACL_FIFO_FOREACH
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ACL_FIFO
|
|
|
|
|
* @param iter {ACL_FIFO_ITER}
|
|
|
|
|
* @param fifo {ACL_FIFO}
|
|
|
|
|
* @example:
|
|
|
|
|
void test()
|
|
|
|
|
{
|
|
|
|
|
ACL_FIFO fifo;
|
|
|
|
|
ACL_FIFO_ITER iter;
|
|
|
|
|
char *data;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
acl_fifo_init(&fifo);
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < 10; i++) {
|
|
|
|
|
data = acl_mymalloc(32);
|
|
|
|
|
snprintf(data, 32, "data: %d", i);
|
|
|
|
|
acl_fifo_push(&fifo, data);
|
|
|
|
|
}
|
|
|
|
|
acl_fifo_foreach_reverse(iter, &fifo) {
|
|
|
|
|
printf("%s\n", (char*) iter.ptr->data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
data = acl_fifo_pop(&fifo);
|
|
|
|
|
if (data == NULL)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
#define ACL_FIFO_FOREACH_REVERSE(iter, fifo_ptr) \
|
|
|
|
|
for ((iter).ptr = (fifo_ptr)->tail; (iter).ptr; (iter).ptr = (iter).ptr->prev)
|
|
|
|
|
#define acl_fifo_foreach_reverse ACL_FIFO_FOREACH_REVERSE
|
|
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|