Open Menu

Synergex Blog


Now that’s what I call service!

By Richard Morris, Posted on February 23, 2010 at 6:11 pm

Web services have been around for quite a while now.  If you attended the Success Partner Conference back in 2006, in London or Boston, you’ll have completed a hands-on tutorial that walked you through the steps required to consume web services with Synergy code.

During the conference, we wrote Synergy code to consume a number of different web services, from a number of different hosting sites.  The first service we utilised returned an array of valid country names. We then used the returned information to populate a UI Toolkit combo drop-down input control to allow the user to select the required country.  Other services we used allowed us to validate address details and credit card numbers.  The final web service we worked with, that I know several customers have since made use of, gave us the ability to interface with a Simple Message Service (SMS) API and send text messages to a mobile phone number.  Not all web services are free, and if I remember correctly, I believe the cost for sending an SMS was about $0.008!

So, when I saw the request from Rodney Latham on the Synergy-l list server, requesting if anyone had code to determine if a given date was a public holiday, I thought “there must be a web service to determine that”.  After a quick search on the Internet I found one at a site called www.holidaywebservice.com. After a few minutes of navigating the site, and looking at the WSDL (Web Service Description Language), it was obvious that I could write a few lines of Synergy code to consume the web service to determine if a date was a public holiday.  Another great feature of the web service was that it was free!

I knew that Rodney’s Synergy software ran on the OpenVMS operating system, so any fancy MS Windows coding was to be avoided – it had to be pure Synergy.  As long as the machine could access the internet we could execute the web service.

I could have written a regular Synergy subroutine or function, but instead I chose to implement executing the web service within a static method, as part of a SynPSG.DateFunctions class.  By defining the method as static, you don’t need to instantiate an instance of it.  This makes the coding very simple.  Add a reference in your code, using the “import” statement, to the SynPSG namespace and you’re ready.  To determine if the date is a holiday, simply execute the static method, for example;

import SynPSG

proc

    if (SynPSG.DateFunctions.IsHoliday(20100105,

&     SynPSG.CountryCode.EnglandAndWales)

    begin

    ;;we have a holiday, let’s party!

    end

The first argument to the IsHoliday() method accepts a reversed eight digit date and the second is an enumeration which allows you to select the required country code.  The enumeration is defined within the SynPSG namespace;

public enum CountryCode

    Ireland

    EnglandAndWales

    Scotland

    UnitedStates

endenum

Simple, free and the code is available on the Synergex Code Exchange – log into the resource centre and search the Code Exchange directory for IsHoliday.


Using Workbench to Build Applications on Remote Servers

By William Hawkins, Posted on February 18, 2010 at 4:21 pm

I recently went to a customer site, to help them integrate Workbench into their OpenVMS development environment.  As a source code editor, the “integration” is relatively simple, you just need to have NFS/CIFS/SAMBA installed, and use it to make your OpenVMS (or UNIX) drives look like they’re actually Windows drives.  However, when you want to compile or link your application, you either need to go back to your telnet window and build it there, or you can download the RemoteBuild utility from the SynergyDE CodeExchange.  There are two versions for OpenVMS out there right now, both provided by Chris Blundell from United Natural Foods Inc.

Synergex PSG decided that we wanted to provide a remote build facility that could talk to multiple environments using information from a single Workbench project.  We wanted to minimize any potential firewall issues (for companies that have internal firewalls), and we also wanted to build on the SynPSG.System classes (distributed with ChronoTrack – our SPC 2009 demonstration application) for the network communication.  For those of you unfamiliar with the SynPSG.System classes, they are a partial implementation of the Microsoft System classes written in Synergy, (so they work on all supported platforms,) but when we have Synergy for .Net available, we'll be able to use the native .NET framework System class without modifying code. (ok, we'll have to change the import statements, but that should be all.)

So PSG has posted our flavor of a remote building application into CodeExchange – it's called remoteServer.   There is a client component to install into Workbench, and a server component (written in Synergy) that runs on each development server.  If you have both SAMBA (or equivalent) and remoteServer installed and configured, you are able to compile your application on the remote system, and in the unlikely event of a compile error (I know, you never have any coding errors) you will be able to double click on the error on the output window, and go straight to that line of code in the source file on your remote server.

If you work in a multi-platform development environment, I would encourage you to go download any of the remote build offerings in CodeExchange, and start using the power of Workbench to help improve the productivity of your developers.


To Print or not To Print

By Richard Morris, Posted on February 12, 2010 at 10:10 pm

The Synergy Windows Printing API is a collection of routines that allow you to fully control printing on the Windows platform, and make use of extended printer features.  The API records the print information in a Windows enhanced metafile which can then be played back to devices such as a printer or the print preview window.

Many of you will be using this API to bring true Windows printing capabilities to you applications. So, when you upgraded to version 9.3 of Synergy and rebuilt your applications, where did your prints disappear to?  You may have been caught out by a new feature added to the API.  In version 9.3 two new integer fields were introduced to the font specifications structure to enable you to change the orientation and escapement of the font.  The orientation allows you to specify the angle between the baseline of a character and the page’s horizontal axis.  The escapement specifies the angle between the baseline of a string of text and the page’s horizontal axis.  For full details see the version 9.3 on-line manuals.  The default value for both of these two new fields is zero, meaning that no rotation of the text will occur.

To set the required font characteristics you use the DWP_FONT sub-function of the WPR_SETDEVICE() function.  The font characteristics are defined within a structure called “font_specs”, included in the DBLDIR:winprint.def header file.  This structure is used to allocate memory to store the font specifications, and provide them to the %WPR_SETDEVICE() function.  You allocate the required memory using the %MEM_PROC() function, for example;

    fontHandle = %mem_proc(DM_ALLOC+DM_STATIC, ^size(font_specs))

You can then set the required font details;

    ^m(font_specs.face_name, fontHandle) = “Courier”

However, if you don’t specify values for all of the fields defined within the “font_specs” structure, the values will be undefined, and for the integer fields, most likely be non-zero.  So, the two new fields will actually contain values, and so orientation and escapement settings will be passed to the %WPR_SETDEVICE() function.  Things will no longer print as you expect!

One way to ensure that the integer data is initialised when you allocate dynamic memory is to use the DM_NULL qualifier.  This ensures that any integer data is initialised correctly.  For example;

    fontHandle = %mem_proc(DM_ALLOC+DM_STATIC+DM_NULL, ^size(font_specs))

However, this does not correctly initialise any non-integer data, and is not future-proof.  If the structure is modified to include new alpha/decimal/implied decimal fields in the future, these fields would then contain incorrect values.  An alternative is to initialise a local copy of the font specifications structure and then assign that to the allocated dynamic memory.  The INIT statement ensures that fields within a record or structure are initialised correctly based on the field type.  Firstly, create a structfield, which is a field defined as a structure type.

.ifdef DBLV9

record

    tmpFont    ,font_specs

endrecord

.endc

The code to allocate the memory for the font specification remains the same;

    fontHandle = %mem_proc(DM_ALLOC+DM_STATIC+DM_NULL, ^size(font_specs))

Now we use the structfield to correctly initialise the dynamic memory;

.ifdev DBLV9

init tmpFont    ;ensures individual fields correctly initialised

^m(font_specs, fontHandle) = tmpFont

.endc

This same coding structure can be applied to the other structure specifications defined in the DBLDIR:winprint.def header file.  The code is backward compatible with earlier versions of Synergy, and will prevent any similar issues in the future.

Alternatively, from version 9.1 you can remove the need to allocate memory, and simply use the structfield.  For example;

record

    textFont    ,font_specs

endrecord

And then use the structfield to define font characteristics;

    init textFont    ;ensures individual fields are correctly initialised

    textFont.facename = “Courier”

    textFont.weight = 700

    wpr_setdevice(rptHandle, DWP_FONT, textFont)

    wpr_pint(rptHandle, DWP_WRITEOUT, x, y, “Hello Bloggers!”)

This second approach has two advantages.  Firstly, you no longer need to allocate and clean up any dynamic memory.  The second is that you get full intellisense within workbench, listing the available fields within the font structfield.


What’s in my library?

By William Hawkins, Posted on February 4, 2010 at 4:22 pm

The obvious answer that springs to mind is "books", but some may respond "what sort of library?".  Of course, in this context, I'm really referring to a library containing Synergy object code. 

When referring to Synergy subroutines and functions, on both Windows & Unix, you can perform a "listdbo" or "dblibr -t" on the object file/object library and peruse the output to see the names of your routines.  However, when referring to methods (in classes/namespaces), the name used is mangled.  This mangling process takes the fully qualified name of the method, the return type, and all the parameter types, and reduces it down to a mangled name.  In a lot of cases, you can look at the mangled name and stand a chance of actually recognizing the name of the routine, but decoding the parameters in your head may require the use of illegal drugs.

For example, if you see a mangled name of '7SYNPSG5CORE11UTILITIES3CC6SYNCC11GETCCNAME_O7SYSTEM7STRINGI', you could intuitively see that it's probably this routine: 'SYNPSG.CORE.UTILITIES.CC.SYNCC.GETCCNAME(I)@SYSTEM.STRING'. 

But what about this one: '7SYNPSG5CORE11UTILITIES3CC6SYNCC11GETCCNAME_O7SYSTEM7STRINGSP0P1P2P39CARDTYPE'?  It’s the "same" overloaded routine, but it has a SYNPSG.CORE.UTILITIES.CC.CARDTYPE parameter instead of an integer parameter.  Similarly, if you saw '7SYNPSG5CORE11UTILITIES8WORKING9SHOWFORM_XO7SYSTEM7STRING', you could probably see that it's 'SYNPSG.CORE.UTILITIES.WORKING.SHOWFORM(@SYSTEM.STRING)'.  Now, what if you saw this '7SYNPSGCR1UTLTESWRKNGSHW9HTGB13'?   Well, it's surprisingly the same SHOWFORM method, but it's been mangled beyond recognition.  The term used here at Synergex is "crushed".  In fact, if you have a crushed name, it's basically impossible to determine the original method name. If the mangled name of the method is too long for the environment, the mangled name is crushed down to the maximum size permissible.  OpenVMS has a limit of 31 characters, 64-bit systems have a 188 character limit, and 32-bit systems have a 200 character limit. Actually, the limit is one character less, because we use the rule that if the name is exactly the maximum size, it must be a crushed name.  As the last 7 characters of a crushed name is a checksum, on OpenVMS you’re only left with 24 characters for a human “readable” name.

So how, exactly, does a mangled name become a crushed name? Well, characters are removed, one by one, until the name is exactly the correct length. First non-alphanumeric characters are removed, then vowels, then letters from the name of your first born child, then random letters based on the cycle of the moon, until you eventually get a name that fits. So, with only 31 characters for method ames, the OpenVMS users out there will have to become accustomed to seeing crushed (i.e. indecipherable) method names inside Shared Image Libraries.  If you need to create an OpenVMS Shared image library, I would recommend creating an object library, and using the make_share.com file to convert to a shared image library.  However, you may need to review the use of the MATCH qualifier on your shared image libraries, as method names can change with the modification of a parameter (or return) type. So changing a method to (for example) have an additional optional parameter will cause a new method name to be created.  Unless you rebuild your application to see (and use) the new name, you could find that the application starts giving “routine not found” errors.

You might think that not knowing the name of the routine would be a problem – it's not really, because the compiler has a consistent supply of the same high quality drugs, and given a constant method signature, will always generate the same crushed name.  So it really doesn't care that that your code said  "object.showform(1)", because it'll know that you really want to call the method '7SYNPSGCR1UTLTESWRKNGSHW9HTGB13' from your library.

For most developers out there, the actual name of the method inside a library is unimportant, but I though the more curious of you out there would be interested in this.


Don't miss a post!

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Recent Posts Tag Cloud Archives