Dimeric Software logo

Top Ten Reasons to use the Dimeric Software Utility Library

This document describes the top ten reasons to use DSUtil, including a full discussion of each point, with several examples along the way.


Contents

  1. DSMap / DSSet
  2. DSGenUtil / DSStringUtil / DSSortUtil
  3. DSList / DSPropertyBag
  4. DSMiniCalc
  5. DSStreams / DSTypedStreams
  6. DSDiffUtil / DSRSync
  7. DSSchedule / DSTimer
  8. DSSocket
  9. DSWebServer
  10. DSCheckSum / DSCRC / DSMD5


#1: DSMap / DSSet

These units implement associative arrays (maps), which are useful in a wide range of applications. The basic map object, IMap, manages a collection of key/value pairs (both of which are of variant type). Two specialized map types are also available. They contain values that are interfaced objects (IIntfMap) or regular TObject references (TObjectMap). The DSSet unit defines a related set of types (ISet, IIntfSet, and IObjectSet), which only contain the keys (no duplicates allowed, of course).

These map types have a number of features that make them extremely flexible:

  • Interfaced-based - the map objects are reference-counted for simpler memory management.
  • Thread-safe - each map object is (optionally) thread-safe.
  • Case sensitivity - each map object can honor or ignore case within strings (at your option).
  • Open hashing - the map objects use a hash table for improved performance.
You will find a surprising number of uses for these map objects -- before too long, you'll be wondering (as we are) how you ever managed to code without them!


#2: DSGenUtil / DSStringUtil / DSSortUtil

These three units are the foundation on which the DSUtil library is built.

DSGenUtil defines many generic routines and data types, including routines to compare variant values with or without case sensitivity.

DSStringUtil contains numerous string-handling routines. Some of our favorites include:

  • AddPaths - concatenates two or more strings, adding directory separators (slashes) between items, where necessary.
  • ParseCSV - parses a string containing multiple values; you specify the separator character(s) and the quote character(s), if any.
  • PathIsRelative - determines if a path is a relative path, in an OS-specific way.
  • Base64Encode / Base64Decode - this pair of routines implement the standard Base64 encoding algorithm.

DSSortUtil implements the QuickSort and BinarySearch algorithms.


#3: DSList / DSPropertyBag

DSList defines list container objects. These objects are interface- based, for improved memory management.

DSPropertyBag extends DSList by defining the IPropertyBag and IPropBagList interfaces. A property bag is a collection of named attributes. Usually the IPropertyBag interface provides a standardized (but limited) view of an object. The benefit of this scheme is that it allows your application to manipulate objects in a more dynamic fashion. For example, property bag lists work with MiniCalc for sorting, filtering, and aggregating features.

The full power of property bags is realized in Rinse and Ginkgo -- property bags are the basis on which Rinse's smartrecords and Ginkgo's business objects are built. In a nutshell, the IPropertyBag interface abstracts the smartrecords and business objects defined in an application.


#4: DSMiniCalc

MiniCalc is a powerful and flexible expression evaluator. You can use MiniCalc to make your applications more dynamic. For example, a MiniCalc expression can be used to filter a property bag list. MiniCalc is also used to implement calculated smartrecord properties. DSP uses MiniCalc to implement the <%@ if ... %> directive. You can use MiniCalc in your own applications whenever you need a simple expression parser/evaluator. You can even define new functions to extend MiniCalc!

For more information on MiniCalc, see the MiniCalc Reference (PDF) or the DSUtil Online Documentation.


#5: DSStreams / DSTypedStreams

These two units implement an input/output streams library that is superior to the VCL's TStream framework. Specifically, they address the following drawbacks of TStream:

  • It's a non-interfaced class.
  • It only works with untyped binary data.
  • It assumes that you can both read and write to the stream.
  • It assumes that streams have a size and position, and you can reposition and resize the stream.

Our stream library offers the following advantages:

  • Interface-Based - Because DSStreams are interfaces, they are memory-managed and are, therefore, simpler to use.
  • Fine-Grained - The basic DSStreams interfaces are more fine-grained than TStream. There are many cases where TStream is too broad of an abstraction. For example, if you have a THandleStream representing the console, what should the Size method return?
  • Layered Design - Additional functionality is added in layers. For example, if you would like to buffer an underlying stream (such as a file stream), you add the buffered layer on top of the underlying stream. The buffered layer can be added to any underlying stream, so it only has to be coded once and has a consistent interface across underlying stream implementations. On the other hand, if you don't need buffering, then it isn't forced on you. You simply leave off that layer.
  • Greater functionality - The built-in streams provide raw binary input and output to files, memory, strings and "handles" (such as the console) and resources. DSStreams provides all of these basic binary streams, and adds socket streams. DSSStreams also adds functionality in layered classes and interfaces, one or more of which can be added on top of any of the underlying streams, including: buffering, text printing and "put-back".
  • Object Persistence - DSTypedStreams provides for better binary data streaming, providing specific methods for streaming basic data types like string, Integer, Boolean, Double and TDateTime. It also provides for streaming a network of objects. For example, IDataSet and IMap can be streamed. If there are objects contained in the IMap then they can be streamed as well.

For more information on DSStreams, please see the DSStreams Tutorial. You can also view the DSUtil Online Documentation.


#6: DSDiffUtil / DSRSync

DSDiffUtil implements the standard line-based textual difference (diff) algorithm. The basic algorithm is described in "An O(ND) Difference Algorithm and its Variations", Eugene W. Myers, Algorithmica Vol. 1 No. 2, 1986, pp. 251--266; and in "A File Comparison Program", Webb Miller and Eugene W. Myers, Software--Practice and Experience Vol. 15 No. 11, 1985, pp. 1025--1040.

DSRSync implements the rsync algorithm, which is described in "Efficient Algorithms for Sorting and Synchronization", Andrew Tridgell. It is essentially a kind of binary difference algorithm that allows you to synchronize one version of a file with another version of the same file on a remote computer, sending a minimal amount of data between the two machines. Basically, an rsync client will compute a set of checksums on a local file and transmit those to the remote rsync server. The rsync server uses those checksums and its version of the file to compute a binary diff of its file -- essentially a set of instructions and snippets of data -- that is transmitted back to the rsync client, which uses the diff to reconstruct the server's version of the file from its version of the file.


#7: DSSchedule / DSTimer

DSSchedule implements a task scheduler. Programs often have periodic background tasks that they would like to run on a background thread. This unit defines the ITask interface, which a program can implement. It also defines the Scheduler singleton, which can be used to schedule ITask instances to be executed on a background thread.

DSTimer implements a platform-independent high-resolution timer you can use to time execution of parts of your code, or anything else you'd like to time.


#8: DSSocket

DSSocketDefines the ISocket, IServerSocket, and IThreadedServerSocket objects, which allow your programs to communicate via TCP/IP as a client or server. One of the nicest features of DSSocket is that it uses the DSStreams abstractions. A socket defines an input stream and an output stream. This makes socket streams look just like other streams your application might use (file streams, console streams, streams connected to pipes to other programs, string streams, memory streams, etc.). DSP and Rinse use the DSSocket abstractions.


#9: DSWebServer

DSWebServer defines the IWebServer interface, based on the IThreadedSocketServer, which is a fully functional web-server. It allows you to easily build custom web-server applications. It provides handy abstractions such as IWebRequest, IWebResponse, and IWebQuery. DSP uses this unit for stand-alone web applications, but it is useful in other situations as well.


#10: DSCheckSum / DSCRC / DSMD5

DSCRC and DSMD5 provide implementations of the CRC (Cyclic-Redundancy-Check) and MD5 (Message-Digest v5) hashing algorithms. There are 32-bit, 64-bit and 128-bit CRC implementations. MD5 is a 128-bit hashing algorithm. Both of these units rely on the abstractions defined in DSCheckSum, so hashing algorithms are interchangable.

CheckSums, or hashes, can be computed on raw buffers, string, TStreams, DSStream objects, and files. In addition, there are "filter streams" that compute a checksum (such as 64-bit CRC or 128-bit MD5) as data is written to or read from an underlying stream. This makes it easy to compute the checksum of data as it is written to a file, or across the network.

   Privacy Policy © 2002 Dimeric LLC. All Rights Reserved. Contact Us   
> Powered by VDB, DSP and Rinse <