User bio
404 bio not found
Member since Feb 2, 2016
Replies:

I agree that LOG^%ETN, and ^%ETN as a process terminating trap routine, are the best way to log problems.  But we should also mention that DO ^%ERN is the utility that will dump the data that LOG^%ETN places in the ^ERRORS multi-dim global.  That dump includes state information, a complete call-stack dump, a list of all active local variables at each stack level, and in recent IRIS releases, it also includes a dump of all Class Objects with an oref active in memory.  This is a lot of information for each ^ERRORS entry so you might not want to be over-enthusiastic with your calls on LOG^%ETN.

I don't know anything about the FhirBinary class but I do know why the %GetNext method in the %Iterator.Array or %Iterator.Object classes is giving the <MAXSTRING> signal.  Let's assume the %GetNext in question is accessing a %DynamicObject as the %DynamicArray case is identical.  A %DynamicObject (usually created by the %FromJSON method) limits it contained string elements only by the amount of memory that can be obtained from the Operating System running the IRIS instance.  Fetching a long string element from a %DynamicObject as an ObjectScript string value will signal <MAXSTRING> when the %DynamicObject string element is too long.  However, you can fetch a long string element as a %Stream.DynamicBinary or %Stream.DynamicCharacter class object.  Such a %Stream object can contain any string that will into the system memory.  Long %Stream contents longer than the ObjectScript maximum string length can be accessed by using the Read(.len,.status) method to access smaller substrings of the %Stream contents.  Also, you can copy one class of long %Stream into a different class of long %Stream if you want to move a long string out of memory and into either a a file or an ObjectScript global array.

The Class Reference documentation for the %Iterator.Object class does not directly appear in either Class Reference webpage on an IRIS instance nor in the Class Reference web page in the InterSystems IRIS network documentation.  This strikes me as a documentation bug.

Fortunately you can see the appropriate Class Reference documentation by indirectly going to the Class Reference page for the %Library.DynamicObject class (or %Library.DynamicArray class) and going to the documentation for %GetIterator method. That documentaton contains a link to the %Iterator.Object class. Click on that link and you will go the %Iterator.Object Class Reference page where you can see the documentation for the GetNext(.key,.value,.type) method.  

%GetNext method is used to iterate over the values in a %DynamicObject.  The third argument, .type, is optional.  The two argument form, %GetNext(.key,.value) will return the key index in .key and its associated ObjectScript value in .value.  If the element value cannot be converted to an ObjectScript value then you will get a <MAXSTRING> or <MAXNUMBER> signal.  However, the three argument form, %GetNext(.key,.value,.type) will not signal these errors.  In place of a <MAXSTRING> signal, the .type argument will contain "string" and the the .value argument will contain the appropriate in-memory %Stream object value.  In place of a <MAXNUMBER> signal, the .type argument will contain "number" and .value will contain a string with the decimal representation of the numeric value.

More detail of other uses for the .type argument of the %GetNext(.key,.value,.type) method call can be found on the %Iterator.Object (or %Iterator.Array) Class Reference web page.

When the Fhir.Binary class needs to iterate over the elements of a %DynamicArray/Object then it should not use the 2 argument form of %GetNext(.key,.value) but should instead use the the 3 argument form %GetNext(.key,.value,.type) and be prepared when the type of the the .value variable does not match the type specified by the .type argument.

We need to see more of your code to see what is truly happening.  The routine method call Do obj.%Set("data",pStream,"stream>base64") should have no problem providing your system has enough memory to construct entire 'obj' Dynamic Object in your process memory.  Your system will want to avoid having many large Dynamic Objects in memory at the same time.  If the system runs out memory for all the active processes then the operating system will usually start aborting processes randomly until the operating system decides it now has enough free memory to continue execution.

Calling %Set(,,) to read JSON text from a very large %Stream should only use moderate size buffers on the string stack.  If a call on %Set(,,) writing from a %Stream generates a <STRINGSTACK> signal then that should be reported to InterSystems as a bug.

However, your reply mentions the %ToJSON() function method call.  Calling %ToJSON as a function will place the result on the String Stack so it is possible such a function call could signal a <STRINGSTACK> error although if the %ToJSON() function call appears in a very simple expression then I would expect a <MAXSTRING> signal instead of a <STRINGSTACK> signal.

Calling %ToJSON() or %ToJSON(outstrm) as a routine method call in a DO statement should not get either a <STRINGSTACK> or a <MAXSTRING> signal since the result is not going to an ObjectScript string value.

Certifications & Credly badges:
Steven has no Certifications & Credly badges yet.
Global Masters badges:
Steven has no Global Masters badges yet.
Followers:
Following:
Steven has not followed anybody yet.