Inside RSS

By Liu Rui

Nov. 2003

In this chapter, I will explain RSS and RSS API, as well as the considerations in RSS development.

What is RSS

In last chapter, we know that the Actions of a Process Oriented Interface need more expressive definitions and have more polymorphism features. So, I invented a special format string named Regular Statement String (RSS) in order to achieve these goals. Process Oriented Interface by RSS is accordingly named Regular Statement String Interface (RSSI). So what is RSS? RSS is a simple but powerful container to maintain keys and values used for an Action.

There are 5 special characters in RSS. However you can use a byte array made up of any characters as the value of a key because these special characters are escaped. Following are the special characters:

Let me explain multi-level key access. If a RSS has a key named "Spectacle", and the value of it is also a child RSS. Inside this child RSS, you can find a key named "China". If you want to get or set the value of key "China", you can use virtual key named "Spectacle~China". Furthermore, if the value of multi-level key "Spectacle~China" is also a RSS, and you can find a key named "North" inside it, then you can use multi-level key named "Spectacle~China~North" to access it. The rest may be deduced by analogy. You can disable the option of multi-level key access with RSS API.

Let me explain family key. If you want to get the value of a key named "PC|IBM" from the RSS, and there's not a key named "PC|IBM", instead there is a key named "PC" inside this RSS, the value of key "PC|IBM" will be the value of "PC". That is to say, the key "PC|IBM" and key "PC" are of the same key family "PC". And key "PC" is the parent key, key "PC|IBM" is the child key. For another example, if you want to get the value of a key named "Machine|Computer|PC|IBM", the system will check key "Machine|Computer|PC|IBM" at first. If it is empty, check "Machine|Computer|PC" at next time. If it is also empty, check "Machine|Computer". If it is still empty, check "Machine" at the last. You can disable the option of  family key with RSS API.
 

RSST and RSS API

You can use almost any programing language to build server and client applications with RSSI. A structure named RSST is the basal structure for RSS API. There's a RSS inside RSST. If a RSS C function returns a "ChrPtr" (an alias of "char *"), you should free it with function "ChrPtrFree" after using the ChrPtr. If a RSS API returns a C pointer, you should save the return data (a zero character ended C style string) before the next RSS function call. If a C function returns a pointer ("char *" or ChrPtr), the corresponding Java and COM function will return a byte array. In COM applications, you can use the inside method "toStr" or system function "StrConv" to convert the byte array to unicode string.

There are 7 categories of RSS API:

1. ChrPtr functions.
"ChrPtr" is only used in C language, it is an alias of "char *". "ChrPtr" is used to indicate that the function library has allocated memory for the pointer and user must free the memory later. Usually "ChrPtr" is used as the return value of a RSS API which wants to return a pointer. The reason for me to invent such a type is obvious. C language can return a pointer but not a real string or byte array. The "ChrPtr" is usually used as the return value representing a string or byte array allocated by the called party, the calling party should free the "ChrPtr" later. "ChrPtr" is useless in other languages such as Java and COM, because a string or byte array can be a return value in these languages.

ChrPtr functions for C:

void ChrPtrFree(ChrPtr value);
int ChrPtrLen(ChrPtr value);
Use function "ChrPtrFree" to free "ChrPtr". Use function "ChrPtrLen" to get the data length from a "ChrPtr".
 

2. RSS basic functions.
These functions are only used for validation.

RSS basic functions for C:

int RssValid(char *rss);
int RssValidKey(char *key);
RSS basic functions for Java (import rss.Rsst4j;):
public native int RssValid(byte[] rss);
public int RssValidKey(String key);
RSS basic functions for Visual Basic (Class Rsso):
Function RssValid(rss) As Long
Function RssValidKey(key As String) As Long
Function "RssValid" is used to test if a string is a valid RSS. Function "ValidKey" is used to test if a key name is valid. A non zero value indicate it is invalid. Character ASCII(96) is not a valid character in a key name.
 

3. RSST basic functions.
These functions are used to maintain RSST.

RSST basic functions for C:

void RsstInit (Rsst *rsst, int unit_size);
void RsstClose(Rsst *rsst);
int  RsstCheck(Rsst *rsst);

char * RsstGetRss0(Rsst *rsst);
ChrPtr RsstGetRss (Rsst *rsst);
void RsstSetRss(Rsst *rsst, char *rss);
void RsstSetRssNum(Rsst *rsst, char *rss1, int n);
void RsstClear(Rsst *rsst);

void RsstRssLoad(Rsst *rsst, char *filename);
void RsstRssDump(Rsst *rsst, char *filename);

int  RsstGetLen(Rsst *rsst);
int  RsstGetMaxLen(Rsst *rsst);
void RsstSetMaxLen(Rsst *rsst, int max_len);
int  RsstGetMaxValueLen(Rsst *rsst);
void RsstSetMaxValueLen(Rsst *rsst, int max_len);
int  RsstGetUnitSize(Rsst *rsst);
void RsstSetUnitSize(Rsst *rsst, int unit_size);
unsigned int RsstGetOption(Rsst *rsst, unsigned int opt);
void RsstSetOption(Rsst *rsst, unsigned int opt, unsigned int f);

int  RsstGetRtCode(Rsst *rsst);
void RsstSetRtCode(Rsst *rsst, int RtCode);
int  RsstGetStatus(Rsst *rsst);
void RsstSetStatus(Rsst *rsst, int status);

Rsst* RsstGetHandle(Rsst *rsst);
void  RsstSetHandle(Rsst *rsst, Rsst *handle);
Rsst* RsstNewHandle  (Rsst *rsst);
void  RsstCloseHandle(Rsst *rsst);

RSST basic functions for Java (import rss.Rsst4j;):
 public native int Check();
 public native byte[] getRss();
 public native void setRss(byte[] rss);
 public native void Clear();
 public void RssLoad(String filename);
 public void RssDump(String filename);
 public native int  getLen();
 public native int  getMaxLen();
 public native void setMaxLen(int max_len);
 public native int  getMaxValueLen();
 public native void setMaxValueLen(int max_len);
 public native int  getUnitSize();
 public native void setUnitSize(int unit_size);
 public native int  getOption(int opt);
 public native void setOption(int opt, int f);
 public native int  getRtCode();
 public native void setRtCode(int rtcode);
 public native int  getStatus();
 public native void setStatus(int status);
 public native int  getHandle();
 public native void putHandle(int handle);
 public native int  newHandle();
 public native void closeHandle();
RSST basic functions for Visual Basic (Class Rsso):
Function Check() As Long
Property rss As Variant
Sub Clear()
Sub RssLoad(FileName As String)
Sub RssDump(FileName As String)
Property Len As Long
Property MaxLen As Long
Property MaxValueLen As Long
Property UnitSize As Long
Property Option(opt As Long) As Long
Property RtCode As Long
Property Status As Long
Property Handle As Long
Function NewHandle() As Long
Sub CloseHandle()
Function "RsstInit" and "RsstClose" are used to create and destroy Rsst. Function "RsstCheck" is used to check if a pointer points a valid Rsst. Function "RsstSetRss" and "RsstSetRssNum" are used to set RSS to a RSST. The latter uses a pointer and a data length as arguments instead of a pointer to a zero ended string.  Function "RsstGetRss0" and "RsstGetRss" get RSS from Rsst. Function "RsstRssLoad" and "RsstRssDump" are used to load from or dump to a file. The other functions are used to get or set the parameters of Rsst. You can get/set Rss from/to Rsst, get Rss length from Rsst, get internal return code length from Rsst, get/set maximum value length from/to Rsst, get/set unit size from/to Rsst, get/set options from/to Rsst. The Unit size is allocation granularity for Rsst. You can find the default values in header file "rss.h".

4. Key/value functions.
These functions are used to deal with key and value pairs.

Key/value functions for C:

ChrPtr RsstKeyGet (Rsst *rsst, char *key);
char * RsstKeyGet0(Rsst *rsst, char *key);
ChrPtr RsstKeyGetM (Rsst *rsst, char *key, int no);
char * RsstKeyGetM0(Rsst *rsst, char *key, int no);

void  RsstKeyPut (Rsst *rsst, char *key, void *value, int len);
void  RsstKeyPut0(Rsst *rsst, char *key, char *value);
void RsstKeyPutM (Rsst *rsst, char *key, void *value, int len, int no);
void RsstKeyPutM0(Rsst *rsst, char *key, char *value, int no);

int  RsstKeyGetInteger (Rsst *rsst, char *key);
int  RsstKeyGetMInteger(Rsst *rsst, char *key, int no);
void RsstKeyPutInteger (Rsst *rsst, char *key, int  value);
void RsstKeyPutMInteger(Rsst *rsst, char *key, int  value, int no);

void RsstKeyCopy      (Rsst *rsst1, Rsst *rsst2, char *key);
void RsstKeyCopyFamily(Rsst *rsst1, Rsst *rsst2, char *key0);

void RsstKeyList(Rsst *rsst);
void RsstKeyListFamily(Rsst *rsst, char *key0);

Key/value functions for Java (import rss.Rsst4j;):
 public native byte[] KeyGet(byte[] key);
 public byte[] KeyGet(String key);
 public native byte[] KeyGetM(byte[] key, int no);
 public byte[] KeyGetM(String key, int no);
 public native void KeyPut(byte[] key, byte[] value);
 public void KeyPut(String key, byte[] value);
 public void KeyPut(String key, String value);
 public native void KeyPutM(byte[] key, byte[] value, int no);
 public void KeyPutM(String key, byte[] value, int no);
 public void KeyPutM(String key, String value, int no);
 public native int KeyGetInteger(byte[] key);
 public int KeyGetInteger(String key);
 public native int KeyGetMInteger(byte[] key, int no);
 public int KeyGetMInteger(String key, int no);
 public native void KeyPutInteger(byte[] key, int value);
 public void KeyPutInteger(String key, int value);
 public native void KeyPutMInteger(byte[] key, int value, int no);
 public void KeyPutMInteger(String key, int value, int no);
 public static native void KeyCopy(int rsst1, int rsst2, byte[] key);
 public static void KeyCopy(Rsst4j rsst1, Rsst4j rsst2, String key);
 public static native void KeyCopyFamily(int rsst1, int rsst2, byte[] key0);
 public static void KeyCopyFamily(Rsst4j rsst1, Rsst4j rsst2, String key0);
 public native void KeyList();
 public native void KeyListFamily(byte[] key0);
 public void KeyListFamily(String key0);
Key/value functions for Visual Basic (Class Rsso):
 Property Key(key As String)
 Property KeyM(key As String, No As Long)
 Property KeyInteger(key As String) As Long
 Property KeyMInteger(key As String, No As Long) As Long
 Sub KeyCopy(Rsso2 As Rsso, key As String)
 Sub KeyCopyFamily(Rsso2 As Rsso, Key0 As String)
 Sub KeyList()
 Sub KeyListFamily(Key0 As String)
Functions "*KeyPut*" are used to put the value of a key into the RSS. Functions "*KeyGet*" are used to get the value of a key from the RSS. Functions "*KeyPutM*" and "*KeyGetM*" are used to deal with a key with multivalues. Functions "*Key*Integer" are used to deal with a integer as the value of the key. This integer is usually defined as "long" in C, and it is defined "int" in Java. Functions "*Key*0" are used to deal with C style string (null character ended string) as the value of the key. Functions "*KeyGet*0" always return a normal pointer in C, and you must save the data before next RSS API. If you set  an empty string ("") as value to a key, the key is actually removed from the RSS.

Functions "*KeyCopy*" are used to copy key/value pairs from one RSS to another. Functions "*KeyList*" are used to list key names into the current Array.

There are some important agreements in RSS API for key and value issues:


5. Array functions.
If a key has multiple values, these values compose an Array. There's always an operational Array named current Array in a Rsst. Array functions are used for Array manipulation.

Array functions for C:

void RsstArrayFetch(Rsst *rsst, char *key);
void RsstArrayNew  (Rsst *rsst);
void RsstArraySave (Rsst *rsst, char *key);

ChrPtr RsstArrayGet (Rsst *rsst, int no);
char * RsstArrayGet0(Rsst *rsst, int no);

void RsstArrayPut (Rsst *rsst, char *value, int len, int no);
void RsstArrayPut0(Rsst *rsst, char *value, int no);

int  RsstArrayGetInteger(Rsst *rsst, int no);
void RsstArrayPutInteger(Rsst *rsst, int value, int no);

int RsstArrayItemNum(Rsst *rsst);
void RsstArrayRemoveItem(Rsst *rsst, int no);

Array  functions for Java (import rss.Rsst4j;):
 public native void ArrayFetch(byte[] key);
 public void ArrayFetch(String key);
 public native void ArrayNew();
 public native void ArraySave(byte[] key);
 public void ArraySave(String key);
 public native byte[] ArrayGet(int no);
 public native void ArrayPut(byte[] value, int no);
 public void ArrayPut(String value, int no);
 public native int ArrayGetInteger(int no);
 public native void ArrayPutInteger(int value, int no);
 public native int ArrayItemNum();
 public native void ArrayRemoveItem(int no);
Array  functions for Visual Basic (Class Rsso):
Sub ArrayFetch(key As String)
Sub ArrayNew()
Sub ArraySave(key As String)
Property Array(No As Long)
Property ArrayInteger(No As Long) As Long
Function ArrayItemNum() As Long
Sub ArrayRemoveItem(No As Long)
Function "RsstArrayFetch" is used to fetch the values of a key into the current Array. Function "RsstArrayNew" is used to create a new empty Array. Function "RsstArraySave" is used to save the current array as values to a key. The total length of the array plus the separators must not greater than the maximum value length of the RSST. Function "*ArrayGet*" and  "*ArrayPut*" are used to get or set the value of the current array. You can use function "RsstArrayItemNum" to get the total number of items of the current array, use function "RsstArrayRemoveItem" to remove the specified item from the current array.

6. Table functions.
These functions are simple application of Array functions. A Table is composed of a series of Arrays belonging to special keys based on the key name which is also the family name of these keys. You can get or set one row of the table from or to the current Array. You can only create or open one table within one Rsst at the same time.

Table functions for C:

void RsstTableCreate(Rsst *rsst, char *tbl_name);
void   RsstTableSave(Rsst *rsst, int col_num, int row_num, int start_row);
void   RsstTableOpen(Rsst *rsst, char *tbl_name);

int   RsstTableGetColNum(Rsst *rsst);
int   RsstTableGetRowNum(Rsst *rsst);
int RsstTableGetStartRow(Rsst *rsst);

void RsstTableFetchRow(Rsst *rsst, int row);
void   RsstTableNewRow(Rsst *rsst);
void  RsstTableSaveRow(Rsst *rsst, int row);

ChrPtr RsstTableGet (Rsst *rsst, int col);
char * RsstTableGet0(Rsst *rsst, int col);

void RsstTablePut (Rsst *rsst, char *value, int len, int col);
void RsstTablePut0(Rsst *rsst, char *value, int col);

int  RsstTableGetInteger(Rsst *rsst, int col);
void RsstTablePutInteger(Rsst *rsst, int  value, int col);

Table functions for Java (import rss.Rsst4j;):
 public native void TableCreate(byte[] tbl_name);
 public void TableCreate(String tbl_name);
 public native void TableSave(int col_num, int row_num, int start_row);
 public native void TableOpen(byte[] tbl_name);
 public void TableOpen(String tbl_name);
 public native int TableGetColNum();
 public native int TableGetRowNum();
 public native int TableGetStartRow();
 public native void TableFetchRow(int row);
 public native void TableNewRow();
 public native void TableSaveRow(int row);
 public native byte[] TableGet(int col);
 public native void TablePut(byte[] value, int col);
 public void TablePut(String value, int col);
 public native int TableGetInteger(int col);
 public native void TablePutInteger(int value, int col);
Table functions for Visual Basic (Class Rsso):
Sub TableCreate(tbl_name As String)
Sub TableSave(col_num As Long, row_num As Long, start_row As Long)
Sub TableOpen(tbl_name As String)
Property TableColNum As Long
Property TableRowNum As Long
Property TableStartRow As Long
Sub TableFetchRow(Row As Long)
Sub TableNewRow()
Sub TableSave(col_num As Long, row_num As Long, start_row As Long)
Property Table(Col As Long)
Property TableInteger(Col As Long) As Long
Function "TableCreate" is used to create a new table, Function "TableOpen" is used to open an existing table, Function "TableClose" is used to close the current table. You can use function "RsstTableGetColNum" to get the total number of columns of the current table, use function "TableGetRowNum" to get the total number of rows of the current table, use function "TableGetStartRow" to get the sequence number of the start row of the current table (the default value is 1). Function "TableFetchRow" is used to fetch the data in the columns of a specified row of the current table into the current array. Function "TableNewRow" is used to create an empty Array. Function "TableSaveRow" is used to save the current array to the specified row of the table. Function "*TableGet*" and  "*TablePut*" are used to get or put the value of the specified column of the current array.

7. RSSI functions.
These functions are convenient functions for Regular Statement String Interface (RSSI). Generally you can write these functions by yourself.

RSSI functions for C:

void StringFitIn(char *str, char *str0, int len);
int Locate(Rsst *rsst, char *dll_path, char *func_name);
void Unlocate(Rsst *rsst);
RSSI  functions for Java:
 public native int Locate(byte[] DllPath, byte[] FuncName);
 public int Locate(String DllPath, String FuncName);
 public native void CallRssi(byte[] Action);
 public void CallRssi(String Action);
RSSI  functions for Visual Basic:
Function Locate(DllPath As String, FuncName As String) As Long
Sub CallRssi(Action As String)
Function ToStr(Value As Variant) As String   (Class Rsso)
The standard RSSI only has one exported function as its entry, which has has two arguments. One argument is RSST, a standard structure holding RSS. The other argument is the name of the Action. For example, a RSSI entry named "MyRssi" will be declared in following forms:
For C:                void MyRssi(Rsst *rsst, char *action);
For Java:            public void MyRssi(Rsst4j rsst, String action);
For Visual Basic:Public Sub MyRssi(rsst As Long, action As String)
There are some string manipulation functions. C Function "StringFitIn" is used to copy string with a length limitation. COM function "ToStr" is more like the Visual Basic function "StrConv", which will translate a byte array to a Unicode string. In a language supporting COM, such as Visual Basic, the input argument as a value of key or the RSS is always defined as type VARIANT. The real internal type must be a byte array or BStr (a Unicode String). The return value as a value of key or the RSS is always defined as type VARIANT, too. But the real internal type is always a byte array. If you want to change the byte array into a Unicode string, you can use convenient function "ToStr" or Visual Basic function "StrConv".
 

Common Considerations

Register COM Automation Server "Rsscom.dll".
If you want to develop RSS or RSSI applications based on a COM automation server. You should register the COM automation server "Rsscom.dll" to your Windows system. In a DOS window, change to the lib directory containing "Rsscom.dll", use following command to register the dynamic library:
regsvr32 Rsscom.dll


Set Environment Variables Required by RSS
Suppose you have put the RSS into directory RSS_DIR. The header files of RSS can be found in RSS_DIR/include, The library file of RSS can be found in RSS_DIR/lib. The JNI and class path are also located in  RSS_DIR/lib. So you should add RSS_DIR/lib to environment variable "CLASSPATH" and "PATH" (for Windows) or LD_LIBRARY_PATH (for Linux/Solaris)..