Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > microsoft.public.scripting.vbscript > #12187 > unrolled thread

ADODB.Stream binary array to binary string failed unless x-user-defined is used

Started byJJ <jj4public@vfemail.net>
First post2019-09-16 08:23 +0700
Last post2019-09-22 02:07 +0700
Articles 20 on this page of 47 — 5 participants

Back to article view | Back to microsoft.public.scripting.vbscript


Contents

  ADODB.Stream binary array to binary string failed unless x-user-defined is used JJ <jj4public@vfemail.net> - 2019-09-16 08:23 +0700
    Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-15 23:03 -0400
      Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used GS <gs@v.invalid> - 2019-09-15 23:58 -0400
        Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-16 10:08 -0400
          Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used GS <gs@v.invalid> - 2019-09-16 12:32 -0400
            Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-16 13:13 -0400
              Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used GS <gs@v.invalid> - 2019-09-16 20:26 -0400
                Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-16 22:08 -0400
                  Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used GS <gs@v.invalid> - 2019-09-17 22:08 -0400
      Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used JJ <jj4public@vfemail.net> - 2019-09-16 18:27 +0700
        Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-16 09:55 -0400
          Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-16 10:32 -0400
          Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used JJ <jj4public@vfemail.net> - 2019-09-17 20:15 +0700
            Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-17 10:04 -0400
            Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-17 23:04 -0400
              Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used JJ <jj4public@vfemail.net> - 2019-09-18 16:17 +0700
                Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-18 10:12 -0400
                  Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used JJ <jj4public@vfemail.net> - 2019-09-19 21:23 +0700
                    Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-19 11:47 -0400
              Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "R.Wieser" <address@not.available> - 2019-09-18 11:30 +0200
                Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used JJ <jj4public@vfemail.net> - 2019-09-18 17:43 +0700
                  Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-18 10:16 -0400
                  Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "R.Wieser" <address@not.available> - 2019-09-18 16:49 +0200
                    Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-19 09:29 -0400
                    Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "R.Wieser" <address@not.available> - 2019-09-19 20:10 +0200
                      Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "R.Wieser" <address@not.available> - 2019-09-20 08:04 +0200
                      Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used JJ <jj4public@vfemail.net> - 2019-09-20 16:06 +0700
                        Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "R.Wieser" <address@not.available> - 2019-09-22 12:15 +0200
                          Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-22 09:38 -0400
                            Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "R.Wieser" <address@not.available> - 2019-09-22 16:49 +0200
    Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-16 15:58 -0400
    Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used Schmidt <ng@vbRichClient.com> - 2019-09-20 21:44 +0200
      Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-20 17:11 -0400
        Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used Schmidt <ng@vbRichClient.com> - 2019-09-21 00:18 +0200
          Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-20 21:26 -0400
          Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-20 23:50 -0400
            Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used Schmidt <ng@vbRichClient.com> - 2019-09-22 16:32 +0200
              Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-22 12:45 -0400
                Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used Schmidt <ng@vbRichClient.com> - 2019-09-22 19:41 +0200
                  Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-22 14:10 -0400
                    Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used Schmidt <ng@vbRichClient.com> - 2019-09-22 20:46 +0200
                      Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-22 15:09 -0400
                        Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used Schmidt <ng@vbRichClient.com> - 2019-09-22 22:30 +0200
                      Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-22 15:10 -0400
                        Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used Schmidt <ng@vbRichClient.com> - 2019-09-22 22:32 +0200
              Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used "Mayayana" <mayayana@invalid.nospam> - 2019-09-22 13:45 -0400
      Re: ADODB.Stream binary array to binary string failed unless x-user-defined is used JJ <jj4public@vfemail.net> - 2019-09-22 02:07 +0700

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#12212

FromJJ <jj4public@vfemail.net>
Date2019-09-18 17:43 +0700
Message-ID<1ed1j3kgoic6z.1ljakatuf60s0$.dlg@40tude.net>
In reply to#12210
On Wed, 18 Sep 2019 11:30:06 +0200, R.Wieser wrote:
> 
> @JJ,
> Did you compare the file contents ?  (FC /B test.bin part.bin)

Yes, I did. With that 256 bytes binary file.

[toc] | [prev] | [next] | [standalone]


#12214

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-18 10:16 -0400
Message-ID<qlte8v$8ft$1@dont-email.me>
In reply to#12212
"JJ" <jj4public@vfemail.net> wrote

| > @JJ,
| > Did you compare the file contents ?  (FC /B test.bin part.bin)
|
| Yes, I did. With that 256 bytes binary file.

 Your sample file does seem to work better for some
reason. Weird stuff.

  If it keeps working for you then that's fine. But if
you have any trouble you might want to just check
file size and then do Read(filesize). I've been using
a binary FSO class for years that';s been dependable,
but I use specific methods like that, never "looking a
null in the eye". :) 

[toc] | [prev] | [next] | [standalone]


#12216

From"R.Wieser" <address@not.available>
Date2019-09-18 16:49 +0200
Message-ID<qltg6r$16nv$1@gioia.aioe.org>
In reply to#12212
JJ,

> Yes, I did. With that 256 bytes binary file.

Odd that it works for you ...  The only difference I can think of is that I 
tried to write & read widestring files.

Regards,
Rudy Wieser

[toc] | [prev] | [next] | [standalone]


#12217

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-19 09:29 -0400
Message-ID<qlvvu9$n1o$1@dont-email.me>
In reply to#12216
"R.Wieser" <address@not.available> wrote

|
| > Yes, I did. With that 256 bytes binary file.
|
| Odd that it works for you ...  The only difference I can think of is that 
I
| tried to write & read widestring files.
|

  It gets even more weird. First I should say that I'm
almost never dealing with unicode in these cases. I'm
assuming we're talking about "binary" files treated as
ANSI text.

  If I open, read and write to disk JJ's short sample file,
even with a couple of extra nulls added in the middle,
it works. And Len shows the full length of the file after
reading it in, but Left(s1, 100) shows nothing.

  If I do the exact same thing with a small GIF file I
get an invalid operation error when I try to write it back
to disk as a new file. But if I do it my way,
getting the length of file and doing a TS.Read(filelen)
then it works fine to write it back to disk. In both cases
wscript tells me the string I read in is length 13,297.
But the string acquired via ReadAll doesn't work.

  I got curious about how much ADODB can do and
found another glitch: ADODB was removed on Server
2003. I don't know why. Security? But so far I haven't
found a way to use that to bypass FSO.

  If I read in a GIF with ADODB it only allows me to
read it in binary. It seems to be sniffing the file. Weird.
If I set it to text I get an error "Operation not allowed in
this context."
   If I read it in as binary then MSXML can't convert it
to Base-64. I'm finding MSXML very opaque to work with.
The method for doing a Base-64 conversion is bizarre.
Just assign the data type and insert a string and, presto,
like a magician it does the conversion, despite no explicit
call to a conversion method. That appears to be some kind
of bug-based hack that someone discovered along the way.

  It looks like MSXML can do a lot of handy things but
the docs and the object model are pretty much inpenetrable
to me. And since it's mainly for handling XML, which I
have no use for, I'm not inspired to dig out these useful
nuggets, like implicit data transformation. 

[toc] | [prev] | [next] | [standalone]


#12221

From"R.Wieser" <address@not.available>
Date2019-09-19 20:10 +0200
Message-ID<qm0gaq$12ld$1@gioia.aioe.org>
In reply to#12216
JJ,

> Odd that it works for you ...

I generated your testfile with the chars 0 ... 255, which, using "readall",
worked perfectly for me too.  So I experimented a bit.

As it truns out I got my "it garbage!" problem back when I prefixed the
example file with just the word "Hello".  Turns out that at least 5
characters is all it takes ("aaaaa" makes a mess as well)

However, that doesn't explain why your GIF file worked though.

Regards,
Rudy Wieser

[toc] | [prev] | [next] | [standalone]


#12223

From"R.Wieser" <address@not.available>
Date2019-09-20 08:04 +0200
Message-ID<qm1q59$t36$1@gioia.aioe.org>
In reply to#12221
JJ,

> Turns out that at least 5 characters is all it takes ("aaaaa" makes a mess 
> as well)

This morning I realized that by prefixing those five chars changing the 
files contents was not all I did, it also changes the size of the file.

And whatdoyouknow, just changing the size of the file to be at least 261 
chars (prepending, appending, randomly inserting any content you like) 
causes the trashing.

And something remarkable: Its only the first 260 bytes that get trashed. 
From character 261 the origional, expected content is visible again.

Regards,
Rudy Wieser

P.s.
Could you check the size of the GIF file (the one that worked for you) ? 
Chances are its less than 261 bytes ...

[toc] | [prev] | [next] | [standalone]


#12224

FromJJ <jj4public@vfemail.net>
Date2019-09-20 16:06 +0700
Message-ID<1da27nzi1ged7.4cykhn3dfnqx.dlg@40tude.net>
In reply to#12221
On Thu, 19 Sep 2019 20:10:33 +0200, R.Wieser wrote:
> JJ,
> 
>> Odd that it works for you ...
> 
> I generated your testfile with the chars 0 ... 255, which, using "readall",
> worked perfectly for me too.  So I experimented a bit.
> 
> As it truns out I got my "it garbage!" problem back when I prefixed the
> example file with just the word "Hello".  Turns out that at least 5
> characters is all it takes ("aaaaa" makes a mess as well)
> 
> However, that doesn't explain why your GIF file worked though.
> 
> Regards,
> Rudy Wieser

You're right. That test file, shows that ReadAll() is inconsistent and
buggy.

I also tried to use a test file which contains 0x00-0xFF then another
0x00-0xFF - totalling 512 bytes. While ReadAll() seems to succeed and the
variable length is 512, the received data is errorneous.

However, I found that using Read() with the same or larger number of
character of the file size, works (read count can't be too big though). I've
already tested it with above test file, and that "Hello"+(0x00-0xFF) test
file. e.g.

  on error resume next
  set fs = createobject("scripting.filesystemobject")
  s256 = ""
  for i = 0 to 255
    s256 = s256 & chr(i)
  next
  hello256 = "Hello" & s256
  set f = fs.createtextfile("hello256.bin", true, false)
  f.write hello256
  f.close
  set f = fs.opentextfile("hello256.bin", 1, false, 0)
  s = f.readall
  f.close
  if s = hello256 then
    wscript.echo "readall() ok"
  else
    wscript.echo "readall() fail" 'this one is shown
  end if
  set f = fs.opentextfile("hello256.bin", 1, false, 0)
  s = ""
  do while not f.atendofstream
    s = s & f.read(1048576)
  loop
  f.close
  if s = hello256 then
    wscript.echo "read(x) ok" 'this one is shown
  else
    wscript.echo "read(x) fail"
  end if

For further testing, I use below code as a binary file copier.

  set fs = createobject("scripting.filesystemobject")
  set f = fs.opentextfile(wscript.arguments(0), 1, false, 0)
  s = ""
  do while not f.atendofstream
    s = s & f.read(1048576)
  loop
  f.close
  set f = fs.createtextfile(wscript.arguments(1), true, false)
  f.write s
  f.close

I use it with below batch file to test copy all files of Windows' SYSTEM32
folder. Validating each file copy.

  @echo off
  setlocal
  for %%A in (c:\windows\system32\*) do (
    echo %%~nxA...
    cscript //nologo filecopy.vbs "%%A" test.tmp
    fc/b "%%A" test.tmp > nul
    if errorlevel 1 (
      echo "%%~nxA" copy is not identical!
      pause
      exit
    )
  )

[toc] | [prev] | [next] | [standalone]


#12232

From"R.Wieser" <address@not.available>
Date2019-09-22 12:15 +0200
Message-ID<qm7hm7$n4u$1@gioia.aioe.org>
In reply to#12224
JJ,

> You're right. That test file, shows that ReadAll() is inconsistent
> and buggy.

I've been taking a peek inside scrrun.dll (v5.7.0.16599), and have found 
that - most likely - it all boils down to a single mistake: the routine (at 
735A32E4) which copies a wide-string from one spot to another stops at a 
(word)zero (at 735A333A...E), even when it has been given a length argument 
for the source.

Padding the branch there with NOPs causes "readall" to return the files full 
contents.

Combine that with the memory-allocation just grabbing some heap-space 
without clearing it and you know what happens ....   Yep, the observed 
garbage.

I've already been thinking of patching it, but as it can easily circumvented 
in script code and such a patch would make scripts incompatible with other 
computers I don't think I should.

Regards,
Rudy Wieser

[toc] | [prev] | [next] | [standalone]


#12233

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-22 09:38 -0400
Message-ID<qm7thp$lsd$1@dont-email.me>
In reply to#12232
| > You're right. That test file, shows that ReadAll() is inconsistent
| > and buggy.
|
| I've been taking a peek inside scrrun.dll (v5.7.0.16599), and have found
| that - most likely - it all boils down to a single mistake: the routine 
(at
| 735A32E4) which copies a wide-string from one spot to another stops at a
| (word)zero (at 735A333A...E), even when it has been given a length 
argument
| for the source.
|
| Padding the branch there with NOPs causes "readall" to return the files 
full
| contents.
|

  Very clever. I wonder if it was really a bug, though. As I
understand it, the "scripting guys" wrote the files and they
clearly didn't think much of their clientelle. There was a
famous posting that told scripters, in a condescending,
scolding tone, that they shouldn't try to do binary operations
with WSH. It was intended to just be a GUI update for BAT
files, to be used by sys admins who don't really know what
they're doing. The whole thing is designed with "ninny
barriers".

[toc] | [prev] | [next] | [standalone]


#12235

From"R.Wieser" <address@not.available>
Date2019-09-22 16:49 +0200
Message-ID<qm81lj$v8p$1@gioia.aioe.org>
In reply to#12233
Mayayana,

>  Very clever.

Thanks, but not really.  Just some (freeware) IDA, a bit of programming and 
a lot of trace-and-tracking.

> I wonder if it was really a bug, though.

As far as I can tell it has to be.  Otherwise they could (should) have 
stopped reading the contents (which they do 128 bytes at a time) as soon as 
they encountered a Zero, and return a string with the size upto it (and no 
more).    Reading (way) beyond it simply doesn't make sense (especially not 
when executed on a remote file/stream ...).

> There was a famous posting that told scripters, in a
> condescending, scolding tone, that they shouldn't try to do
> binary operations with WSH.

:-)  That sounds like inventing restrictions to match the found bugs.

Over time I've encountered a number of win32 areas where something has been 
designed to solve one problem - theirs - and the rest doesn't really matter.

Regards,
Rudy Wieser

[toc] | [prev] | [next] | [standalone]


#12196

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-16 15:58 -0400
Message-ID<qlopj6$r2s$1@dont-email.me>
In reply to#12187
   The following seems to work, but I got to fooling around
and now I'm not sure what I did right. :) It looks like the only
difference was in changing the CharSet value, but I thought
I'd tried that before and it didn't work. In any case, this code
seems to work now. On a 3.6 MB file it was very quick to encode.
.17 seconds. But oddly slow to decode. 5.5 seconds. It also works
fine on your sample.

    So it may have only been a problem with using ascii as
CharSet. It didn't matter to the original author because he
only wanted to encode English text. Though I don't understand
why you couldn't use your "x-user-defined". In any case,
Windows-1252 works, as should any other ANSI encoding.


Dim LRet, Arg, FSO, TS, OFil, LSize, sOut, sIn

Arg = WScript.Arguments(0)

LRet = MsgBox("Click yes to encode file or no to decode.", 36)
  If LRet = 6 Then
      IfEncode = True
  Else
      IfEncode = False
  End If

Set FSO = CreateObject("Scripting.FileSystemObject")
Set OFil = FSO.GetFile(Arg)
LSize = OFil.Size
Set OFil = Nothing
Set TS = FSO.OpenTextFile(Arg)
sIn = TS.Read(LSize)
Set TS = Nothing

t1 = timer
If ifencode = True Then
  sOut = Base64Encode(sIn)
  Set TS = FSO.CreateTextFile(Arg & "-en64", True)
         TS.Write sOut
         TS.Close
    Set TS = Nothing
Else
 sOut = Base64Decode(sIn)
   Set TS = FSO.CreateTextFile(Arg & "-de64", True)
         TS.Write sOut
         TS.Close
    Set TS = Nothing
End If
t2 = timer
Set FSO = Nothing
MsgBox CStr(t2 - t1)

Function Base64Encode(sText)
    Dim oXML, oNode
    Set oXML = CreateObject("Msxml2.DOMDocument.3.0")
    Set oNode = oXML.CreateElement("base64")
    oNode.dataType = "bin.base64"
    oNode.nodeTypedValue = Stream_StringToBinary(sText)
    Base64Encode = oNode.text
    Set oNode = Nothing
    Set oXML = Nothing
End Function

Function Base64Decode(ByVal vCode)
    Dim oXML, oNode
    Set oXML = CreateObject("Msxml2.DOMDocument.3.0")
    Set oNode = oXML.CreateElement("base64")
    oNode.dataType = "bin.base64"
    oNode.text = vCode
    Base64Decode = Stream_BinaryToString(oNode.nodeTypedValue)
    Set oNode = Nothing
    Set oXML = Nothing
End Function

Private Function Stream_StringToBinary(Text)
  Const adTypeText = 2
  Const adTypeBinary = 1
  Dim BinaryStream 'As New Stream
  Set BinaryStream = CreateObject("ADODB.Stream")
  BinaryStream.Type = adTypeText
  BinaryStream.CharSet = "Windows-1252"
  BinaryStream.Open
  BinaryStream.WriteText Text
  BinaryStream.Position = 0
  BinaryStream.Type = adTypeBinary
  BinaryStream.Position = 0
  Stream_StringToBinary = BinaryStream.Read
  Set BinaryStream = Nothing
End Function

Private Function Stream_BinaryToString(Binary)
  Const adTypeText = 2
  Const adTypeBinary = 1
  Dim BinaryStream 'As New Stream
  Set BinaryStream = CreateObject("ADODB.Stream")
  BinaryStream.Type = adTypeBinary
  BinaryStream.Open
  BinaryStream.Write Binary
  BinaryStream.Position = 0
  BinaryStream.Type = adTypeText
  BinaryStream.CharSet = "Windows-1252"
  Stream_BinaryToString = BinaryStream.ReadText
  Set BinaryStream = Nothing
End Function 

[toc] | [prev] | [next] | [standalone]


#12226

FromSchmidt <ng@vbRichClient.com>
Date2019-09-20 21:44 +0200
Message-ID<qm3a6i$po8$1@dont-email.me>
In reply to#12187
Am 16.09.2019 um 03:23 schrieb JJ:
> I'm writing a slimmed down version of Base64 decoder...

Not sure, why there's so much "confusion" about this
(and why one should read binary FileData into a String first).

The modus-operandi with Base64 is Binary:
- passed as Input (as ByteArray) into the enconder
- and returned as Output-(ByteArray) from the decoder

Here's some (pretty symmetrical) Helpers,
which do as they should in my *.asp-Scripts (on Win2008/Win2012 and 
Win2016):

Function Base64Encode(Bytes) 'expects VarType "Byte()", returns a B64-String
   With CreateObject("Msxml2.DOMDocument").CreateElement("e")
     .DataType = "bin.base64"
     .NodeTypedValue = Bytes
     Base64Encode = .Text
   End With
End Function
Function Base64Decode(sBase64) 'expects a B64-String, returns VarType 
"Byte()"
   With CreateObject("Msxml2.DOMDocument").CreateElement("e")
       .DataType = "bin.base64"
       .Text = sBase64
       Base64Decode = .NodeTypedValue
   End With
End Function

Function ReadBytesFromFile(FileName) 'returns VarType "Byte()"
   With CreateObject("ADODB.Stream")
     .Open
         .Type = 1 'adTypeBinary
         .LoadFromFile FileName
         ReadBytesFromFile = .Read
     .Close
   End With
End Function
Sub WriteBytesToFile(FileName, Bytes) 'expects VarType "Byte()"
   With CreateObject("ADODB.Stream")
     .Open
         .Type = 1 'adTypeBinary
         .Write Bytes
         .SaveToFile FileName, 2 'adSaveCreateOverWrite
     .Close
   End With
End Sub

HTH

Olaf

[toc] | [prev] | [next] | [standalone]


#12227

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-20 17:11 -0400
Message-ID<qm3fc9$nof$1@dont-email.me>
In reply to#12226
"Schmidt" <ng@vbRichClient.com> wrote

| Not sure, why there's so much "confusion" about this
| (and why one should read binary FileData into a String first).
|

   Olaf! I didn't know you did scripting.

   Did you try your code? I can't get it to work. I'd tried
out of curiosity earlier, to cut out FSO, but there seems
to be a conflict with types. ADODB binary read is an array
of bytes. MSXML expects variants.

My quick test tries this:

a = ReadBytesFromFile(arg)
s = Base64Encode(a)
WriteBytesToFile Arg & "-64.txt", s

arg is the path of a dopped GIF. WScript.Arguments(0)

Error, on the line .Write Bytes in WriteBytesToFile:

Arguments are of the wrong type, are out of acceptable range, or are in 
conflict with one another.

  When I then encode a file and drop that to run the
decode, I get "Error parsing as bin-base64 datatype".
That's in Base64Decode at the line .Text = sBase64


[toc] | [prev] | [next] | [standalone]


#12228

FromSchmidt <ng@vbRichClient.com>
Date2019-09-21 00:18 +0200
Message-ID<qm3j85$egp$1@dont-email.me>
In reply to#12227
Am 20.09.2019 um 23:11 schrieb Mayayana:

>  Olaf! I didn't know you did scripting.
Well, I do... (a lot) - mostly at the serverside though
(in the context of WebApps).

Less often on the Desktop (but then using vbRichClient5
as the HelperLib for VBScript-enhancements, which go as
far as supporting e.g. __stdcall and __cdecl Dll-calls -
but also allow DB-based GUI-Apps without (registering anything).

Here is the package of ScriptGUI5:
http://vbRichClient.com/Downloads/ScriptGUI5.zip

Which should work (without touching the registry)
on all Win-Systems > XP (on XP you'll need registering)

I've developed this tool primarily, to help blind people
(who for the most part prefer to develop in NotePad(++)
or some other simple editor instead of a "graphical IDE".

I know, that you did something similar for these guys -
perhaps you will find especially the fruitbasket-demo
interesting (wich shows GUI-design without "using Pixels"
for Control-Placement, and has Speech-Support).

But to your questions:

> Did you try your code? I can't get it to work. I'd tried
> out of curiosity earlier, to cut out FSO, but there seems
> to be a conflict with types. 
Then one should take "better care" of the types
(within "those Variants", which is all VBScript knows).

A helpful (Debugging-)Function is TypeName(...).

Those functions I've commented with 'expects "Byte()"',
were referring to the approriate Variant-SubType.

> ADODB binary read is an array of bytes.
Yes, and such a ByteArray can be perfectly hosted within
a VBScript-Variant (but further used only, for "passing it along").

>  MSXML expects variants.
Yep - and certain Properties deliver - or expect,
ByteArrays (within Variants).

> My quick test tries this:
> 
> a = ReadBytesFromFile(arg)
> s = Base64Encode(a)
> WriteBytesToFile Arg & "-64.txt", s

As commented in the Signatur for WriteBytesToFile,
you'll have to pass a Variant of SubType "Byte()",
not a Variant of SubType String (your s Variable).

If you want to write "a String" to a File (with
the above Function WriteBytesToFile), then you'll
have to convert it to SubType "Byte()" priorily.

Usual Candidates (for such conversions) are Functions like:
- StringToANSIBytes
- StringToUTF8Bytes
(I can post routines for that, if needed)

Your example (to stay OnTopic with Base64) should work e.g. this way:

a = ReadBytesFromFile(arg) 'read a file without interpretation to bytes
s = Base64Encode(a) 'encode ByteArray a into s as Base64-Content
b = Base64Decode(s) 'decode s-Base64-Content back into a ByteArray b
WriteBytesToFile Arg & ".EncDec", b 'write ByteArray b into a File

The Base64-string (in your case s), is in almost all scenarios
"a temporary thing" (it does not deserve to be written to disk) -
usually it gets "passed along" within JSON-Objects or XML-Nodes.

E.g. if you receive Base64-content as a String from a WebRequest
(for example, a JPG-file when it was encoded at the server, and
then passed "downwards" in a JSON-Result-Response), then you
might want to write that clientside received "JPG-Base64-String"
to disk after decoding - e.g. in a single line of code like:

WriteBytesToFile "c:\temp\my.jpg", Base64Decode(sB64jpgContent)

HTH

Olaf

[toc] | [prev] | [next] | [standalone]


#12229

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-20 21:26 -0400
Message-ID<qm3uaa$usr$1@dont-email.me>
In reply to#12228
"Schmidt" <ng@vbRichClient.com> wrote

| Here is the package of ScriptGUI5:
| http://vbRichClient.com/Downloads/ScriptGUI5.zip
|

With help files. I'm impressed.

| I know, that you did something similar for these guys -

 I did a few small things and started working on a screen
reader, for a friend, but then he got his work to pay for
Jaws, and screen readers are a lot of work....


| A helpful (Debugging-)Function is TypeName(...).
|
| Those functions I've commented with 'expects "Byte()"',
| were referring to the approriate Variant-SubType.
|

 Yes, but ADODB is sending a variant of bytes, not
a variant of array members that are variants of subtype
byte, which is what MSXML seems to need.

| > My quick test tries this:
| >
| > a = ReadBytesFromFile(arg)
| > s = Base64Encode(a)
| > WriteBytesToFile Arg & "-64.txt", s
|
| As commented in the Signatur for WriteBytesToFile,
| you'll have to pass a Variant of SubType "Byte()",
| not a Variant of SubType String (your s Variable).
|

  Ah. Thanks. It works fine. I didn't realize at first glance
that I needed to adapt the functions, reading or writing
bytes or strings as needed. Once I made those changes
it works fine in both directions. Nice. And that bypasses FSO.


[toc] | [prev] | [next] | [standalone]


#12230

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-20 23:50 -0400
Message-ID<qm46ns$1g2$1@dont-email.me>
In reply to#12228
I turned this into a finished script for drag drop.
Very interesting. With a 3.6 MB file it was .1 seconds
to convert to base-64 but 10.6 seconds to convert
it back. Slower than FSO. But the docs say it does a
lot of processing when it reads in text and recommend
reading 128KB at a time. So I tried that and got a speed
of .14 seconds!

'-------------------------------------------

Dim ADO, XML, s1, A1, Arg, IfEncode, oNode
Dim T1, T2

Arg = WScript.Arguments(0)

LRet = MsgBox("Click yes to encode file or no to decode.", 36)
  If LRet = 6 Then
      IfEncode = True
  Else
      IfEncode = False
  End If

Set XML = CreateObject("Msxml2.DOMDocument")
Set ADO = CreateObject("ADODB.Stream")

T1 = Timer

If IfEncode = True Then
      With ADO
        .Open
        .Type = 1 'Binary
        .LoadFromFile Arg
        A1 = .Read
        .Close
      End With

      Set oNode = XML.CreateElement("El")
        oNode.DataType = "bin.base64"
        oNode.NodeTypedValue = A1
        s1 = oNode.Text
      Set oNode = Nothing

     With ADO
       .Open
       .Type = 2 'text
       .WriteText s1
       .SaveToFile Arg & "-64.txt", 2 'OverWrite
       .Close
     End With
Else

     With ADO
        .Open
        .Type = 2 'text
        .LoadFromFile Arg
        Dim iA, A2()
        iA = 0
        ReDim A2(100)
        Do
        s1 = .ReadText(128000)
        If Len(s1) > 0 Then
          A2(iA) = s1
        Else
          Exit Do
        End If
          iA = iA + 1
           If iA mod 100 = 0 Then ReDim Preserve A2(iA + 100)
        Loop
        .Close
      End With
      s1 = Join(A2, "")

      Set oNode = XML.CreateElement("El")
        oNode.DataType = "bin.base64"
        oNode.Text = s1
        A1 = oNode.NodeTypedValue
      Set oNode = Nothing

     With ADO
       .Open
       .Type = 1 'binary
       .Write A1
       .SaveToFile Arg & "-64.dat", 2 'OverWrite
       .Close
     End With

End If
T2 = timer

MsgBox CStr(T2 - T1)

Set ADO = Nothing
Set XML = Nothing

[toc] | [prev] | [next] | [standalone]


#12234

FromSchmidt <ng@vbRichClient.com>
Date2019-09-22 16:32 +0200
Message-ID<qm80ls$8cd$1@dont-email.me>
In reply to#12230
Am 21.09.2019 um 05:50 schrieb Mayayana:
> I turned this into a finished script ...

I'd leave the generic Helper-Functions I've posted intact
(one can place them in - and later load them from an include-file)

With just the two additional Helpers I've mentioned
(StringToBytes and BytesToString) you'd have all you need,
to replicate your Script with this short(er) code:

'*** script-code ***
Dim File, T, bInp, sB64
File = WScript.Arguments(0)

If MsgBox("Click yes to encode (no to decode)", vbYesNo) = vbYes Then
     T = Timer
     bInp = ReadBytesFromFile(File)
     sB64 = Base64Encode(bInp)
     WriteBytesToFile File & "-64.txt", StringToBytes(sB64, "utf-8")
Else
     T = Timer
     bInp = ReadBytesFromFile(File)
     sB64 = BytesToString(bInp, "utf-8")
     WriteBytesToFile File & "-64.dat", Base64Decode(sB64)
End If

MsgBox Timer - T
'*** end of script-code ***


Ok, here again the helper-stuff (now including StringToBytes/BytesToString):


'******* a small set of generic Helper-Functions *******
'* (usually placed in and loaded from an Include-File) *
Function BytesToString(Bytes, Charset)
   With CreateObject("ADODB.Stream")
     .Open
       .Charset = Charset
       .Type = 1: .Write Bytes: .Position = 0
       .Type = 2
       Do Until .EOS
         BytesToString = BytesToString & .ReadText(2^18)
       Loop
     .Close
   End With
End Function
Function StringToBytes(S, Charset)
   With CreateObject("ADODB.Stream")
     .Open
       .Charset = Charset
       .Type = 2: .WriteText S: .Position = 0
       .Type = 1
       If LCase(Charset) = "utf-8" Then .Position = 3
       StringToBytes = .Read
     .Close
   End With
End Function

Function Base64Encode(Bytes) 'expects VarType "Byte()", returns a B64-String
   With CreateObject("Msxml2.DOMDocument").CreateElement("e")
     .DataType = "bin.base64"
     .NodeTypedValue = Bytes
     Base64Encode = .Text
   End With
End Function
Function Base64Decode(sBase64) 'expects a B64-String, returns VarType 
"Byte()"
   With CreateObject("Msxml2.DOMDocument").CreateElement("e")
       .DataType = "bin.base64"
       .Text = sBase64
       Base64Decode = .NodeTypedValue
   End With
End Function

Function ReadBytesFromFile(FileName) 'returns VarType "Byte()"
   With CreateObject("ADODB.Stream")
     .Open
         .Type = 1 'adTypeBinary
         .LoadFromFile FileName
         ReadBytesFromFile = .Read
     .Close
   End With
End Function
Sub WriteBytesToFile(FileName, Bytes) 'expects VarType "Byte()"
   With CreateObject("ADODB.Stream")
     .Open
         .Type = 1 'adTypeBinary
         .Write Bytes
         .SaveToFile FileName, 2 'adSaveCreateOverWrite
     .Close
   End With
End Sub
'*** end of generic script-helpers ***


HTH

Olaf

[toc] | [prev] | [next] | [standalone]


#12236

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-22 12:45 -0400
Message-ID<qm88hq$ovk$1@dont-email.me>
In reply to#12234
"Schmidt" <ng@vbRichClient.com> wrote

| > I turned this into a finished script ...
|
| I'd leave the generic Helper-Functions I've posted intact
| (one can place them in - and later load them from an include-file)
|

  To each their own. To do both operations you end up
needing numerous helper functions. Something like 7 or 8.
Each step needs the helper function written differently.
Yet what I'm doing accomplishes the same thing in just
a few lines. And it doesn't repeatedly reference and
dereference ADODB and MSXML.

  Also, I find it worthwhile to post actual working code,
not just theoretical code. That way people can just
paste what I wrote and test the functionality/speed
for themselves, without having to write their own code
from scratch. You're posting various raw materials but
not working code. What you posted doesn't actually
work as is.

  So I was just turning it into working code that people
can test and time for themselves.

   But the details here are also critical:
   When reading in the base64 it needs to be read in as
text. That operation is amazingly slow. Reading bytes
is fast but reading a string is slow. And ADODB can't
copy bytes to a string. Note that the version I wrote is
reading in 128 KB at a time. The result is code that can
encode or decode 25 MB in less than 1 second. The older
version was taking about 4 seconds per MB and it turned
out all that lost time was on the read.
  If you look up ReadText in the ADODB help there's
an explanation.

    Also, if you do it the way I wrote it there's no
issue of charset. The only text being dealt with is
base64, which is ascii and the same on any computer.

   So the working operation ends up being:

To encode:

read in as bytes with adodb
assign that to msxml NodeTypedValue
read out msxml text
write that to disk as text

To decode it needs to be reversed:

read in as text with adodb (128KB at a time)
assign that to msxml text
read out msxml NodeTypedValue
write that to disk as binary

  Each step is unique. So in your method each
step requires instantiating a library, doing one
operation, then dereferencing (hopefully). Each
step is a function.

  If you want to write yours up as working code
we can try it, but I expect yours will end up being
notably longer, a bit slower, and more brittle.

[toc] | [prev] | [next] | [standalone]


#12237

FromSchmidt <ng@vbRichClient.com>
Date2019-09-22 19:41 +0200
Message-ID<qm8bp2$djd$1@dont-email.me>
In reply to#12236
Am 22.09.2019 um 18:45 schrieb Mayayana:
> "Schmidt" <ng@vbRichClient.com> wrote
> 
> | > I turned this into a finished script ...
> |
> | I'd leave the generic Helper-Functions I've posted intact
> | (one can place them in - and later load them from an include-file)
> |
> 
>    To each their own.

Goes without saying...

> To do both operations you end up needing numerous helper functions. 
> Something like 7 or 8.

No, it's exactly 6 (very small ones).

> Each step needs the helper function written differently.

No, as already stated, the functions are *generic*.

> Yet what I'm doing accomplishes the same thing in just
> a few lines. 
Nope, it's much more lines, compared to what I've posted.


> And it doesn't repeatedly reference and
> dereference ADODB and MSXML.

You mean "instancing"...
And no, that is definitely not an expensive operation -
(at least not for ADODB.Stream or Msxml2.DOMDocument,
which take about 10 Micro-Seconds = 0.01 Milli-Seconds).

So, creating a new, fresh instance within each function,
is perfectly fine (no need for you, as the function-user,
to "know about" or "bother with" these Helper-Objects)

>  Also, I find it worthwhile to post actual working code,
 > not just theoretical code.

Sorry, but every code-snippet I've posted in this thread,
already *is* working code - even the longer text in my last post.

But here is my replacement for your code again in a Zip:
http://vbRichClient.com/Downloads/B64Test.zip


> So I was just turning it into working code that people
> can test and time for themselves.

Nope, if I may be so frank, you "murdered it"... ;-)

E.g. what you wrote out as Base64-Text in your DemoCode,
is unnecessarily blown-up two UTF16-LE TextFormat,
which is twice as large as the written file needs to be.

> When reading in the base64 it needs to be read in as text.

As already said in a prior posting - nobody really writes
out a singular Base64-encoded String into the FileSystem -
you'll encounter those Strings "as parts of other stuff"
(e.g. in http-headers, or in JSON- or XML-trees)

But if you need to read or write text from/to the FileSystem,
you can use my posted (6 Base-)Functions as well...

As they are currently, you'll have to do that in two steps -
but those two steps can be combined into one line:

To read into a VB-String from an UTF8-Text-File
MyString = BytesToString(ReadBytesFromFile(File), "utf-8")

To read into a VB-String from a ANSI-Text-File
MyString = BytesToString(ReadBytesFromFile(File), "x-ansi")

 > Also, if you do it the way I wrote it there's no issue of charset.

As said, since you did not specify a Charset in your Code,
there definitely *is* an issue (because you generate UTF16-LE).

 > If you want to write yours up as working code...

Again, every Function I've posted definitely *is* working code.

If you think otherwise, I'd like a proper citation, containing
the snippet which (in your opinion) was not working for you -
that's considered good style in Usenet-communication.

HTH

Olaf

[toc] | [prev] | [next] | [standalone]


#12239

From"Mayayana" <mayayana@invalid.nospam>
Date2019-09-22 14:10 -0400
Message-ID<qm8dgd$ose$1@dont-email.me>
In reply to#12237
"Schmidt" <ng@vbRichClient.com> wrote

| Sorry, but every code-snippet I've posted in this thread,
| already *is* working code - even the longer text in my last post.
|

   No. The first one didn't work at all. It was
just the 4 helper functions. I tried it assuming
it would work, but it needed to be rewritten.

| Nope, if I may be so frank, you "murdered it"... ;-)
|
:)

| E.g. what you wrote out as Base64-Text in your DemoCode,
| is unnecessarily blown-up two UTF16-LE TextFormat,
| which is twice as large as the written file needs to be.
|

   Interesting. It does no such thing on my end. Maybe that's
system-specific. We're both doing the same thing there, but
you're switching the base64 string to bytes before writing it.
and otherwise ADODB flips it to unicode? That seems very odd.
Maybe ADODB changes all strings to unicode on later systems?
That seems rather dopey, to take a base-64 ascii string and
switch it without being asked to.

   I guess you could add that function to my code, but I'm
not sure it's necessary. And when I tried it I got "not
allowed in this context" at the charset assignment.

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | microsoft.public.scripting.vbscript


csiph-web