Just because the code works doesn't mean that I am satisfied with the implementation.
Here is one solution that I devised (I'm still looking for others):
/// linefeed-delimited text
Class My.datatype.textLines Extends %String [ ClassType = datatype, ClientDataType =
CHARACTERSTREAM, OdbcType = LONGVARCHAR, ProcedureBlock ]
{
/// req: property value <var>%val</var>
/// action: Strips out unneeded delimiters from %val, invokes NormalizeExtra
/// method on %val, and truncates %val to <a href="#MAXLEN">MAXLEN</a> characters.
ClassMethod Normalize(%val As %String) As %String [ CodeMode = objectgenerator ]
{
s zpn=$p($li(%compiledmethod.%Oid(),1),"|",3) ;name of property
if zpn="Normalize" s zpn="" ;true when compiling this datatype's class
w " Generating methods ",zpn,"Normalize and ",zpn,"NormalizeExtra... "
d %code.WriteLine(" if %val[$c(13,10) {s %val=$tr(%val,$c(13))} ;remove CRs")
d %code.WriteLine(" elseif %val[$c(13) {s %val=$tr(%val,$c(13),$c(10))}
;change CRs to LFs")
d %code.WriteLine(" f q:$a(%val)'=10 s $e(%val)="""" ;remove leading LFs")
d %code.WriteLine(" f s f=$l(%val) q:$a(%val,f)'=10 s $e(%val,f)=""""
;remove trailing LFs")
d %code.WriteLine(" d z"_zpn_"NormalizeExtra()") k zpn
if %parameter("TRUNCATE"),%parameter("MAXLEN")'="" {d %code.WriteLine(" q
$e(%val,1,"_+%parameter("MAXLEN")_") ;truncated to MAXLEN")}
else {d %code.WriteLine(" q %val")}
q $$$OK
}
/// This property method is called from the property's Normalize method to
/// allow additional transformations without overriding the inherited method.
ClassMethod NormalizeExtra() [ CodeMode = objectgenerator ]
{
d %code.WriteLine(" //Put code here to transform %val")
d %code.WriteLine(" q")
q $$$OK
}
}
I welcome all comments and suggestions.