Page 1 sur 1

Les Chaînes, incompréhension

Publié : dim. 26/déc./2004 21:07
par LeCyb
Tout d'abord bonjour :)

Je dois manipuler des chaînes de caractères de l'ordre de 250-300k (parfois 500k), je voudrais faire des Left, Trim, FindString et Mid avec ces chaînes.

Le problème c'est que je regarde dans l'aide (variables et types) et je vois que les chaînes ont une longueur illimitée, longueur de chaîne + 1.
Par contre j'ai vu (je sais plus dans quel post) qu'il y avait des soucis avec les chaînes de plus de 64k.
Donc là je voudrais connaître la réalité de la chose, et si possible la limite exacte si il y en a.

Dans le même combat, je dois faire ça en faisant des multi-threads et des connections réseau (j'utilise la lib network de purebasic).
Donc je fais joujou avec un buffer local et des PeekS.
J'ai pensé à faire (si limite il y a) une liste de chaînes de 64k, mais les listes chaînées m'ont l'air globales et je ne connais pas à l'avance le nombre de threads qui seront lancés (on pourrait en avoir 10 comme 150).

Donc voilà je rame un peu.

Je me permet aussi de mettre ma contribution à l'édifice en proposant une petite procédure pour gérer les déconnections (event 4)

Code : Tout sélectionner

Procedure.b NetworkClientEvent2(ConnectionID)
;*********************************************************************
;* Idem que NetworkClientEvent mais avec l'événement Déconnecté (4). *
;*********************************************************************
  If WSAAsyncSelect_(ConnectionID,WindowID(),$9000,#FD_CLOSE) = #SOCKET_ERROR
    ProcedureReturn 4
  Else
    ProcedureReturn NetworkClientEvent(ConnectionID)
  EndIf
EndProcedure
Merci d'avance pour les réponses et bravo pour purebasic :D

Publié : dim. 26/déc./2004 22:08
par Heis Spiter
Pas mal ta procédure :). Je sens que je vais la mettre dans Bird Chat ;). Mais d'abord, tests :P

Publié : dim. 26/déc./2004 22:49
par Chris
Les chaines ont, effectivement, une longueur maxi de 64 Ko. (63999 Ko)

Par contre, rien ne t'empêche de charger une chaine de 500 Ko en mémoire par AllocateMemory(), et de la décomposer ensuite en chaines de 64 Ko par des PeekS() pour le traitement, et de la réassembler ensuite.

J'avais fait une procédure sur ce principe pour afficher plus rapidement de gros fichiers dans un EditorGadget(), si ça peut te servir...

Code : Tout sélectionner

Procedure LireFichier(Gagdet.l, Fichier.s) 
  Size = FileSize(Fichier) 
  Longueur = Size : Decalage = 0 
  L_Max = 63999 
  
  If Size > 0 
    If ReadFile(0,Fichier) 
      *Buffer = AllocateMemory(Size) 
      If *Buffer 
        ReadData(*Buffer, Size) 
      EndIf 
      CloseFile(0) 
    EndIf 
    
    If Longueur > L_Max 
      Repeat 
        Chaine.s = PeekS(*Buffer + Decalage, L_Max) 
        AddGadgetItem(gadget,-1,Chaine) 
        Longueur = Longueur - L_Max : Decalage = Decalage + L_Max 
      Until Longueur < L_Max 
      Chaine = PeekS(*Buffer + Decalage,Longueur) 
      AddGadgetItem(gadget,-1,Chaine) 
    Else 
      Chaine.s = PeekS(*Buffer,Longueur) 
      AddGadgetItem(gadget,-1,Chaine) 
    EndIf 
    FreeMemory(*Buffer) 
  EndIf 
EndProcedure

Publié : dim. 26/déc./2004 22:59
par filperj
Par contre, les opérations sur chaînes utilisent un buffer commun...
Donc il ne faut surtout pas que plusieurs threads en fassent en même temps. :?

Publié : dim. 26/déc./2004 23:13
par nico
Salut LeCyb et bienvenue sur le Forum.

Il y a une petite procédure pour utiliser des chaines de plus de 64Ko,
elle te permettra d'utiliser les commandes habituelles sur les strings,
voir ce lien: http://purebasic.hmt-forum.com/viewtopic.php?t=1963

:)

Publié : dim. 26/déc./2004 23:16
par LeCyb
Pas con du tout :D

Maintenant si je fais genre:

Code : Tout sélectionner

Chaine.s = PeekS(*Buffer, L_Max)
*Buffer + L_Max
Chaine2.s = PeekS(*Buffer, L_Max)
Je suppose quen faisant un FreeMemory(*Buffer) il n'est pas libéré entièrement ? Je suppose aussi que c'est pas très propre de faire *Buffer + L_Max ?

Est-ce que SizeOf() fonctionne pour les pointeurs ?

Pour "grouper" ces chaînes je pensais à une liste mais il me semble qu'elles sont globales et les tableaux sont statiques, que faire à part me tapper des PeekS à chaque fois que je manipule le buffer ?

Oulà, ça se complique. Donc si je comprends bien, si je fais un Len(String.s) dans 100 threads j'ai des chances que tout ce petit monde se mélange les pinceaux. Donc faut faire joujou avec les Mutex dès qu'on chipotte à une chaîne dans un thread ?

Y'a d'autres soucis du genre ?

Merci beaucoup Chris et filperj pour vos réponses :wink:

Heis, n'hésite pas, y'a pas de copyright :D

Edit:
Merci nico, on a posté quasi en même temps :)

Donc je fais SetStringManipulationBufferSize(taille_de_ma_superstring) et je pourrai utiliser les Trim et tout sans me soucier de rien tant que ça ne dépasse pas la taille que je définit ?
Et pour les Threads ?

Publié : dim. 26/déc./2004 23:30
par nico
Oui, c'est ça; par contre je ne savais pas pour les problèmes de manipulation de chaines avec les commandes de Pure avec plusieurs threads; tu peux peut être utiliser les mutex:

Le lien: http://purebasic.hmt-forum.com/viewtopi ... ght=thread

Publié : dim. 26/déc./2004 23:41
par LeCyb
Bon ben Mutex powa jusqu'à nouvel ordre :D

Encore merci merci merci merci.