Skip to main content

Sasa v0.12.0 Released

Just a quick announcement that Sasa v0.12.0 was just released. You can obtain the individual assemblies via Nuget, or the whole set from Sourceforge. The docs are available as a CHM file on sourceforge, or online here.


This release includes a few fixes, the most prominent of which are in the HTML parser and the parsing of MIME linked resources.

Note that since v0.11.0, some extension methods on MailMessage have been deprecated due to Microsoft's recommended usage guidelines. The headers those extension methods accessed are overwritten whenever a MailMessage is sent via SmtpClient, so it's better not to rely on them.

A new feature is the sasametal utility, which is basically a wrapper around sqlmetal that normalizes some of the bizarre property names from sqlmetal into more CLR friendly names. A forthcoming blog post will cover the use of this tool.

Other new features include first-class references, and first-class slots. These are currently in the core Sasa assembly, but may be moved to a satellite assembly in the future if they don't see enough use.

Other changes cover backend work that simply expands the power of pre-existing features, like a more efficient and reusable PIC dispatch, now supporting up to 16 type arguments. There's also a new assembly, Sasa.Partial, which provides partial application overloads for System.Func and System.Action, up to 10 arguments.


 * added Strings.RemoveLast extension which is a convenient way of removing
   characters from the end of a StringBuilder.
 * made MailMessage parsing stricter to conform to Microsoft's usage
   recommendations for MailMessage
 * deprecated certain header parsers, like ContentType() and
   ContentTransferEncoding(), since .NET strips these when sending mail anyway
 * HTML views are no longer unpacked into MailMessage.Body since docs say this
   property is reserved for plain/text
 * QuotedPrintable decoding is now more permissive to encoding errors
 * merged sasametal tool that normalizes the output of sqlmetal
 * ilrewrite now only outputs pdb file if an input pdb was available
 * adapted MailMessage parsing code to .NET 4.0 (mainly ReplyToList)
 * added text encoding extension methods to ContentType
 * added extension method for filtering a sequence of attachments by media type 
 * added extension method for extracting attachment data as a string using the
   encapsulated encoding
 * added extension method to overwrite an attachment's data using string
   content using the encapsulated encoding
 * Strings.SliceEquals now has an overload accepting a StringComparison
   parameter to customize the comparison type performed
 * Tokenizer now takes an optional parameter for the type of string
 * HTML parser now performs case-insensitive comparisons
 * now correctly parsing alternate view linked resources
 * added implementations for first-class references to all core CLR types
 * added implementations for first-class slots to all core CLR types
 * PIC now based on a concurrency-safe map that looks up a tuple of System.Type
 * PIC and CLR expression compiler can now efficiently dispatch up to 16 params
 * Sasa.Dynamics simplified by switch to new PIC
 * added .NET 3.5-specific overloads of System.Func and System.Action for up to
   16 params
 * added Sasa.Partial assembly, which provides partial application overloads
   for System.Func and System.Action for up to 10 params
 * fixed a couple of bugs in Sasa.Dynamics codegen


Popular posts from this blog

async.h - asynchronous, stackless subroutines in C

The async/await idiom is becoming increasingly popular. The first widely used language to include it was C#, and it has now spread into JavaScript and Rust. Now C/C++ programmers don't have to feel left out, because async.h is a header-only library that brings async/await to C! Features: It's 100% portable C. It requires very little state (2 bytes). It's not dependent on an OS. It's a bit simpler to understand than protothreads because the async state is caller-saved rather than callee-saved. #include "async.h" struct async pt; struct timer timer; async example(struct async *pt) { async_begin(pt); while(1) { if(initiate_io()) { timer_start(&timer); await(io_completed() || timer_expired(&timer)); read_data(); } } async_end; } This library is basically a modified version of the idioms found in the Protothreads library by Adam Dunkels, so it's not truly ground bre

Building a Query DSL in C#

I recently built a REST API prototype where one of the endpoints accepted a string representing a filter to apply to a set of results. For instance, for entities with named properties "Foo" and "Bar", a string like "(Foo = 'some string') or (Bar > 99)" would filter out the results where either Bar is less than or equal to 99, or Foo is not "some string". This would translate pretty straightforwardly into a SQL query, but as a masochist I was set on using Google Datastore as the backend, which unfortunately has a limited filtering API : It does not support disjunctions, ie. "OR" clauses. It does not support filtering using inequalities on more than one property. It does not support a not-equal operation. So in this post, I will describe the design which achieves the following goals: A backend-agnostic querying API supporting arbitrary clauses, conjunctions ("AND"), and disjunctions ("OR"). Implemen

Simple, Extensible IoC in C#

I just committed the core of a simple dependency injection container to a standalone assembly, Sasa.IoC . The interface is pretty straightforward: public static class Dependency { // static, type-indexed operations public static T Resolve<T>(); public static void Register<T>(Func<T> create) public static void Register<TInterface, TRegistrant>() where TRegistrant : TInterface, new() // dynamic, runtime type operations public static object Resolve(Type registrant); public static void Register(Type publicInterface, Type registrant, params Type[] dependencies) } If you were ever curious about IoC, the Dependency class is only about 100 lines of code. You can even skip the dynamic operations and it's only ~50 lines of code. The dynamic operations then just use reflection to invoke the typed operations. Dependency uses static generic fields, so resolution is pretty much just a field access + invoking a