Storing String Data

The need to store strings is an issue sometimes faced when coding in XML, particularly when designing a gauge that utilizes the gps module (for example, when making an FMS). Options to store string data include:

1. Use of XML String Operators ord chr and scat to store and retrieve the ascii code equivalent of individual string characters in L:Vars. This has been the standard approach.

2. Macros that make use of the String Operators and enable more than one string character (up to 6) to be stored into a single L:Var. For example, Roman Stoviak has written a very clever set of macros that use String and Numerical Operators to store up to 6 string characters into L:Vars. http://forum.avsim.net/topic/299204-storing-string-data/

3. The internal registers, e.g., s0 … s49, with the limitation that these registers are wiped clean every update cycle.

4. String to memory dll module. Doug Dawson’s bottomless bag of cool tricks includes a prototype (September 2011) module that will allow strings to be stored into memory. Tested in FSX. Requires the loading of the dll module (but you won't need the macros from 2.). Please refer to Doug's posts further down in this thread.

5. XML read/write to hard disk. Robbie McElrath has completed a dll module that enables very easy file read/write capability: XML--> HDD--> XML. Accommodates strings and numbers, works with all text and .csv file formats, FS9 and FSX. He will be releasing it soon (Q4 2011). http://forum.avsim.net/topic/299204-storing-string-data/


A variation on 2), Robbie provides the following macros that utilize String and Bit Operators to manipulate strings and store the result into L:Vars.
Features of these macros:

1. Strings of up to 64 alphanumeric characters, including spaces, in length can be stored in a single, L:Var. All ascii special characters: !, @, #, $, % etc. etc. except "&", "/", "\", "<", and " ' " (single quote) are accommodated in addition to all of the alphanumerics.

2. The L:Var can have any name and there can be any number of such 'string' L:Vars in a gauge. The 'string' L:Vars can be read by any XML gauge of your panel set, similar to normal L:Vars.

3. Functional Backspace

4. FS9 and FSX


THE MACROS. There are 12 of them, but once they are copied and pasted into your gauge, you’re set (and these are an update to the original macros posted in the AVSIM Forum link above):
Code:
<Macro Name="Read4">
  (@1_4, number) 7 &lt;&lt; 0xFFFFFFF &amp; (@1_3, number) 21 >> 0x7F &amp; | (>@1_4, number)
  (@1_3, number) 7 &lt;&lt; 0xFFFFFFF &amp; (@1_2, number) 21 >> 0x7F &amp; | (>@1_3, number)
  (@1_2, number) 7 &lt;&lt; 0xFFFFFFF &amp; (@1_1, number) 21 >> 0x7F &amp; | (>@1_2, number)
  (@1_1, number) 7 &lt;&lt; 0xFFFFFFF &amp; (@2, number)   @3    0x7F &amp; | (>@1_1, number)
</Macro>

<Macro Name="ReadKB">
  @Read4(@1_4, @1_3_4, 21 >>)
  @Read4(@1_3, @1_2_4, 21 >>)
  @Read4(@1_2, @1_1_4, 21 >>)
  @Read4(@1_1, M:Key)
</Macro>

<Macro Name="Read4Str">
  (@1_4, number) 7 &lt;&lt; 0xFFFFFFF &amp; (@1_3, number) 21 >> 0x7F &amp; | (>@1_4, number)
  (@1_3, number) 7 &lt;&lt; 0xFFFFFFF &amp; (@1_2, number) 21 >> 0x7F &amp; | (>@1_3, number)
  (@1_2, number) 7 &lt;&lt; 0xFFFFFFF &amp; (@1_1, number) 21 >> 0x7F &amp; | (>@1_2, number)
  (@1_1, number) 7 &lt;&lt; 0xFFFFFFF &amp;  @2                  0x7F &amp; | (>@1_1, number)
</Macro> 	

<Macro Name="ReadStr">
  @Read4(@1_4, @1_3_4, 21 >>)
  @Read4(@1_3, @1_2_4, 21 >>)
  @Read4(@1_2, @1_1_4, 21 >>)
  @Read4Str(@1_1, r)
</Macro>

<Macro Name="Backspace4">
  (@1_1, number) 7 >> (@1_2, number) 0x7F &amp; 21 &lt;&lt; | (>@1_1, number)
  (@1_2, number) 7 >> (@1_3, number) 0x7F &amp; 21 &lt;&lt; | (>@1_2, number)
  (@1_3, number) 7 >> (@1_4, number) 0x7F &amp; 21 &lt;&lt; | (>@1_3, number)
  (@1_4, number) 7 >> (@2_1, number) 0x7F &amp; 21 &lt;&lt; | (>@1_4, number)
</Macro>

<Macro Name="Backspace">
  @Backspace4(@1_1, @1_2)
  @Backspace4(@1_2, @1_3)
  @Backspace4(@1_3, @1_4)
  @Backspace4(@1_4, L:PleaseBeZero)
</Macro>

<Macro Name="Clear4">
  0 (>@1_1, number) 0 (>@1_2, number) 0 (>@1_3, number) 0 (>@1_4, number)
</Macro>

<Macro Name="Clear">
  @Clear4(@1_1) @Clear4(@1_2) @Clear4(@1_3) @Clear4(@1_4)
</Macro>

<Macro Name="ToString1">
  (@1, number) 21 >> 0x7F &amp; chr
  (@1, number) 14 >> 0x7F &amp; chr scat
  (@1, number)  7 >> 0x7F &amp; chr scat
  (@1, number)       0x7F &amp; chr scat
</Macro>

<Macro Name="ToString4">
  @ToString1(@1_4) @ToString1(@1_3) @ToString1(@1_2) @ToString1(@1_1) scat scat scat
</Macro>

<Macro Name="ToString">
  @ToString4(@1_4) @ToString4(@1_3) @ToString4(@1_2) @ToString4(@1_1) scat scat scat
</Macro>
	
<Macro Name="FromString">
	:221 d slen 0 > if{ d 0 symb ord @ReadStr(@1) d slen 1 - 1 r ssub g221 }
</Macro>

USING THE MACROS. This is the easy part.

1. CONVERTING STRING DATA INTO AN L:Var

  • Entering one character at a time such as in direct keyboard entry, automatically concatenating as you type. The use of <On Key="Ascii"> will enable keyboard entry of "-" and "." as well as all the other alphanumerics:
Code:
<On Key="Ascii"> <!-- Keyboard Entry -->
	<Visible>(L:KeyboardEntryEnabled1, bool)</Visible>
	@ReadKB(L:StringLVar1)
</On>

<On Key="Backspace"> <!-- Backspace -->
	<Visible>(L:KeyboardEntryEnabled1, bool)</Visible>
	@Backspace(L:StringLVar1)
</On>
The user just needs to choose an L:Var name, such as StringLVar1, or whatever. No units. The macros will take care of the units. Entering data via “typing” on an FMS keypad image in your gauge is a simple variation of this. You only need to adjust the M:Key reference in the ReadKB macro. The last line of the ReadKB macro would read @Read4(@1_1, L:LKey) rather than @Read4(@1_1, M:Key). Then, in the <Mouse> section, for a click on the letter "A" for example:
Code:
<Area Left="25" Top="220" Width="15" Height="15">
	<Cursor Type="Hand" /> 
		<Click> 
			'A' ord (>L:LKey, enum) 
			@ReadKB(L:StringLVar1)	
		</Click>
</Area>
  • Entering a string of characters all at once. If you want to store something like:
‘VED BAM’, or (A:NAV1 IDENT, string), the following is used:
Code:
@Clear(L:BAM_VOR_ICAO)
'VED    BAM' @FromString(L:BAM_VOR_ICAO)

or

@Clear(L:Nav1Name)			
(A:NAV1 NAME, string) @FromString(L:Nav1Name)
2. DISPLAYING THE 'STRING' L:Var:
Code:
<String>%(@ToString(L:StringLVar1))%!s!</String>
3. PASSING A 'STRING' L:Var:
Code:
@ToString(L:BAM_VOR_ICAO) (>C:fs9gps:WaypointVorIcao)
4. CLEARING THE 'STRING' L:Var:
Code:
@Clear(L:StringLVar1)
Later today, I will attach a simple, fully functional “test gauge” that can be used to check out the use and capabilities of these string macros.

Appreciate feedback and comments – especially if unintended side effects are found.

Cheers,

Bob :)
 
Last edited:
Attached is an XML "test gauge" that demonstrates use of the string store macros.

Using the Store String Gauge:

  • Click on Text Box 1 to enable Direct Keyboard Entry in that Text Box
  • Type in any valid VOR ICAO. As an example, VRJ_ _ _ _NRE
  • The String L:Var appears in the text box as you type
  • Click the Dark Red button
  • The String L:Var is passed to the gps dll module and the gps variables (C:fs9gps:WaypointVorIdent), (C:fs9gps:WaypointVorName), and (C:fs9gps:WaypointVorFrequency, MHz) appear above the Text Box

  • Click on Text Box 2 to enable Direct Keyboard Entry in that Text Box
  • Type in any valid Facility ICAO, as an example WK3KICTCF19R which is an approach waypoint associated with Runway 19R at Wichita-MidContinent Airport, Kansas USA
  • The String L:Var appears in the text box as you type
  • Click the Royal Blue button
  • The String L:Var is passed to the gps dll module and a Direct To Flight Plan is created
  • The gps variables (C:fs9gps:FlightPlanTitle) and (C:fs9gps:FlightPlanWaypointDistanceRemaining, nmiles) appear above the Text Box
  • Check your Flight Plan or Map to see the new Flight Plan routing

  • Tune your NAV1 to any VOR within range of the aircraft
  • Click the Olive Drab button
  • The A:Vars (A:NAV1 IDENT, string) and (A:NAV1 NAME, string) are then stored into string L:Vars and the string L:Vars are, in turn, displayed next to the Olive Drab button captions

  • Click on the Red Box “R” to clear values

Inspect the XML code to see how the String Macros @ToString, @FromString, @Backspace, @ReadKB, @ReadStr, and @Clear are used.

Cheers,

Bob
 

Attachments

Last edited:
Hi Bob!
Many thanks for having post this !!
I made a quick test and it seems to work perfectly for me!!
The last blocking point that I have is to be abble to share string between XML and C++ without using a declared dll and generic string variable which is quite complex to install for most of simmers.
I would like to understand how the macros you've posted work, in order to have similar FromString/ToString functions in C++ and be able to share strings using L:Var.
Why? Because I coded c++ gauges which parse xml files (such as carriers or tanker planes configuration values) and I would like to "import" parsed string variables into XML gauge...

Does anyone knows how to translate these macros in C++?
Regars,
Sylvain
 

ddawson

Resource contributor
Hi Bob!
Many thanks for having post this !!
I made a quick test and it seems to work perfectly for me!!
The last blocking point that I have is to be abble to share string between XML and C++ without using a declared dll and generic string variable which is quite complex to install for most of simmers.
I would like to understand how the macros you've posted work, in order to have similar FromString/ToString functions in C++ and be able to share strings using L:Var.
Why? Because I coded c++ gauges which parse xml files (such as carriers or tanker planes configuration values) and I would like to "import" parsed string variables into XML gauge...

Does anyone knows how to translate these macros in C++?
Regars,
Sylvain
Have a look at the CABIN_COMFORT example in the SDK. If you can get that code loading in a gauge, rather than in a module, you are home free. I haven't been able to do that yet, so we are stuck with the .dll module, so far.

Doug
 
Last edited:
I made a quick test and it seems to work perfectly for me!!
Thanks, Sylvain.

I am curious to know - did you test the macros in FS9 or FSX? I have only FS9 on my pc right now, consequently I have not tried them in FSX.

Bob
 
...I am curious to know - did you test the macros in FS9 or FSX?
Hi Bob,
yes I tested it in FSX. For XML gauge that use last ACE XML structure, I just need to add <MacroValue> tag to make it works.

Doug, you're right : CabinConfort done in a "In Proc" process should exactly be what I would like to do...
As SimConnect is something possible in gauge code, I hope CabinConfort should work also I wish I had more time for C++ "exploration" :D

Regards,
Sylvain
 

ddawson

Resource contributor
For the benefit of those who have only had access to the version of the module uploaded in Post #4, above:
The module will also store individual string variables, in addition to arrays of strings or numbers.
The methodology is pretty straightforward.

First, you store the string in a variable, using any variable name you like,
'Some string I want to keep' (>C:FSX_STRINGS:ImportantStringNumberOne)
'Some other useful string' (>C:FSX_STRINGS:ImportantStringNumberTwo)

Then, you use the string variable to retrieve the saved string,
<String>%((C:FSX_STRINGS:ImportantStringNumberOne))%!s!</String>
<String>%((C:FSX_STRINGS:ImportantStringNumberTwo))%!s!</String>

Note that the use of XML style indexes (":" followed by a number), is troublesome at best and really not recommended. That was why I built in the array support.

Sylvain,
There is a C++ interface into the module, above. I will write some documentation for it and post. You can try building it into your existing gauges, if you wish.

Doug
 
Top