mIRC Homepage
Posted By: gaui Socket reading everything - 21/04/10 07:38 PM
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?
Posted By: Riamus2 Re: Socket reading everything - 21/04/10 07:44 PM
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.
Posted By: gaui Re: Socket reading everything - 21/04/10 07:45 PM
Originally Posted By: Riamus2
Use a binary variable to read multiple lines into one variable.

Can you show me how you would do this?
Posted By: Riamus2 Re: Socket reading everything - 21/04/10 07:49 PM
Sorry, read my edit.
Posted By: gaui Re: Socket reading everything - 21/04/10 11:50 PM
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?
Posted By: FroggieDaFrog Re: Socket reading everything - 22/04/10 03:08 AM
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
Posted By: gaui Re: Socket reading everything - 22/04/10 04:39 AM
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.
Posted By: Riamus2 Re: Socket reading everything - 22/04/10 10:12 AM
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.
Posted By: FroggieDaFrog Re: Socket reading everything - 22/04/10 05:20 PM
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
Posted By: FroggieDaFrog Re: Socket reading everything - 22/04/10 05:25 PM
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@"
Posted By: Riamus2 Re: Socket reading everything - 22/04/10 07:02 PM
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.
Posted By: FroggieDaFrog Re: Socket reading everything - 23/04/10 01:52 AM
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.
Posted By: Riamus2 Re: Socket reading everything - 23/04/10 02:01 AM
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.
Posted By: argv0 Re: Socket reading everything - 30/04/10 11:34 PM
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.
Posted By: gaui Re: Socket reading everything - 27/09/10 12:26 AM
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
Posted By: Horstl Re: Socket reading everything - 27/09/10 12:41 AM
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-)
© mIRC Discussion Forums