'Getting access to a binary response byte-by-byte in classic asp/JScript

I asked this question a few days ago but it seems to have gone cold fairly quickly. What I want to do is pretty simple and I can't believe someone hasn't figured it out.

Solution needs to be JScript classic ASP. I am reading a file from a remote server and I want to process that (binary) file on my server and spit the results back to the client as XML.

Here's a simplified version of what I am trying to do. This code runs, or will if the URL is filled in for your site. This test file is readbin.asp. It reads a file called test.bin, and writes the result to a stream. I used a stream because that makes it easier to read the file and parse the contents. Basically I want to:

while not end of stream
    read byte from stream
    process byte

here is readbin.asp:

<%@ LANGUAGE = JScript %>
<%
var url = "http:// (... your URL to the file test.bin goes here...) " ; 
var xmlhttp = Server.CreateObject ("MSXML2.ServerXMLHTTP") ;
xmlhttp.open ("GET", url, false) ; 
xmlhttp.send () ; 

var BinaryInputStream = Server.CreateObject ("ADODB.Stream") ;
BinaryInputStream.Type = 1 ; // binary
BinaryInputStream.Open ;
BinaryInputStream.Write (xmlhttp.responseBody) ;
BinaryInputStream.Position = 0 ;

Response.Write ("BinaryInputStream.size = " + BinaryInputStream.size + "<br>") ;
Response.Write ("BinaryInputStream = " + BinaryInputStream + "<br>") ;

var ByteValue = BinaryInputStream.read (1) ;
Response.Write ("ByteValue = " + ByteValue + "<br>") ;
Response.Write ("typeof (ByteValue) = " + typeof (ByteValue) + "<br>") ;
%>

My problem is: how do I get ByteValue as a number 0..255? typeof (ByteValue) is "unknown".

Ord?? Byte()?? Asc?? Chr??



Solution 1:[1]

You may want to take a look at this piece of code: http://docs.hyperweb.no/source/asplib1.2/util/fileupload.asp

This code is for handling uploaded files. It is really quite similar: - On line 224 the binary request is being read into a stream object. - On line 232 the data is read back as ISO-8859-1 text, which is almost what you want - You can then read each byte of this string by using the getByte() function on line 48. This function uses the lookup table on line 33 to fix ceratin characters that get converted to unicode.

Solution 2:[2]

I am much more experienced with vbscript than jscript but I will give it a shot since not many takers on this question.

states there are six possible values that typeof returns: "number," "string," "boolean," "object," "function," and "undefined."
http://msdn.microsoft.com/en-us/library/259s7zc1(VS.85).aspx

The ADODB.Stream .Read object and method return a variant data type. I suspect typeof does not like the variant datatype.
http://www.w3schools.com/ado/ado_ref_stream.asp

The posting from this guy seems to explain it a bit further.
http://blogs.msdn.com/jaiprakash/archive/2007/01/09/jscript-supports-safearrays-of-variants-only.aspx

I would try casting the return stream before applying typeof to it.

Solution 3:[3]

Maybe not quite on the topic, but using VBScript I wrote this:

option explicit
dim fso, wshSHell, objShellApp, args, stdin,stdout

set fso         = CreateObject("Scripting.FileSystemObject")
Set wshShell    = CreateObject("WScript.Shell")
set objShellApp = CreateObject("Shell.Application")
Set args = Wscript.Arguments
set stdin = wscript.stdin
set stdout = wscript.stdout

dim filename, txtFile

filename = args(0)

Const adTypeBinary = 1

'Create Stream object
Dim BinaryStream, data
Set BinaryStream = CreateObject("ADODB.Stream")

'Specify stream type - we want To get binary data.
BinaryStream.Type = adTypeBinary

'Open the stream
BinaryStream.Open

'Load the file data from disk To stream object
BinaryStream.LoadFromFile filename

'Open the stream And get binary data from the object
data = BinaryStream.Read
BinaryStream.close

dim i, item, strLine, hexLine
hexLine = ""
strLine = ""

stdout.writeline "Decimal |Hex     |Data                                             | ASCII 33-254"
for i = 0 to lenb(data)-1
  item = ascb(midb(data,i+1,1))
  if ((i MOD 16) = 0) and (i<>0) then
    stdout.writeLine right("00000000" & i,8) & "|" & right("00000000" & hex(i),8) & "|" &  hexLine & " | " & strLine
    hexLine = ""
    strLine = ""
  end if
  hexLine = hexLine & right("0" & hex(item),2) & " "
  if (item <= 32) or (item > 254) then 
    strLine=strLine + "."
  else
    strLine = strLine & chr(item)
  end if
next

Key to this solution is to know that the variable 'data' contains an array of bytes. You can handle that by using the function lenb (length of byte array) and midb (to extract one or more bytes).

Run the script as follows:

cscript dumphex.vbs my_binary_file.bin > my_binary_file.hex.txt

This will output to standard out the hex code of all the binary file data. Each line of 16 hex codes is prefixed by a decimal + hex counter of the byte number. THe last column displays readable ascii between 33 and 254.

Also great to circumvent that annoying editor that interprets your UTF-8 codes, if you want to see just the exact codes in your ascii files.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Thomas Kjørnes
Solution 2 RandyMorris
Solution 3 Pianoman