COM interface and large string/stream data.

Author: i.sharp@pcisystems.co.uk (Iain Sharp)

I have a com interface dll, within this I have some data (a pdf file) held in System.IO.Stream format, I can convert this to a string using Streamreader.readtoend(); I have declared this string as a parameter to the function, (ref string outputdata) In uniface have declared the parameter Outputdata mapped to outputdata, type string, implementation VT_BSTR, this only seems to return approx 1000 bytes. Leading to an invalid pdf file. If I change the type to raw, implementation V_ARRAY I get lots more data, but it seems to have {! scattered across it. Leading to an invalid pdf file. Anyone know how to sensibly return large raw data strings from c# to uniface? regards, Iain

6 Comments

  1. Hi Iain, perhaps the following may give you a hint (because there the {D appears instead of the ~): Symptoms When data is encoded using the URL encoding scheme ($encode("URL")) and then decoded again ($decode("URL")) then the returned data may not be the same as the source. Consider the following scenario: The string "ab cd~ef+gh" is encoded using the URL encoding scheme and the return value is assigned to the general variable $1: $1 = $encode("URL", "ab cd~ef+gh") ; $1 = "ab%20cd~ef%2Bgh" The value in $1 is decoded again using the URL encoding scheme and the return value is assigned to the general variable $2: $2 = $decode("URL", $1) ; $2 = "ab cd{Def+gh" As you can see the data in $2 is not equal to the source data. Solution Convert the data returned by $decode("URL") to an Uniface string data type using $encode("USTRING"). For example: The string "ab cd~ef+gh" is encoded using the URL encoding scheme and the return value is assigned to the general variable $1: $1 = $encode("URL", "ab cd~ef+gh") ; $1 = "ab%20cd~ef%2Bgh" The value in $1 is decoded again using the URL encoding scheme and the return value is converted to an Uniface String; the result is then assigned to the general variable $2: $2 = $encode("USTRING", $decode("URL", $1)) ; $2 = "ab cd~ef+gh" Now the data of $2 will be equal to the source data. Root Cause The data returned the Proc function $decode may contain the null byte (0x00), so the return value is in the Uniface raw data type, which is able to handle this. If you need to get the data in the string data type, then you can convert it from raw to string data using $encode with the USTRING algorithm. For details see the reference of $decode in the Uniface documentation (for example for version 9.4): Uniface Library > Uniface Reference > Proc Functions > $decode


    Author: ulrich-merkel (ulrichmerkel@web.de)
  2. No, sorry, I don't see how that's relevant. I don't use $encode or $decode at all. I'm only asking how to get large raw or string values back out of a com object. I have a PDF stored in System.IO.Stream format and I want to return it to Uniface so I can store it in the database. What data types should I use to do this?


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  3. Hi Iain, you said when you specify it as RAW, you will get some "{! scattered across it" (similar to the {D instead of the ~ in the symptoms description). Perhaps a convert to an Uniface string data type using $encode("USTRING") may help you as well as it helped in the URL scenario.


    Author: ulrich-merkel (ulrichmerkel@web.de)
  4. Unfortunately not. This is the beginning of the returned data as per the debugger. %{!P{!D{!F{!-{!1{!.{!7{! {!{+{!%{!|o|q|o|q|o|q|o|q {!{+{!1{! {!0{! {!o{!b{!j{! {!{+{!<{!<{! {!{+{!/{!T{!y{!p{!e{! {!/{!C{!a{!t{!a{!l{!o{!g{! {!{+{!/{!P{!a{!g{!e{!s{! {!2{! {!0{! {!R{! {!{+{!/{!P{!a{!g{!e{!M{!o{!d{!e{! {!/{!U{!s{!e{!N{!o{!n{!e{! {!{+{!/{!V{!i{!e{!w{!e{!r{!P{!r{!e{!f{!e{!r{!e{!n{!c{!e{!s{! {!<{!{!>{! {!{+{!>{!>{! {!{+{!e{!n{!d{!o{!b{!j{! {!{+{!5{! {!0{! {!o{!b{!j{! {!{+{!<{!{!>{! {!{+{!s{!t{!r{!e{!a{!m{!{+{!x{!|o|q|o|q|o|q|o|qn{!{{#l{!|o|qE{!|o|q|o|qq{!l{!!{!{'{!z{!'{!8{!r{!|o|q4{!|o|qZ{!Y{!F{!w{%|o|q{4{(W{!{A{!|o|q This is what I get back if I have my com object save the PDF to file and use lfileload/raw to get the data. %PDF-1.7 {+%|T|U|A|E {+1 0 obj {+<< {+/Type /Catalog {+/Pages 2 0 R {+/PageMode /UseNone {+/ViewerPreferences <> {+>> {+endobj {+5 0 obj {+<> {+stream{+x{b{s{^|Mn{<7{1{L|a|i)x|[{#Z{ If I use $encode("USTRING", v_temp) on the data returned in raw format (1st example) I get % (one character). I am probably/potentially doing this wrong at the c# level. The big burning question here is how to get a large string back out of com to uniface. If I declare the parameter as a string in the signature I get :- %PDF-1.7 %���� 1 0 obj << /Type /Catalog /Pages 2 0 R /PageMode /UseNone /ViewerPreferences << /FitWindow true /PageLayout /SinglePage /NonFullScreenPageMode /UseNone Which is obviously missing data (and is only 463 bytes long in total as opposed to the 23Kb in the file). I have never passed a stream back form com to uniface, and have no idea if converting it to string is the right thing to so in the first place. I am looking for someone with experience in doing this to give me a clue as to what structures/data types I should be using...


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  5. Okay, I faffed within c# and tried unicode encoding. This came SO close to working it confused me for a bit. What I actually needed to do was to pass out a byte[] parameter into the raw data parameter uniface wanted, which required some jiggery pokery to convert System.IO.Stream to byte[] because there isn't an implicit conversion. So it seems to be working now.


    Author: Iain Sharp (i.sharp@pcisystems.co.uk)
  6. Hi iain, thanks for sharing the result of your hard C# work with us. Looks like I will remember your post when I see a similar situation. Is it OK with you when I post your findings on T.U.R.F. as well to inform the independend uniface community as well? Or do you want to do it on your own, which I would prefer. P.S. Perhaps we need some "WSTRING" parameter type to handle C# unicode strings


    Author: ulrich-merkel (ulrichmerkel@web.de)