133 lines
2.4 KiB
Markdown
133 lines
2.4 KiB
Markdown
# ft_irc parsing module
|
|
|
|
Partie parsing C++98 pour `ft_irc`.
|
|
|
|
## Ce que ça fait
|
|
|
|
- accumule les données TCP reçues dans un buffer par client ;
|
|
- extrait les lignes complètes terminées par `\r\n` ou `\n` ;
|
|
- parse une ligne IRC en :
|
|
- prefix optionnel ;
|
|
- command ;
|
|
- params ;
|
|
- trailing param après `:`, qui peut contenir des espaces ;
|
|
- normalise les commandes en uppercase ;
|
|
- fournit une validation minimale du nombre de paramètres.
|
|
|
|
## Ce que ça ne fait volontairement pas
|
|
|
|
Le parser ne doit pas gérer la logique métier :
|
|
|
|
- vérifier le password ;
|
|
- vérifier si le nickname existe déjà ;
|
|
- créer les channels ;
|
|
- vérifier les permissions operator ;
|
|
- appliquer les modes ;
|
|
- envoyer les numeric replies.
|
|
|
|
Tout ça appartient aux handlers de commandes.
|
|
|
|
## Utilisation dans ton Client
|
|
|
|
Chaque client doit avoir son propre `ParseBuffer`.
|
|
|
|
Exemple :
|
|
|
|
```cpp
|
|
// Dans ta classe Client
|
|
ParseBuffer _parseBuffer;
|
|
```
|
|
|
|
Quand `poll()` indique que le fd client est lisible :
|
|
|
|
```cpp
|
|
char buf[4096];
|
|
ssize_t n = recv(clientFd, buf, sizeof(buf), 0);
|
|
|
|
if (n <= 0)
|
|
{
|
|
// déconnexion ou erreur
|
|
}
|
|
else
|
|
{
|
|
client.getParseBuffer().append(buf, n);
|
|
|
|
std::vector<IrcMessage> messages = client.getParseBuffer().extractMessages();
|
|
|
|
for (size_t i = 0; i < messages.size(); ++i)
|
|
{
|
|
IrcMessage &msg = messages[i];
|
|
|
|
if (!msg.isValid())
|
|
{
|
|
// selon l'erreur:
|
|
// - ignorer
|
|
// - répondre ERR_UNKNOWNCOMMAND
|
|
// - fermer si line too long
|
|
continue;
|
|
}
|
|
|
|
// dispatcher.handle(client, msg);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Compilation test
|
|
|
|
```bash
|
|
c++ -Wall -Wextra -Werror -std=c++98 \
|
|
-Iincludes \
|
|
srcs/IrcMessage.cpp \
|
|
srcs/IrcParser.cpp \
|
|
srcs/ParseBuffer.cpp \
|
|
srcs/CommandValidator.cpp \
|
|
test/main.cpp \
|
|
-o parser_test
|
|
|
|
./parser_test
|
|
```
|
|
|
|
## Format IRC géré
|
|
|
|
```txt
|
|
COMMAND param1 param2 :trailing avec espaces
|
|
```
|
|
|
|
Exemples :
|
|
|
|
```txt
|
|
PASS secret
|
|
NICK jeremy
|
|
USER jeremy 0 * :Jeremy Real Name
|
|
JOIN #42
|
|
PRIVMSG #42 :salut les gars
|
|
MODE #42 +it
|
|
MODE #42 +k password
|
|
KICK #42 bob :raison du kick
|
|
```
|
|
|
|
## Intégration recommandée
|
|
|
|
Architecture propre :
|
|
|
|
```txt
|
|
Client
|
|
- fd
|
|
- nick
|
|
- username
|
|
- ParseBuffer
|
|
|
|
Server
|
|
- poll loop
|
|
- accept
|
|
- recv
|
|
- donne les IrcMessage au dispatcher
|
|
|
|
CommandDispatcher
|
|
- map command -> handler
|
|
- PASS/NICK/USER/JOIN/PRIVMSG/MODE/etc.
|
|
|
|
Parser
|
|
- aucune logique métier
|
|
```
|