-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathget_next_line.c
More file actions
175 lines (139 loc) · 7.39 KB
/
get_next_line.c
File metadata and controls
175 lines (139 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* get_next_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: isbesli <isbesli@student.42kocaeli.com. +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/08/17 17:48:07 by isbesli #+# #+# */
/* Updated: 2023/08/17 17:48:08 by isbesli ### ########.fr */
/* */
/* ************************************************************************** */
#include "get_next_line.h"
static char *ft_copy_to_stash(char *stash, char *buf)
{
char *res; // Geçici bir bellek bloğu
res = 0; // Geçici bellek bloğunu başlangıçta NULL olarak atayın
if (!stash && buf) // Eğer stash boşsa ve buf verisi varsa
{
res = ft_strdup(buf); // buf verisini kopyalayarak res'e atayın
if (!res) // Bellek ayırma hatası durumunda NULL döndür
return (NULL);
return (res); // Kopyalanan veriyi döndür
}
res = ft_strjoin(stash, buf); // stash ve buf'u birleştirerek res'e atayın
ft_free_stash(&stash, 0); // Eski stash'i temizleyin (bellek sızıntısı önlemek için)
return (res); // Birleştirilmiş veriyi döndür
}
static int ft_have_nl(char *s)
{
size_t i;
// İlk olarak, gelen karakter dizisinin (string) boş olup olmadığını kontrol ediyoruz.
// Eğer boşsa, '\0' karakteri yani null terminator olmadığı için '\n' karakterini içermiyor demektir.
if (!s)
return (0);
// Bir sayaç (i) tanımlanıyor ve -1 ile başlatılıyor.
// Döngüde başlangıç değeri -1 olarak seçilmiş, böylece döngü başladığında i++ ile 0'ıncı indeksten başlayacaktır.
i = -1;
// Karakter dizisinin sonuna kadar dönecek bir döngü başlıyor.
// Bu döngü, karakter dizisinin her bir karakterini sırayla kontrol eder.
while (s[++i] != '\0') {
// Eğer mevcut karakter '\n' (newline) karakterine eşitse,
// bu, karakter dizisi içerisinde yeni satır karakteri bulunduğu anlamına gelir.
// Bu durumda fonksiyon 1 değerini döndürerek "evet, yeni satır karakteri bulundu" demektedir.
if (s[i] == '\n')
return (1);
}
// Eğer döngü sonuna kadar gelindi ve '\n' karakteri bulunmadıysa,
// fonksiyon 0 değerini döndürerek "hayır, yeni satır karakteri bulunmuyor" demektedir.
return (0);
}
static char *ft_extract_line(char *stash)
{
char *line; // Yeni satırı saklamak için bellek alanı
size_t i; // Stash içinde dolaşmak için sayaç
size_t j; // Line dizisine veriyi kopyalamak için sayaç
i = 0; // Stash içinde gezinmeye başlamak için i'yi sıfırla
if (!stash) // Stash boşsa, yani veri yoksa, hemen NULL döndür
return (0);
// Stash içindeki veriyi '\n' karakterine kadar tara
while (stash[i] != '\n')
i++;
// '\n' karakteri dahil olarak satırın uzunluğunu (i + 1) alıp bellek ayır
line = malloc(sizeof(char) * (i + 2));
if (!line) // Bellek ayırma hatası durumunda NULL döndür
return (0);
j = 0; // Yeni line dizisine veriyi kopyalamak için j'yi sıfırla
while (j < i + 1) // '\n' karakteri dahil olarak veriyi kopyala
{
line[j] = stash[j];
j++;
}
line[j] = '\0'; // Sonuna NULL karakteri ekle (C-string bitirme işareti)
return (line); // Oluşturulan satırı döndür
}
static char *ft_recreate_stash(char *stash)
{
size_t i; // Diziyi tararken kullanılacak sayaç
char *res; // Yeni oluşturulacak bellek bloğu
i = 0; // Sayaç başlangıç değeri ile sıfırlanır
if (!stash) // Eğer stash NULL ise, hemen NULL döndür
return (NULL);
while (stash[i] != '\n') // '\n' karakterine kadar dizi taranır
i++;
if (stash[i + 1] == '\0') // Eğer '\n' karakterinden sonraki karakter '\0' ise
return (ft_free_stash(&stash, 0)); // stash'i temizle ve NULL döndür
// stash içinden '\n' sonrasını alarak yeni bellek bloğu oluştur
res = ft_substr(stash, i + 1, ft_strlen(stash));
if (!res) // Bellek ayırma hatası durumunda
{
ft_free_stash(&stash, 0); // stash'i temizle
return (NULL); // NULL döndür
}
ft_free_stash(&stash, 0); // stash'i temizle
return (res); // Yeni bellek bloğunu döndür
}
char *get_next_line(int fd)
{
// 1. Bellekte BUFFER_SIZE + 1 uzunluğunda bir karakter dizisi (buf) oluşturulur.
char buf[BUFFER_SIZE + 1];
// 2. Veri okuma işlemi sırasında okunan bayt sayısını tutacak değişken (bytes_read) tanımlanır.
long bytes_read;
// 3. Okunan veriyi geçici olarak saklamak için kullanılan bellek alanını temsil eden pointer (stash) tanımlanır.
// Bu değişken static olarak tanımlandığı için, çağrılar arasında değeri korunur.
static char *stash = NULL;
// 4. Okunan bir satırın son halini tutacak pointer (line) tanımlanır ve başlangıçta NULL olarak atanır.
char *line;
// 5. Okunan veri miktarını saklayan değişken başlangıçta BUFFER_SIZE olarak atanır.
bytes_read = BUFFER_SIZE;
// 6. Hata durumlarını kontrol etmek için dosya tanımlayıcısı ve BUFFER_SIZE değerlerinin geçerliliği kontrol edilir.
if (fd < 0 || BUFFER_SIZE <= 0)
return (ft_free_stash(&stash, 0));
// 7. Veri okuma işlemi başlar ve veri okunmaya devam edilirken döngüye girilir.
while (bytes_read > 0)
{
// 8. Dosyadan veri okunur ve okunan bayt sayısı bytes_read değişkenine atanır.
bytes_read = read(fd, buf, BUFFER_SIZE);
// 9. Veri okuma sırasında hata oluştuysa veya okunan veri yoksa ve daha önce saklanmış veri de yoksa
// veya okuma hatası (bytes_read == -1) oluştuysa, bellek alanını temizler ve NULL döner.
if ((bytes_read <= 0 && !stash) || bytes_read == -1)
return (ft_free_stash(&stash, 0));
// 10. Okunan verinin sonuna NULL karakteri eklenerek C-string formatına dönüştürülür.
buf[bytes_read] = '\0';
// 11. Okunan veriyi stash bellek alanına kopyalar.
stash = ft_copy_to_stash(stash, buf);
// 12. Stash bellek alanında yeni satır karakteri var mı diye kontrol edilir.
if (ft_have_nl(stash))
{
// 13. Eğer yeni satır karakteri bulunuyorsa, stash'teki veriden yeni bir satır çıkarılır.
line = ft_extract_line(stash);
// 14. Satır çıkarılma işlemi başarılı olmazsa bellek temizlenir ve NULL döner.
if (!line)
return (ft_free_stash(&stash, 0));
// 15. Stash bellek alanı yeniden oluşturulur ve line (çıkarılan satır) döndürülür.
return (stash = ft_recreate_stash(stash), line);
}
}
// 16. Döngü bittiğinde ve okuma tamamlandığında, bellek temizlenir ve işlem tamamlandığına dair 1 döndürülür.
return (ft_free_stash(&stash, 1));
}