Not so Swift

When tasked with the job of replacing buggy Swift code with release-quality Objective-C (mostly because I am more familiar with the latter), I find myself wondering why Swift is so popular.

Consider the following pair of code lines. The top line is Objective-C and the line below it is the equivalent operation in Swift (the operation pictured is the common task of pulling some user data from local device storage):

The similarities in the two versions of the operation are highlighted.

When I look at the Swift equivalent, I see a slightly re-arranged version of the operation that was specified in Objective-C.

Launch, Monitor, and Terminate Linux Daemons

If you have a daemon listening on port 6666,

connector = 
 accept(
  listener, 
  (struct sockaddr*)&client, 
  (socklen_t*)&acceptor);

the following commands will be helpful for managing it.

Launch:

nohup ./daemon > /dev/null 2>&1 &

Monitor (use sudo if not root):

netstat -lpn |grep :6666

Above call returns (note the returned PID):

tcp 0 0 0.0.0.0:6666 0.0.0.0:* LISTEN PID/daemon

Terminate:

kill -9 PID

Circular Queue Class

While developing a streaming audio application, I found the need for a fast and reliable buffering mechanism. I developed a Queue Class and used it as a buffer, stuffing blocks of data in on one thread and pulling them out on another. The quality of the audio was greatly improved by this buffering mechanism. But I wanted something better, something that would perform as few conditional and allocation operations as possible. So I developed this circular queue class.

The number of elements in the queue is restricted to powers of two. Keeping track of front, back, overflow, and underflow requires only two internal member variables, one of which is incremented on every enqueue operation, the other is incremented on every dequeue operation (wrapping around to zero is expected and supported behavior). Applying a bitmask to one of these variables reduces the actual number to an “index” of the front or back of the queue, respectively. The bitmask value is calculated from the “size” (number of elements) specified during initialization. Allocation of the array of elements is also performed during initialization.

The only condition checked during an enqueue operation is an overflow test. The only condition checked during a dequeue operation is an underflow test. There is no “is initialized” test in these functions, so be sure to initialize an instance before using it!

Cross-platform permutations of the source (GitHub):
https://github.com/UniversalProgrammingOrganization/upo-lib/blob/master/upo-lib/CircularQueue.h
https://github.com/UniversalProgrammingOrganization/upo-lib/blob/master/upo-lib/CircularQueue.cpp

#define O void // for Object pointers (O*)
#define Z NULL // shorthand for NULL

class CQ // a circular queue class
{
public:
    DWORD m_dwNQs; // total number of enqueue operations
    DWORD m_dwDQs; // total number of dequeue operations
    DWORD m_dwIM;  // Index Mask - a bitmask
    O** m_ppE;     // pointer to array of elements

    CQ()
    {
        m_ppE = Z;
    };

    ~CQ()
    {
        Reset();
    };

    void Reset()
    {
        // free array of elements:
        if (m_ppE)
            delete [] m_ppE;
 
        m_dwNQs = 0;
        m_dwDQs = 0;
        m_dwIM = 0;
        m_ppE = Z;
    }
 
    bool Init(
        DWORD dwSize)
    {
        // allow object re-use:
        Reset();
 
        // verify size is not zero:
        if (dwSize == 0)
            return false;
 
        // calculate the bit mask:
        m_dwIM = dwSize - 1;
 
        // verify size is a power of 2:
        if (dwSize & (m_dwIM))
            return false;
 
        // allocate the queue elements:
        m_ppE = new O*[dwSize];
 
        // will return true only if all of the above succeeded:
        return (m_ppE != Z);
    };
 
    // enqueue function:
    O* NQ(O* pO)
    {
        // check for overflow:
        if (Size() > m_dwIM)
            return Z;
 
        // calculate the enqueue index:
        DWORD dwEi = (m_dwNQs & m_dwIM);
 
        // set the element value:
        *(m_ppE + dwEi) = pO;
 
        // increment enqueue count:
        m_dwNQs++;
 
        return pO;
    };
 
    // dequeue function:
    O* DQ()
    {
        // get the element value:
        O* pO = Peek();
 
        // increment dequeue count (if no peek error):
        if (pO != Z)
            m_dwDQs++;
 
        return pO;
    };
 
    O* Peek()
    {
        // check for underflow:
        if (Size() == 0)
            return Z;
 
        // calculate the dequeue index:
        DWORD dwDi = (m_dwDQs & m_dwIM);

        // return the element value:
        return *(m_ppE + dwDi);
    };
 
    // returns the distance between m_dwDQs and m_dwNQs
    // (the size of the actual queue contents):
    DWORD Size()
    {
        if (m_dwDQs < m_dwNQs)
            return (m_dwNQs - m_dwDQs);
        else
            return (m_dwDQs - m_dwNQs);
    };
};

The above “Size()” function would look shorter if it was constructed like this:

    DWORD Size()
    {
      return abs(m_dwDQs - m_dwNQs);
    };

But the “abs()” function is typically implemented like this:

    int abs(int n)
    {
        if (n >= 0)
            return n;
        else
            return -n;
    };

Data Organizer

The Data Organizer application was created to save a user’s time by providing a hierarchical scratch-pad that allows the creation and organization of textual data, without the need for repeating the steps of creating folders and files or editing and saving those files in a text editor window. It automatically saves the content of the text window when switching nodes (control-S can also be used to save the current content). The standard “edit” key combinations are also supported, and always apply to the text window (rather than the tree control): Select All (control-A), Copy (control-C), and Paste (control-V). Selecting a word with a double-click will automatically disregard a trailing space character, so that passwords or usernames can be pasted from the clipboard without errors.

The Data Organizer application uses a folder named “data” to store all data (created in the folder where the EXE is installed), arranging it in a tree of folders containing text files:

This design makes it possible to safeguard the contents of the “data” folder tree using a source control system.

The Data Organizer application supports the renaming of nodes, which changes the underlying folder names:

Feel free to Download and try Data Organizer out.

The Source Code is also available if you prefer reviewing the source before building and using Data Organizer.

Happy organizing!

 

Hexagonal Buttons

When creating the Musician’s Calculator iPhone app for ToruSound, I wanted the buttons to be more ergonomic and also wanted to be able to render them in patterns that made sense with regard to the underlying science, such as a “circle” of fifths surrounding “triangular” base-10 digit buttons, as well as piano-style buttons for producing actual musical pitches.

The source code for the hexagonal buttons (which is compatible with the Xcode interface designer) is up on GitHub:

https://github.com/DanielLewisRandall/iOpenCalculator/blob/master/OpenCalculator/OpenCalculator/UIHexButton.h

https://github.com/DanielLewisRandall/iOpenCalculator/blob/master/OpenCalculator/OpenCalculator/UIHexButton.m

WCF Service Schema Design

For a landmark location WCF service, I wanted to create a method, “GetLandmarks(lat, lon, radius)”, that returned a list of complex types to the caller. The prior art on this was very scattered at the time of this writing, so I have unified my findings in this post for future reference.

This is the schema definition for the “Landmark” complex type:

This is the schema definition for the “Landmarks” type, which is nothing more than a list of “Landmark” items:

This is the schema definition for the response message for the GetLandmarks() method call:

Purify That XML

Processing XML using XPATH or XSLT is much more difficult when the XML contains namespaces; sometimes the namespaces are a very necessary part of the data structure and should be left intact; it is when namespaces are used arbitrarily (and contribute nothing to the underlying data structure) that they become a problem. For the latter case, I have developed this XML purifier routine, which processes an XML string prior to parsing, translating, or even viewing the content. Even the presence of only the “default” namespace is enough to break MSXML XPATH parsing as well as MSXML XSLT transformations or using the .NET XslCompiledTransform class.

using System;
using System.Text.RegularExpressions;
namespace Utilities
{
    public class XmlPurifier
    {
        public static string Purify(string input)
        {
            string output = input;
             
            //
            // remove all "xmlns" attribute assignments:
            //
 
            string xmlns = "(?i)xmlns\\s*=\\s*\\\"[^\\s]*\\\"";
             
            Regex regex = new Regex(xmlns);
 
            MatchCollection nsCollection = regex.Matches(output);
             
            foreach (Match match in nsCollection)
            {
                output = output.Replace(match.Value, String.Empty); 
            }                      
             
            //
            // find and remove all namespace references:
            //
 
            string nsr = "(?i)xmlns:(([a-z0-9_]+))\\s*=\\s*\\\"[^\\s]*\\\"";
             
            Regex nsrx = new Regex(nsr);
 
            MatchCollection nsrCollection = nsrx.Matches(output);
 
            foreach (Match match in nsrCollection)
            {
                // remove the namespace reference:
                output = output.Replace(match.Value, String.Empty);
 
                // remove all namespace prefixes:
                output = output.Replace(match.Groups[1].ToString() + ":", String.Empty);
            }
             
            return output;
        }
    }
}

Stored Procedure Design

When creating stored procedures, I like to use in and out parameters that report possible internal problems. I also like to design a simple “create record if it does not exist and return ID” procedure:

USE [THE_DATABASE]
 
GO
 
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[ReadOrAddUser]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[ReadOrAddUser]
GO
 
SET ANSI_NULLS ON
GO
 
SET QUOTED_IDENTIFIER ON
GO
 
CREATE PROCEDURE [dbo].[ReadOrAddUser]
(
 @in_GroupID integer,
 @in_UserName nvarchar(50),
 @in_UserData nvarchar(MAX),
 @out_UserID integer OUTPUT,
 @out_error_code integer OUTPUT,
 @out_error_message nvarchar(2000) OUTPUT
)
AS
BEGIN
 
 SET NOCOUNT ON
 
 -- populate standard variables
 SELECT @out_error_code = 0,
 @out_error_message = NULL
  
 Select @out_UserID = [ID]
 from [dbo].[Users]
 where [UserName] = @in_UserName AND [GroupID] = @in_GroupID
  
 BEGIN TRANSACTION
 
 BEGIN TRY
 
 -- if Group User is not in table, insert. Return ID in all cases.
 IF ( @out_UserID is null )
 BEGIN
 
 -- insert into table
 INSERT INTO dbo.Users
 (
 GroupID,
 UserName,
 UserData
 )
 VALUES
 (
 @in_GroupID,
 @in_UserName,
 @in_UserData
 )
 
 -- set parameter to value of new record
 SET @out_UserID = SCOPE_IDENTITY()
 
 END
 
 -- else update the data and return the ID.
 ELSE
 BEGIN
 UPDATE [dbo].[Users]
 SET [UserData] = @in_UserData
 WHERE [ID] = @out_UserID
 END
 
 END TRY
 BEGIN CATCH
 
 SET @out_UserID = NULL
 SET @out_error_code = 5000
 SET @out_error_message = ERROR_PROCEDURE() + ': ' + CAST(ERROR_NUMBER() AS VARCHAR(10)) + ' (line ' + CAST(ERROR_LINE() AS VARCHAR(10)) + ') ' + ERROR_MESSAGE()
  
 ROLLBACK TRANSACTION
 RETURN 1
 
 END CATCH
 
 COMMIT TRANSACTION
 
 RETURN 0
 
END
 
GO

C# code for calling the above procedure:

private const string OUT_ERROR_CODE = "@out_error_code";
private const string OUT_ERROR_MESSAGE = "@out_error_message";
 
public int ReadOrAddUser(
    string userName,
    string userData,
    int GroupID)
{
    SqlConnection con = new SqlConnection(_connString);
    SqlCommand cmd = new SqlCommand("ReadOrAddUser", con);
 
    addInParam(ref cmd, "@in_UserName", userName);
 
    addInParam(ref cmd, "@in_UserData", userData);
 
    addInParam(ref cmd, "@in_GroupID", GroupID);
 
    return ExecuteProcedure(ref con, ref cmd, "@out_UserID");
}
 
 
// supporting code:
 
public void addInParam(
    ref SqlCommand cmd,
    string name,
    string value)
{
    cmd.Parameters.Add(name, SqlDbType.Text);
    cmd.Parameters[name].Value = value;
}
 
public void addInParam(
    ref SqlCommand cmd,
    string name,
    int value)
{
    cmd.Parameters.Add(name, SqlDbType.Int);
    cmd.Parameters[name].Value = value;
}
 
public void addOutIntParam(
    ref SqlCommand cmd,
    string name)
{
    cmd.Parameters.Add(new SqlParameter(name, SqlDbType.Int));
    cmd.Parameters[name].Direction = ParameterDirection.Output;
}
 
public int ExecuteProcedure(
        ref SqlConnection con,
        ref SqlCommand cmd,
        string outVarName = "")
{
    bool getResult = (outVarName.Length > 0);
 
    int result = 0;
 
    cmd.CommandType = CommandType.StoredProcedure;
 
    if (getResult)
    {
        addOutIntParam(ref cmd, outVarName);
    }
 
    addOutIntParam(ref cmd, OUT_ERROR_CODE);
 
    cmd.Parameters.Add(new SqlParameter(OUT_ERROR_MESSAGE, SqlDbType.NChar));
    cmd.Parameters[OUT_ERROR_MESSAGE].Direction = ParameterDirection.Output;
    cmd.Parameters[OUT_ERROR_MESSAGE].Size = 2000;
 
    con.Open();
 
    cmd.ExecuteNonQuery();
 
    int code = (int)cmd.Parameters[OUT_ERROR_CODE].Value;
 
    if (code != 0)
    {
        string message = (string)cmd.Parameters[OUT_ERROR_MESSAGE].Value;
 
        throw new Exception(message);
    }
    else if (getResult)
    {
        result = (int)cmd.Parameters[outVarName].Value;
    }
 
    con.Close();
 
    return result;
}

XSL Translation: Powerful, Misunderstood, and Mislabeled

Back in the year 1999, XSL and CSS (both dubbed “stylesheet languages”) were unofficial competitors. CSS ended up becoming the “winner”. This was actually a good thing for XSL, which was considered to be more powerful and complex than CSS.
CSS is all well and good for the applying of styles to online content (such as Web pages), but the true power of XSL lies in its ability to translate XML into any other text-based format. XSL can be used completely outside of the context of browsers and Web pages; all you need is a good XSLT processor that you can use in your code (sample code provided below).

An important thing to note, at this point, is that there will be no discussion of any “browser” or “HTML” in this post, nor will there be any discussion of behavior that one would describe as “stylesheet-like”. Instead, the true power of XSL translation will be illustrated.

Example: Converting XML Into CSV Text

This example will illustrate conversion of XML data into CSV (Comma Separated Value, an input format that is supported by Excel, for example).

Here is the input XML:

<?xml version="1.0" encoding="utf-8"?>
<DataTable name="The Data">
 <Row name="Header Row">
  <Column name="Column 1" />
  <Column name="Column 2" />
  <Column name="Column 3" />
 </Row>
 <Row name="Row 1">
  <Column value="Alpha"/>
  <Column value="Bravo"/>
  <Column value="Charlie"/>
 </Row>
 <Row name="Row 2">
  <Column value="Delta"/>
  <Column value="Echo"/>
  <Column value="Foxtrot"/>
 </Row>
 <Row name="Row 3">
  <Column value="Golf"/>
  <Column value="Hotel"/>
  <Column value="India"/>
 </Row>
</DataTable>

Here is the desired spreadsheet layout:

Column 1 Column 2 Column 3
Alpha Bravo Charlie
Delta Echo Foxtrot
Golf Hotel India

 

Here is the XSL translation code (more information on XSLT available here):

<?xml version='1.0'?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output
    method="text"
    omit-xml-declaration="yes"/>

    <xsl:variable
    name="dataTableName"
    select="/DataTable/@name"/>

    <xsl:template match="/DataTable">
        <xsl:choose>
            <xsl:when test="$dataTableName">
                Data Table Name: "<xsl:value-of select="$dataTableName"/>"&#13;&#10;
            </xsl:when>
            <xsl:otherwise>Data Table Name: (no name)&#13;&#10;</xsl:otherwise>
        </xsl:choose>
        <xsl:apply-templates select="Row"/>
    </xsl:template>

    <xsl:template match="Row">
        <xsl:if test="@name">
            <xsl:value-of select="@name"/>,
        </xsl:if>
        <xsl:apply-templates select="Column"/>
        <!--  add a line break (0D0A) between rows -->
        <xsl:if test="following-sibling::Row">&#13;&#10;</xsl:if>
    </xsl:template>

    <xsl:template match="Column">
        <xsl:choose>
            <xsl:when test="@name">
                <xsl:value-of select="@name"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:if test="@value">
                    <xsl:value-of select="@value"/>
                </xsl:if>
            </xsl:otherwise>
        </xsl:choose>
        <!--  add a comma between columns -->
        <xsl:if test="following-sibling::Column">,</xsl:if>
    </xsl:template>

</xsl:stylesheet>

Here is C++ source code that will perform the translation (using MSXML):

#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#import <msxml3.dll> named_guids
using namespace MSXML2;

int main(int argc, char* argv[])
{
   CoInitialize(NULL);	

   variant_t vResult;
   void *output  = NULL;
   MSXML2::IXMLDOMDocumentPtr pXml(MSXML2::CLSID_DOMDocument);
   MSXML2::IXMLDOMDocumentPtr pXslt(CLSID_FreeThreadedDOMDocument);
   IXSLTemplatePtr pTemplate(CLSID_XSLTemplate);
   IXSLProcessorPtr pProcessor;
   IStream *pOutStream;

   try
   {
      vResult = pXml->load(_bstr_t("input.xml"));
      vResult = pXslt->load(_bstr_t("translate.xslt"));
   }
   catch(_com_error &e)
   {
      printf(
         "Error loading XML/XSL: %s\n",
         (const char*)_bstr_t(e.Description()));
      exit(-1);
   }

   try
   {
      vResult = pTemplate->putref_stylesheet(pXslt);
      pProcessor = pTemplate->createProcessor();
   }
   catch(_com_error &e)
   {
      printf(
         "Error initializing XSL translator: %s\n",
         (const char*)_bstr_t(e.Description()));
      exit(-1);
   }

   CreateStreamOnHGlobal(NULL,TRUE,&pOutStream);
   pProcessor->put_output(_variant_t(pOutStream));

   vResult = pProcessor->put_input(_variant_t((IUnknown*)pXml));
   pProcessor->transform();

   HGLOBAL hg = NULL;
   pOutStream->Write((void const*)"\0",1,0);
   GetHGlobalFromStream(pOutStream,&hg);
   output = GlobalLock(hg);
   // advance past (and ignore) BOM:
   printf("%S",(((const char*)(output)) + 2));
   GlobalUnlock(hg);

   pXml.Release();
   pXslt.Release();
   pTemplate.Release();
   pProcessor.Release();

   CoUninitialize();

   return 0;
(original source available here)

Here is the command-line to use (with the above program):

convert > output.csv

Here is an example of the output:

Data Table Name: "The Data"
Header Row,Column 1,Column 2,Column 3
Row 1,Alpha,Bravo,Charlie
Row 2,Delta,Echo,Foxtrot
Row 3,Golf,Hotel,India

Happy translating!