From 0e894b1b633c488bbdfbcf2b4fb1276f819a6ffc Mon Sep 17 00:00:00 2001 From: Willem Haffmans Date: Fri, 26 Jul 2024 22:30:53 +0200 Subject: [PATCH] add all --- scratch/get_next_line.c | 240 ++++++++++++++++++++++++++++++++ scratch/get_next_line.h | 31 +++++ scratch/get_next_line_utils.c | 45 ++++++ src/get_next_line.c | 122 ++++++++++++++++ src/get_next_line.h | 34 +++++ src/get_next_line_bonus.c | 122 ++++++++++++++++ src/get_next_line_bonus.h | 38 +++++ src/get_next_line_utils.c | 70 ++++++++++ src/get_next_line_utils_bonus.c | 70 ++++++++++ src/test.c | 68 +++++++++ src/test.txt | 4 + src2/test.c | 54 +++++++ 12 files changed, 898 insertions(+) create mode 100644 scratch/get_next_line.c create mode 100644 scratch/get_next_line.h create mode 100644 scratch/get_next_line_utils.c create mode 100644 src/get_next_line.c create mode 100644 src/get_next_line.h create mode 100644 src/get_next_line_bonus.c create mode 100644 src/get_next_line_bonus.h create mode 100644 src/get_next_line_utils.c create mode 100644 src/get_next_line_utils_bonus.c create mode 100644 src/test.c create mode 100644 src/test.txt create mode 100644 src2/test.c diff --git a/scratch/get_next_line.c b/scratch/get_next_line.c new file mode 100644 index 0000000..2d25536 --- /dev/null +++ b/scratch/get_next_line.c @@ -0,0 +1,240 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: whaffman +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/11 17:35:46 by whaffman #+# #+# */ +/* Updated: 2024/07/12 10:18:44 by whaffman ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" +#include + +size_t ft_strlen(const char *s) +{ + size_t length; + + length = 0; + while (*s++) + length++; + return (length); +} + +char *ft_strchr(const char *str, int c) +{ + while (*str) + { + if (*str == c) + return ((char *) str); + str++; + } + if (*str == c) + return ((char *) str); + return (NULL); +} + +void ft_lstclear(t_list **lst, void (*del)(void *)) +{ + t_list *next; + + if (!del || !lst) + return ; + while (*lst) + { + if ((*lst)->next) + next = (*lst)->next; + else + next = NULL; + del((*lst)->content); + free(*lst); + *lst = next; + } +} + +t_list *new_node(size_t size) +{ + t_list *node; + char *buffer; + + if (size <= 0) + return (NULL); + buffer = malloc(size * sizeof(char)); + if (!buffer) + return (NULL); + node = malloc(sizeof(t_list)); + if (!node) + { + free(buffer); + return (NULL); + } + node->content = buffer; + node->next = NULL; + return (node); +} + +int read_block(int fd, t_list **stock) +{ + t_list *node; + int read_result; + + if (fd < 0) + return (-1); + node = new_node(BUFFER_SIZE + 1); + if (!node) + return (-1); + read_result = read(fd, node->content, BUFFER_SIZE); + if (read_result > 0) + { + (node->content)[read_result] = '\0'; + node->next = NULL; + *stock = node; + } + return (read_result); +} + +int restock(int fd, t_list **stock) +{ + int read_result; + t_list *last_node = *stock; + + // Find the last node in the list + while (last_node && last_node->next) + last_node = last_node->next; + + // Read blocks until a newline or EOF is reached + while (1) + { + read_result = read_block(fd, &last_node); + if (read_result < 0) + return -1; + if (read_result == 0 || ft_strchr(last_node->content, '\n')) + break; + last_node = last_node->next; + } + + return read_result; +} + +size_t len_till_newline(t_list *lst) +{ + size_t len; + size_t i; + + len = 0; + while(lst) + { + i = 0; + while (lst->content[i] && lst->content[i] != '\n') + { + len++; + i++; + } + if (lst->content[i] == '\n') + return (len + 1); + lst = lst->next; + } + return (len); +} + +char *get_line(t_list *lst) +{ + size_t i; + size_t j; + size_t len; + char *line; + + len = len_till_newline(lst); + line = malloc((len + 1) * sizeof(char)); + if (!line) + return (NULL); + i = 0; + while (i < len && lst) + { + j = 0; + while(lst->content[j]) + { + line[i + j] = (char) lst->content[j]; + j++; + } + i += j; + lst = lst->next; + } + line[i] = '\0'; + return (line); +} + +void clean_lst(t_list **lst) +{ + t_list *last; + t_list *new; + size_t i; + size_t j; + + last = *lst; + while(last->next) + last = last->next; + i = 0; + while(last->content[i] && last->content[i] != '\n') + i++; + if (!last->content[i]) + { + new = new_node(ft_strlen(&(last->content[i++])) + 1); + if (!new) + return ; + j = 0; + while (last->content[i + j]) + { + new->content[j] = last->content[i + j]; + j++; + } + ft_lstclear(lst, free); + *lst = new; + } +} + +char *get_next_line(int fd) +{ + static t_list *stock; + char *line; + + if (fd < 0) + return (NULL); + restock(fd, &stock); + if (!stock) + return (NULL); + line = get_line(stock); + clean_lst(&stock); + return (line); +} + + +#include + +int main(int argc, char **argv) +{ + int fd; + char *line; + + if (argc > 1) + fd = open(argv[1], O_RDONLY); + else + fd = STDIN_FILENO; + + if (fd < 0) + { + return 1; + } + + while ((line = get_next_line(fd)) != NULL) + { + printf("%s\n", line); + free(line); + } + + close(fd); + + return 0; +} \ No newline at end of file diff --git a/scratch/get_next_line.h b/scratch/get_next_line.h new file mode 100644 index 0000000..e7a4dca --- /dev/null +++ b/scratch/get_next_line.h @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: whaffman +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/11 17:36:01 by whaffman #+# #+# */ +/* Updated: 2024/07/12 10:18:47 by whaffman ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H + +# include +# include + +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 80 +# endif + +typedef struct s_list +{ + char *content; + struct s_list *next; +} t_list; + +char *get_next_line(int fd); + +#endif diff --git a/scratch/get_next_line_utils.c b/scratch/get_next_line_utils.c new file mode 100644 index 0000000..1821403 --- /dev/null +++ b/scratch/get_next_line_utils.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* get_next_line_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: whaffman +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/11 17:38:00 by whaffman #+# #+# */ +/* Updated: 2024/07/11 18:37:49 by whaffman ### ########.fr */ +/* */ +/* ************************************************************************** */ + + +#include + +char *ft_strdup(const char *s) +{ + size_t size; + char *d; + + size = ft_strlen(s) + 1; + d = (char *) malloc(size * sizeof(char)); + if (d) + ft_strlcpy(d, s, size); + return (d); +} + +char *ft_strjoin(char const *s1, char const *s2) +{ + char *str; + size_t len_s1; + size_t len_s2; + + if (!s1 || !s2) + return (NULL); + len_s1 = ft_strlen(s1); + len_s2 = ft_strlen(s2); + str = (char *)malloc(len_s1 + len_s2 + 1); + if (!str) + return (NULL); + ft_memcpy(str, s1, len_s1); + ft_memcpy(str + len_s1, s2, len_s2); + str[len_s1 + len_s2] = '\0'; + return (str); +} diff --git a/src/get_next_line.c b/src/get_next_line.c new file mode 100644 index 0000000..1f1eed0 --- /dev/null +++ b/src/get_next_line.c @@ -0,0 +1,122 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_next_line.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/07/15 16:59:55 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/07/15 17:00:24 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +void clean(void **ptr) +{ + if (*ptr) + { + free(*ptr); + *ptr = NULL; + } +} + +int check_and_extract(char **line, char **stock) +{ + char *temp1; + char *temp2; + + if (!stock || !*stock) + return (0); + temp1 = *stock; + while (temp1 && *temp1 != '\n') + if (!*temp1++) + return (0); + if (temp1) + temp1++; + temp2 = ft_strdup(temp1); + *temp1 = '\0'; + *line = ft_strdup(*stock); + free(*stock); + *stock = temp2; + if (!*line || !*stock) + { + clean((void **)line); + clean((void **)stock); + return (-1); + } + return (1); +} + +int ft_read(int fd, char **buffer, size_t size) +{ + int bytes_read; + + if (!*buffer) + { + *buffer = malloc(sizeof(char) * (BUFFER_SIZE + 1)); + if (!*buffer) + return (-1); + } + bytes_read = read(fd, *buffer, size); + if (bytes_read >= 0) + (*buffer)[bytes_read] = '\0'; + return (bytes_read); +} + +int read_file(int fd, char **stock, char **line) +{ + char *buffer; + char *temp; + int bytes_read; + + buffer = NULL; + bytes_read = ft_read(fd, &buffer, BUFFER_SIZE); + while (bytes_read > 0) + { + if (!*stock) + *stock = ft_strdup(buffer); + else + { + temp = *stock; + *stock = ft_strjoin(temp, buffer); + free(temp); + } + if (check_and_extract(line, stock)) + break ; + bytes_read = ft_read(fd, &buffer, BUFFER_SIZE); + } + free(buffer); + if (!*stock) + return (-1); + return (bytes_read); +} + +char *get_next_line(int fd) +{ + static char *stock; + char *line; + int status; + + if (fd < 0 || BUFFER_SIZE <= 0) + return (NULL); + if (stock && check_and_extract(&line, &stock)) + return (line); + status = read_file(fd, &stock, &line); + if (status > 0) + return (line); + else if (status < 0) + { + clean((void **)&stock); + return (NULL); + } + if (stock && *stock) + { + line = ft_strdup(stock); + clean((void **)&stock); + if (line) + return (line); + } + clean((void **)&stock); + return (NULL); +} diff --git a/src/get_next_line.h b/src/get_next_line.h new file mode 100644 index 0000000..7983def --- /dev/null +++ b/src/get_next_line.h @@ -0,0 +1,34 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_next_line.h :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/07/15 20:10:22 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/07/15 20:10:27 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_H +# define GET_NEXT_LINE_H + +# include +# include +# include +# include + +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 1 +# endif + +size_t ft_strlen(const char *s); +void *ft_memcpy(void *dest, const void *src, size_t n); +char *ft_strjoin(char const *s1, char const *s2); +char *ft_strdup(const char *s); +int ft_read(int fd, char **buffer, size_t size); +int check_and_extract(char **line, char **stock); +int read_file(int fd, char **stock, char **line); +char *get_next_line(int fd); + +#endif diff --git a/src/get_next_line_bonus.c b/src/get_next_line_bonus.c new file mode 100644 index 0000000..38ca3f9 --- /dev/null +++ b/src/get_next_line_bonus.c @@ -0,0 +1,122 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_next_line.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/07/15 16:59:55 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/07/15 17:00:24 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line_bonus.h" + +void clean(void **ptr) +{ + if (*ptr) + { + free(*ptr); + *ptr = NULL; + } +} + +int check_and_extract(char **line, char **stock) +{ + char *temp1; + char *temp2; + + if (!stock || !*stock) + return (0); + temp1 = *stock; + while (temp1 && *temp1 != '\n') + if (!*temp1++) + return (0); + if (temp1) + temp1++; + temp2 = ft_strdup(temp1); + *temp1 = '\0'; + *line = ft_strdup(*stock); + free(*stock); + *stock = temp2; + if (!*line || !*stock) + { + clean((void **)line); + clean((void **)stock); + return (-1); + } + return (1); +} + +int ft_read(int fd, char **buffer, size_t size) +{ + int bytes_read; + + if (!*buffer) + { + *buffer = malloc(sizeof(char) * (BUFFER_SIZE + 1)); + if (!*buffer) + return (-1); + } + bytes_read = read(fd, *buffer, size); + if (bytes_read >= 0) + (*buffer)[bytes_read] = '\0'; + return (bytes_read); +} + +int read_file(int fd, char **stock, char **line) +{ + char *buffer; + char *temp; + int bytes_read; + + buffer = NULL; + bytes_read = ft_read(fd, &buffer, BUFFER_SIZE); + while (bytes_read > 0) + { + if (!*stock) + *stock = ft_strdup(buffer); + else + { + temp = *stock; + *stock = ft_strjoin(temp, buffer); + free(temp); + } + if (check_and_extract(line, stock)) + break ; + bytes_read = ft_read(fd, &buffer, BUFFER_SIZE); + } + free(buffer); + if (!*stock) + return (-1); + return (bytes_read); +} + +char *get_next_line(int fd) +{ + static char *stock[OPEN_MAX]; + char *line; + int status; + + if (fd < 0 || fd >= OPEN_MAX || BUFFER_SIZE <= 0) + return (NULL); + if (stock[fd] && check_and_extract(&line, &stock[fd])) + return (line); + status = read_file(fd, &stock[fd], &line); + if (status > 0) + return (line); + else if (status < 0) + { + clean((void **)&stock[fd]); + return (NULL); + } + if (stock[fd] && *stock[fd]) + { + line = ft_strdup(stock[fd]); + clean((void **)&stock[fd]); + if (line) + return (line); + } + clean((void **)&stock[fd]); + return (NULL); +} diff --git a/src/get_next_line_bonus.h b/src/get_next_line_bonus.h new file mode 100644 index 0000000..2809254 --- /dev/null +++ b/src/get_next_line_bonus.h @@ -0,0 +1,38 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_next_line_bonus.h :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/07/16 12:03:06 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/07/16 12:03:08 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#ifndef GET_NEXT_LINE_BONUS_H +# define GET_NEXT_LINE_BONUS_H + +# include +# include +# include +# include + +# ifndef OPEN_MAX +# define OPEN_MAX 1024 +# endif + +# ifndef BUFFER_SIZE +# define BUFFER_SIZE 1 +# endif + +size_t ft_strlen(const char *s); +void *ft_memcpy(void *dest, const void *src, size_t n); +char *ft_strjoin(char const *s1, char const *s2); +char *ft_strdup(const char *s); +int ft_read(int fd, char **buffer, size_t size); +int check_and_extract(char **line, char **stock); +int read_file(int fd, char **stock, char **line); +char *get_next_line(int fd); + +#endif diff --git a/src/get_next_line_utils.c b/src/get_next_line_utils.c new file mode 100644 index 0000000..1322c2b --- /dev/null +++ b/src/get_next_line_utils.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_next_line_utils.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/07/15 17:00:39 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/07/15 17:00:41 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line.h" + +size_t ft_strlen(const char *s) +{ + size_t length; + + if (!s) + return (0); + length = 0; + while (*s++) + length++; + return (length); +} + +void *ft_memcpy(void *dest, const void *src, size_t n) +{ + if (dest == NULL && src == NULL) + return (NULL); + while (0 < n--) + ((unsigned char *)dest)[n] = ((unsigned char *)src)[n]; + return (dest); +} + +char *ft_strjoin(char const *s1, char const *s2) +{ + char *str; + size_t len_s1; + size_t len_s2; + + if (!s1 || !s2) + return (NULL); + len_s1 = ft_strlen(s1); + len_s2 = ft_strlen(s2); + str = (char *)malloc(len_s1 + len_s2 + 1); + if (!str) + return (NULL); + ft_memcpy(str, s1, len_s1); + ft_memcpy(str + len_s1, s2, len_s2); + str[len_s1 + len_s2] = '\0'; + return (str); +} + +char *ft_strdup(const char *s) +{ + size_t size; + char *d; + + if (!s) + return (NULL); + size = ft_strlen(s) + 1; + d = (char *) malloc(size * sizeof(char)); + if (d) + { + ft_memcpy(d, s, size - 1); + d[size - 1] = '\0'; + } + return (d); +} diff --git a/src/get_next_line_utils_bonus.c b/src/get_next_line_utils_bonus.c new file mode 100644 index 0000000..48ddd3b --- /dev/null +++ b/src/get_next_line_utils_bonus.c @@ -0,0 +1,70 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* get_next_line_utils_bonus.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/07/16 12:06:48 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/07/16 12:06:51 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include "get_next_line_bonus.h" + +size_t ft_strlen(const char *s) +{ + size_t length; + + if (!s) + return (0); + length = 0; + while (*s++) + length++; + return (length); +} + +void *ft_memcpy(void *dest, const void *src, size_t n) +{ + if (dest == NULL && src == NULL) + return (NULL); + while (0 < n--) + ((unsigned char *)dest)[n] = ((unsigned char *)src)[n]; + return (dest); +} + +char *ft_strjoin(char const *s1, char const *s2) +{ + char *str; + size_t len_s1; + size_t len_s2; + + if (!s1 || !s2) + return (NULL); + len_s1 = ft_strlen(s1); + len_s2 = ft_strlen(s2); + str = (char *)malloc(len_s1 + len_s2 + 1); + if (!str) + return (NULL); + ft_memcpy(str, s1, len_s1); + ft_memcpy(str + len_s1, s2, len_s2); + str[len_s1 + len_s2] = '\0'; + return (str); +} + +char *ft_strdup(const char *s) +{ + size_t size; + char *d; + + if (!s) + return (NULL); + size = ft_strlen(s) + 1; + d = (char *) malloc(size * sizeof(char)); + if (d) + { + ft_memcpy(d, s, size - 1); + d[size - 1] = '\0'; + } + return (d); +} diff --git a/src/test.c b/src/test.c new file mode 100644 index 0000000..45746bf --- /dev/null +++ b/src/test.c @@ -0,0 +1,68 @@ +/* ************************************************************************** */ +/* */ +/* ::: o_ :::::: ::: */ +/* test.c :+: / :+::+: :+: */ +/* +:+ > +:++:+ +:+ */ +/* By: whaffman +#+ +:+ +#++#++:++#++ */ +/* +#+ +#+#+ +#++#+ +#+ \o/ */ +/* Created: 2024/07/16 12:03:14 by whaffman #+#+# #+#+# #+# #+# | */ +/* Updated: 2024/07/16 12:06:02 by whaffman ### ### ### ### / \ */ +/* */ +/* ************************************************************************** */ + +#include +#include "get_next_line.h" + +int main(int argc, char **argv) +{ + int fd; + char *line; + + if (argc > 1) + fd = open(argv[1], O_RDONLY); + else + fd = STDIN_FILENO; + if (fd < 0) + { + return (1); + } + while (1) + { + line = get_next_line(fd); + if (line == NULL) + break ; + printf("%s", line); + free(line); + } + close(fd); + return (0); +} +/* +#include +int main(int argc, char **argv) +{ + int fd; + char *line; + + if (argc > 1) + fd = open(argv[1], O_RDONLY); + else + fd = STDIN_FILENO; + if (fd < 0) + { + return (1); + } + line = get_next_line(fd); + printf("1: first char: %s\n", *line++ == '\n' ? "true" : "false"); + printf("1:second char is \\0: %s\n", *line == '\0' ? "true" : "false"); + + line = get_next_line(fd); + printf("line is null: %s\n", line == NULL ? "true" : "false"); + printf("2: first char is \\0: %s\n", *line == '\0' ? "true" : "false"); + + + close(fd); + return (0); +} + +*/ diff --git a/src/test.txt b/src/test.txt new file mode 100644 index 0000000..e2413cd --- /dev/null +++ b/src/test.txt @@ -0,0 +1,4 @@ +THIS IS A TEST FILE +STILL TESTING.. + +STILL TESTING diff --git a/src2/test.c b/src2/test.c new file mode 100644 index 0000000..194010f --- /dev/null +++ b/src2/test.c @@ -0,0 +1,54 @@ + +#include +#include +#include +int main(int argc, char **argv) +{ + int fd; + char *line; + + if (argc > 1) + fd = open(argv[1], O_RDONLY); + else + fd = STDIN_FILENO; + if (fd < 0) + { + return (1); + } + while ((line = get_next_line(fd)) != NULL) + { + printf("%s", line); + free(line); + } + close(fd); + return (0); +} +/* +#include +int main(int argc, char **argv) +{ + int fd; + char *line; + + if (argc > 1) + fd = open(argv[1], O_RDONLY); + else + fd = STDIN_FILENO; + if (fd < 0) + { + return (1); + } + line = get_next_line(fd); + printf("1: first char: %s\n", *line++ == '\n' ? "true" : "false"); + printf("1:second char is \\0: %s\n", *line == '\0' ? "true" : "false"); + + line = get_next_line(fd); + printf("line is null: %s\n", line == NULL ? "true" : "false"); + printf("2: first char is \\0: %s\n", *line == '\0' ? "true" : "false"); + + + close(fd); + return (0); +} + +*/ \ No newline at end of file