mIRC Home    About    Download    Register    News    Help

Print Thread
#220688 21/04/10 07:38 PM
Joined: Apr 2003
Posts: 61
G
gaui Offline OP
Babel fish
OP Offline
Babel fish
G
Joined: Apr 2003
Posts: 61
Hello, I'm trying to read a socket with everything into just one %var

But it outputs line 1 \n line 2 \n line 3

I want it like this: line 1 | line 2 | line 3

I tried this:

Code:
sockread -n %data
echo -a $target $replace(%data,$crlf,|)


No success. frown Any ideas?


__________________________
Curiosity killed the cat.
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
You do not want to have your echo line in the sockread event. Or, at least, you don't want it until a check that shows you're done reading from the socket. Everything in the sockread event is done/checked for each line in the socketed file. So you are echoing after every line is read.

Code:
on *:sockread:socketname: {
  sockread %data
  set %output %output $chr(124) %data
}

on *:sockclose:socknetname: {
  if (%output) {
    echo -a %output
    unset %output
  }
  else { echo -a No data. }
}


* This is a very basic example and probably needs "fleshed out" a bit depending on the data in the socketed file.

** If you have a LOT of text, you may have to use a binary variable instead.

EDIT: I put in an error check if you have no data from the socket. It can be edited or removed as needed.

Last edited by Riamus2; 21/04/10 07:56 PM.

Invision Support
#Invision on irc.irchighway.net
Joined: Apr 2003
Posts: 61
G
gaui Offline OP
Babel fish
OP Offline
Babel fish
G
Joined: Apr 2003
Posts: 61
Originally Posted By: Riamus2
Use a binary variable to read multiple lines into one variable.

Can you show me how you would do this?


__________________________
Curiosity killed the cat.
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
Sorry, read my edit.


Invision Support
#Invision on irc.irchighway.net
Joined: Apr 2003
Posts: 61
G
gaui Offline OP
Babel fish
OP Offline
Babel fish
G
Joined: Apr 2003
Posts: 61
Originally Posted By: Riamus2
You do not want to have your echo line in the sockread event. Or, at least, you don't want it until a check that shows you're done reading from the socket. Everything in the sockread event is done/checked for each line in the socketed file. So you are echoing after every line is read.

Code:
on *:sockread:socketname: {
  sockread %data
  set %output %output $chr(124) %data
}

on *:sockclose:socknetname: {
  if (%output) {
    echo -a %output
    unset %output
  }
  else { echo -a No data. }
}


* This is a very basic example and probably needs "fleshed out" a bit depending on the data in the socketed file.

** If you have a LOT of text, you may have to use a binary variable instead.

EDIT: I put in an error check if you have no data from the socket. It can be edited or removed as needed.

Thank you very much, this works! smile

But if I've got this %var = Show Name@House | Show URL

How would I get only House out of this?

I tried this and it works, but I think it's too complicated:

Code:
$gettok($matchtok(%var,Show Name,1,124),2,64)


Is there any simpler method?

Last edited by gaui; 21/04/10 11:54 PM.

__________________________
Curiosity killed the cat.
Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Code:
on *:SOCKREAD:sockname:{
  if ($sockerr) { return }
  :loop
  if (!$sockbr) { return }
  sockread &bvardata
  set %sockdata %sockdata $+ $bvar(&bvardata,$bvar(&bvardata,0)).text
  goto loop
}
on *:sockclose:sockname:{
  if ($sockerr) { return }
  echo -a %data
}


Something for thought though: mIRC has a text buffer that allows only so many characters to be handled at one time. So if the page is to big you will get a "Set line to long" error


I am SReject
My Stuff
Joined: Apr 2003
Posts: 61
G
gaui Offline OP
Babel fish
OP Offline
Babel fish
G
Joined: Apr 2003
Posts: 61
Originally Posted By: FroggieDaFrog
Code:
on *:SOCKREAD:sockname:{
  if ($sockerr) { return }
  :loop
  if (!$sockbr) { return }
  sockread &bvardata
  set %sockdata %sockdata $+ $bvar(&bvardata,$bvar(&bvardata,0)).text
  goto loop
}
on *:sockclose:sockname:{
  if ($sockerr) { return }
  echo -a %data
}


Something for thought though: mIRC has a text buffer that allows only so many characters to be handled at one time. So if the page is to big you will get a "Set line to long" error

Doesn't matter, the page is never too big.


__________________________
Curiosity killed the cat.
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
If you are using a binary variable for the sockread, you shouldn't be using a regular variable for the data. If you stick to just binary variables, you should never get the line too long error. That's the reason for using the binary variable in the first place. Also, with binary variables, I don't think you'll need a second variable if you set it correctly. I'd have to look into it as I really don't use binary variables for anything, so don't have a lot of experience with them. And since the OP doesn't need them, I'll just leave it the way it was.


Invision Support
#Invision on irc.irchighway.net
Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Once a script/event is done processing the bvar unsets. U can either set that data to a variable, save it in a hashtable(which has a switch for adding bvars) or use /fopen /fwrite and /close to just write it all to a file the use /bread to retrieve all the data when you're done getting the info


I am SReject
My Stuff
Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Code:
var %a = $regex(get,Show Name@somename,/Show Name@([^\s]+)/i)
var %var = $regml(get,1)

this gets everything upto the next space after "Show Name@"


I am SReject
My Stuff
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
Originally Posted By: FroggieDaFrog
Once a script/event is done processing the bvar unsets. U can either set that data to a variable, save it in a hashtable(which has a switch for adding bvars) or use /fopen /fwrite and /close to just write it all to a file the use /bread to retrieve all the data when you're done getting the info


Or, the better method... You'd put the final echo into the sockread event in an IF that checks for the end of the file.


Invision Support
#Invision on irc.irchighway.net
Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
Code:
on *:SOCKREAD:sockname:{
  ;loop back position
  :loop

  ;Check for sockerr
  if ($sockerr) { 

    ;if sockerror occured, check if hashtable is opened
    if ($hget($sockname)) {

      ;if hashtable is opened, close it
      hfree $sockname
    }

    ;if sockerr, stop processing
    return
  }

  ;read data from socket to &tmp1
  sockread &tmp1

  ;if no data was read, stop processing
  if (!$sockbr) { return }

  ;retrive data, if present, from the hashtable and set it to &tmp2
  var %a = $hget($sockname,1,&tmp2)

  ;append the data that was read from the socket to the end of the stored data
  bcopy -c &tmp2 $bvar(&tmp2,0) &tmp1 1 -1

  ;store &tmp2(old data + fresh data from socket)
  hadd -mb $sockname 1 &tmp2

  ;loop back
  goto loop
}
on *:SOCKWRITE:sockname:{
  ;check for socket errors
  if ($sockerr) {

    ;if a sockerror occured, check to see if the hashtable is opened
    if ($hget($sockname)) { 

      ;free the hashtable if it's opened
      hfree $sockname
    }

    ;if a sockerr occured, stop processing
  } 
}
on *:sockclose:sockname:{
  ;check for socket errors
  if ($sockerr) {

    ;if a sockerror occured, check to see if the hashtable is opened
    if ($hget($sockname)) { 

      ;free the hashtable if it's opened
      hfree $sockname
    }

    ;if a sockerr occured, stop processing
  } 
  
  ;check to see if any data was stored.
  if ($hashtable($sockname)) {
  
    ;retrive data from the hashtable, and clear the hashtable
    var %a = $hget($sockname,1,&tmp)
    hfree $sockname
 
    ;replace all carriage-return+linefeeds with char(124) "|" (this also stops you from having multiple pipes side be side. IE: || )
    var %data = $regsubex($bvar(&tmp,1,$bvar(&tmp,0)).text,/(?:\s+?\r\n\s+?)+/g,$chr(124))

    ;echo data out
    echo -a %data
  }
}


I didn't test the regex so it might be off, but other than that, it's good.

Last edited by FroggieDaFrog; 23/04/10 01:55 AM.

I am SReject
My Stuff
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
You are once again mixing binary and non-binary variables. A main reason for using binary variables is to avoid line too long issues. If you stick a binary into a non-binary, you risk losing data and/or getting errors.

Like I said, stick the echo into the sockread event and avoid unnecessary things like hash tables. They aren't needed for something like this.

Code:
if (!$sockbr) { echo -a $regsubex($bvar(&tmp,1,$bvar(&tmp,0)).text,/(?:\s+?\r\n\s+?)+/g,$chr(124)) }


That's assuming your regex is correct. I don't know regex, so have no idea. But in either case, this avoids 1) hash tables, and 2) mixing variables. And as long as you're not re-triggering the sockread (i.e. you're using a loop), the binary variable shouldn't get reset.

All of that said, the OP does not appear to need binary variables and so there's no need for any of this.


Invision Support
#Invision on irc.irchighway.net
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
Using $bvar().text converts the binary data to text, defeating the purpose of storing binary data. Converting it to text and using it in an mIRC command subjects it to the same line length issues that %vars would have, so you're right in saying there's no need for binary data here.

Just sockread %var and perform your operations on %var. *IF* the line is too long, deal with it then. There is no easy way to process large (>4k) blocks of data in mIRC, so stick to the simple case.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
Joined: Apr 2003
Posts: 61
G
gaui Offline OP
Babel fish
OP Offline
Babel fish
G
Joined: Apr 2003
Posts: 61
Okay, so how do I read a webpage that has:

line1
line2
line3

into a %var like this:

line1 | line2 | line3 ?

I have something like this:

Code:
sockread %data
set %output %data $chr(124) $gettok(%data,1,13)


%output is then: line3 | line3

Last edited by gaui; 27/09/10 12:28 AM.

__________________________
Curiosity killed the cat.
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
sockread %data
set %output %output $chr(124) $gettok(%data,1,13)

will result in: "| line1 | line2 | line3" - to get rid of the first "| ", use e.g. $mid(%output,3-)


Link Copied to Clipboard