go to post Julius Kavay · Jul 28, 2021 Thanks for the hint, I saw the problem right after answering.Do we have a backwards-%GetNext(), i.e. an %GetPrevious()?
go to post Julius Kavay · Jul 28, 2021 Just create a simple method like this: ClassMethod RemoveNull(obj) { set iter=obj.%GetIterator() while iter.%GetNext(.key,.val) { if $isobject(val) { do ..RemoveNull(val) } elseif obj.%GetTypeOf(key)="null" { do obj.%Remove(key) } } gives you set json={"recipients": [{ "name":"Utsavi", "email":"utsavi@gmail.com"},{ "name":"Utsavi 1", "email":"utsavi1@gmail.com"},null, null],"content":[null, {"title":"Test.pdf", "data":"ygwehfbnwfbhew"} ]} write json.%ToJSON() --> {"recipients":[{"name":"Utsavi","email":"utsavi@gmail.com"},{"name":"Utsavi 1","email":"utsavi1@gmail.com"},null,null],"content":[null,{"title":"Test.pdf","data":"ygwehfbnwfbhew"}]} write ##class(some.class).RemoveNull(json) --> {"recipients":[{"name":"Utsavi","email":"utsavi@gmail.com"},{"name":"Utsavi 1","email":"utsavi1@gmail.com"},null],"content":[{"title":"Test.pdf","data":"ygwehfbnwfbhew"}]}
go to post Julius Kavay · Jul 20, 2021 Just a hint, I would take $ZD($h,2). For today, my development system (and systems at customers site) shows: Write $horolog - $zdate($horolog, 4) + 1 --> 65925.93 Write $zdate($horolog,4) --> 20.07.2021 Write $horolog - $zdate($horolog, 2) + 1 --> 65926 // expected value Later, this value (65925.93), as a $zdate() argument, gives you an <ILLEGAL VALUE> For $zdate($horolog,4), the link you provided says: 4 DD/MM/[YY]YY (01/07/97 or 27/03/2002) — European numeric format. You must specify the correct dateseparator character (/ or .) for the current locale.
go to post Julius Kavay · Jul 17, 2021 Hello Matjaž, I have a suspicion... I tested your case with a 16201607 bytes large PNG file (and it worked). First, to be able to do this, I had to made a change in the User.API class: //Do model.%JSONExportToString(.json) //Quit json Do model.%JSONExportToStream(.str) Quit str so you get back a STREAM instead of a string. As for IRIS and Cache, a string can't have more then 3641144 chars! And take into account, a base64 encoded string is 33% longer then the orginal (exact: newSize = oldSize + 2 \ 3 * 4), so you can use stringvariables up to an original picture size of (roughly, not counting the padding(s)): 3641144 - 19 - $l(identname) \ 4 * 3 // 19 bytes for {Ident:"","PNG":""} By the way, can you output the encoded size (i.e. the length) of the JSONString you send and then the size of the same string in C#? Are they the same?
go to post Julius Kavay · Jul 17, 2021 Zdravo Matjaž, for the first glance, the above methods should work. Although I don't understand why you need the User.Model class? You can achieve the same thing by defining Class User.Data Extends (%Persistend, %JSONAdapter) { } and then ClassMethod Load(Ident As %String) As %String [ Language = objectscript ] { Set data=##class(User.Data).%OpenId(Ident) Quit:data="" "null" Do data.%JSONExportToString(.json) Quit json } By the way, in the User.Data class, you can shorten the index definition to Index Ident On Ident [ IdKey ]; because an IdKey is ALWAYS unique. If you say, your C# gets a garbage PNG, then I would check two things: 1) does the PNG property (in User.Data) contain a valid PNG? Issue in a terminal session following commands: set data=##class(User.Data).%OpenId("...") do data.PNG.Rewind() // not necessary straight after an open zzdump data.PNG.Read(16) the output should be: 0000: 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 .PNG........IHDR 2) are you sure, C# gets the JSON-string returned by Load() method? Are you sure, no intermediate process (a middleware) changes this string by applying extra encoding or decoding? Pozdrav z Beča (Dunaja)
go to post Julius Kavay · Jul 16, 2021 Class Test.JD Extends (%Persistent, %JSON.Adaptor) [ Language = objectscript ] { Property Name As %String; Property Type As %String; Property Image As %Stream.GlobalBinary; } set obj=##class(Test.JD).%New() set obj.Name="Joe" do obj.Image.Write($system.Encryption.Base64Decode("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAAACXBIWXMA")) do obj.Image.Write($system.Encryption.Base64Decode("AA7EAAAOxAGVKw4bAAAAGElEQVQokWNk+M9AEmAiTfmohlENQ0kDAD8vAR+xLJsiAAAAAElFTkSuQmCC")) if obj.%JSONExportToString(.string) write string --> {"Name":"Joe","Image":"iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAA AAAAABupgeRAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAGElEQVQokWNk+M9AEmAiTfmohlENQ0kDAD8vA R+xLJsiAAAAAElFTkSuQmCC"} As you see in the above example, the export works and does Base64Encoding for the appropriate property (in my example this is 16x16 pixel green rectangle). Please show the relevant part (property) of your class (definition).
go to post Julius Kavay · Jul 15, 2021 Obviously, the response.Data does not contain valid JSON. You can simply check the received data by putting the data aside in a temporary global, something like this: do request.HttpResponse.Data.Rewind() set ^temp.debug($j,"size")=request.HttpResponse.Data.Size set ^("data")=request.HttpResponse.Data.Read(request.HttpResponse.Data.Size) // or just the first 1000 bytes zw ^temp.debug Now you can take a look on the incoming data, maybe there is an encoding problem or the data do not adhere to JSON specification
go to post Julius Kavay · Jul 13, 2021 According to your code, the variable obx5 contains the base64 encoded tiff image. There is one thing I do not understand: what are those "\.br\" char-sequences, how they came into the base64 stream? Anyway, I suppose they are OK (those "\.br\"s), so put all those pieces together and decode all at once: set input = "" for i=1:1:$L(obx5,"\.br\") { set input = input _ $P(obx5,"\.br\",i)) } Do obj.Write($system.Encryption.Base64Decode(input)) Now you should have a correct decoded image, provided, the obx5 variable really contains the original base64 encoded tiff image with randomly inserted "\.br\" chars (for whatever reason).
go to post Julius Kavay · Jul 13, 2021 You are sure, for each and every $P(obx5,"\.br\",i) the equation $L($P(obx5,"\.br\",i))#4=0 holds?
go to post Julius Kavay · Jul 13, 2021 Good Morning Vietnam... ach, I meant Good Morning Julius! After 1977 (the year I first met Mumps) now is the time to learn M the right way and entirely! OK, the truth is, I never usd neither the call nor the expression codemode., hence there was no need to check, how parameter passing works...
go to post Julius Kavay · Jul 13, 2021 Nice solution, but just one question, how gets your S routine the parameter <t>? Is there some trick, I don't know? I would have written this way ClassMethod ToNato(t) [ CodeMode = call ] { ^S(t) } but then makes 5 chars
go to post Julius Kavay · Jul 13, 2021 Oh, believe me, I can top even myself include macrodefs ClassMethod ToNato(t = "If, you can read?" ) [ CodeMode = expression ] { $$$S } ClassMethod s(t) { // whatever solution you have, put it there. } macrodefs.inc #define S ..s(t) Are four chars short enough? Today, I'm just and ish
go to post Julius Kavay · Jul 12, 2021 The possibilities to get a corrupted file are: - you do not read the (Base64) encoded file in chunks of N*4 (where N is an integer)- your stream wasn't rewinded before starting with reading- your (incoming) stream is (already) corrupted (but this would in some cases trigger an error in Base64Decode() method). Just for a test, try this str = is your incoming Base64 stream set filename = "test.tiff" open filename:"nwu":1 if '$test write "Can't open",! quit do str.Rewind() use file while 'str.AtEnd { write $system.Encryption.Base64Decode(str.Read(32000)) } // 32000 = 4 * 8000 close file If the incoming stream is not corruoted, the right now created tiff file should be readable
go to post Julius Kavay · Jul 12, 2021 I bet, this one, with 6 chars only, is shorter ClassMethod ToNato(t = "If, you can read?" ) [ CodeMode = expression ] { ..s(t) } ClassMethod s(t) { // whatever solution you have, put it there. }
go to post Julius Kavay · Jun 21, 2021 I have no idea, what is the date format of PID 7.1, but I'm sure, you can convert this date to $h format, so the answer to your question is set age = $h - $zdh(PID7.1Date,?) \ 365.25 now <age> contains the patients age in full years
go to post Julius Kavay · Jun 10, 2021 Can you please give us an example for (each) those "variantes" (I mean, those JSON strings)?Something like: {"sent":"2021-06-10 09:00:00", "received":"2021-06-10 09:05:00", variante1... } {"sent":"2021-06-10 09:00:00", "received":"2021-06-10 09:05:00", variante2... } Thank you.
go to post Julius Kavay · Jun 9, 2021 If it helped you to understand how things work, then everything is OK. Have a nice day.
go to post Julius Kavay · Jun 8, 2021 Somehow I don't get you right. To save obj.%Size() in a variable, just do a simple assign set myVariable = obj.%Size() but I'm pretty shure, this was not your intended question. I suppose, you have JSON formatted data (a string or a stream) and you want to store those data in a table. Am I right? If yes, then follow the next steps: 1) create a class which describes your JSON objects (strings) Class DC.SehindeRaji Extends (%Persistent, %JSON.Adaptor) { Property byr As %String(%JSONFIELDNAME = "byr:"); Property iyr As %String(%JSONFIELDNAME = "iyr:"); Property eyr As %String(%JSONFIELDNAME = "eyr:"); // do the same for all other fields ClassMethod Import(data) { set obj=..%New() // create a new DC.SehindeRaji object set sts=obj.%JSONImport(data,"") // import the (JSON) data if sts { set sts = obj.%Save() if sts { write "Saved, ID=",obj.%Id(),! quit 1 } else { write "Not saved, Err=",$system.Status.GetOneErrorText(sts),! quit 0 } } else { write "Can't import: ",$system.Status.GetOneErrorText(sts),! quit 0 } } } 2) You can create some test data (interactively) in a terminal session set dynObj = {"byr:":"1937", "iyr:":"2017", "eyr:":"2020"} set data = dynObj.%ToJSON() or get your data somehow from an input (possibly from a file), the only important thing is, your data should look like this write data --> {"byr:":"1937","iyr:":"2017","eyr:":"2020"} 3) import those data write ##class(DC.SehindeRaji).Import(data) --> Saved, ID=1 4) Now open the saved data and check the result set oref = ##class(DC.SehindeRaji).%OpenId(1) write oref.byr --> 1937 write oref.iyr --> 2017 write oref.%JSONExportToString(.exported,"") --> 1 write exported --> {"byr:":"1937","iyr:":"2017","eyr:":"2020"} zw ^DC.SehindeRajiD ^DC.SehindeRajiD=1 ^DC.SehindeRajiD(1)=$lb("","1937","2017","2020") I hope, this is what yoy want to do...