<> <> <> <> <> <> DIRECTORY Ascii USING [Lower, Upper], Convert USING [AppendCard, AppendInt, Error, IntFromRope], NSString, RefText USING [Append, AppendChar, Compare, Length, TrustTextAsRope], Rope USING [Compare, Index, ROPE, Substr]; NSStringImpl: CEDAR PROGRAM IMPORTS Ascii, Convert, RefText, Rope EXPORTS NSString = BEGIN OPEN NSString; <<-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---->> <> <<-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---->> ROPE: TYPE ~ Rope.ROPE; <> <<>> <> <> <<>> <> <> <> <<>> <> <> <> <<>> <> <<>> <> <<>> <<-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---->> <> <<-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---->> <<>> <> <> <<-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---->> <> <<-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---->> <> LogicalLength: PUBLIC PROC [s: String] RETURNS [CARDINAL] = {RETURN [RefText.Length[s]]}; WordsForString: PUBLIC PROC [bytes: CARDINAL] RETURNS [CARDINAL] = {RETURN[bytes/2+1]}; AppendCharacter: PUBLIC PROC [to: String, from: Character] RETURNS [String] = { RETURN[RefText.AppendChar[to, LOOPHOLE[from.code]]]}; AppendString: PUBLIC PROC [to: String, from: String] RETURNS [String] = { RETURN[RefText.Append[to, from]]}; AppendSubString: PUBLIC PROC [to: String, from: SubString] RETURNS [String] = BEGIN wk: String _ to; IF from = NIL OR from.length = 0 OR from.base = NIL OR from.base.length = 0 THEN RETURN [to]; IF from.offset > from.base.length THEN RETURN[to]; IF wk.length + from.length > wk.maxLength THEN wk _ NEW[TEXT[wk.length + from.length]]; FOR i: CARDINAL IN [from.offset .. from.offset + from.length) DO wk[i] _ from.base[from.offset + i]; ENDLOOP; RETURN[wk]; END; CompareStrings: PUBLIC PROC [s1, s2: String, ignoreCase: BOOLEAN _ TRUE] RETURNS [Relation] = { RETURN[RefText.Compare[s1, s2, ~ignoreCase]]}; CompareSubStrings: PUBLIC PROC [s1, s2: SubString, ignoreCase: BOOLEAN _ TRUE] RETURNS [Relation] = BEGIN r1: ROPE = Rope.Substr[RefText.TrustTextAsRope[s1.base], s1.offset, s1.length]; r2: ROPE = Rope.Substr[RefText.TrustTextAsRope[s2.base], s2.offset, s2.length]; RETURN[Rope.Compare[r1, r2, ~ignoreCase]]; END; DeleteSubString: PUBLIC PROC [s: SubString] RETURNS [String] = {RETURN[s.base]}; <> EqualCharacter: PUBLIC PROC [c: Character, s: String, index: CARDINAL] RETURNS [BOOLEAN] = { RETURN[s[index] = LOOPHOLE[c.code]]}; ScanForCharacter: PUBLIC PROC [c: Character, s: String, start: CARDINAL _ 0] RETURNS [CARDINAL] = BEGIN t: REF TEXT _ NEW[TEXT[1]]; i: INT; ardc: CARDINAL; t[0] _ LOOPHOLE[c.code]; i _ Rope.Index[RefText.TrustTextAsRope[s], start, RefText.TrustTextAsRope[t]]; IF i < 0 THEN ardc _ LAST[CARDINAL] ELSE {IF i > LAST[CARDINAL] THEN ardc _ LAST[CARDINAL] ELSE ardc _ i}; RETURN[ardc]; END; UpperCase: PUBLIC PROC [c: Character] RETURNS [Character] = {RETURN[[0, LOOPHOLE[Ascii.Upper[LOOPHOLE[c.code]]]]]}; LowerCase: PUBLIC PROC [c: Character] RETURNS [Character] = {RETURN[[0, LOOPHOLE[Ascii.Lower[LOOPHOLE[c.code]]]]]}; WellFormed: PUBLIC PROC [s: String] RETURNS [BOOLEAN] = {RETURN[s#NIL]}; <> MakeString: PUBLIC PROC [bytes: CARDINAL] RETURNS [String] = {RETURN[NEW[TEXT[bytes]]]}; FreeString: PUBLIC PROC [s: String] = {}; CopyString: PUBLIC PROC [s: String] RETURNS [String] = BEGIN ns: REF TEXT; IF s = NIL THEN RETURN [NIL]; ns _ NEW[TEXT[s.length]]; FOR i: CARDINAL IN [0 .. s.length) DO ns[i] _ s[i]; ENDLOOP; RETURN[ns]; END; <> ExpandString: PUBLIC PROCEDURE [s: String] RETURNS [Characters] = BEGIN c: Characters; IF s = NIL THEN RETURN [NIL]; c _ NEW[CharactersRep[s.length]]; FOR i: CARDINAL IN [0 .. s.length) DO c.data[i] _ [0, LOOPHOLE[s[i]]]; ENDLOOP; RETURN[c]; END; FreeCharacters: PUBLIC PROCEDURE [c: Characters] = {}; <> TruncateString: PUBLIC PROC [s: String, bytes: CARDINAL] RETURNS [String] = BEGIN s.length _ MIN[s.length, bytes]; RETURN[s]; END; CompareStringsAndStems: PUBLIC PROC [s1, s2: String, ignoreCase: BOOLEAN _ TRUE] RETURNS [relation: Relation, equalStems: BOOLEAN] = {RETURN[equal, TRUE]}; CompareStringsTruncated: PUBLIC PROC [s1, s2: String, trunc1, trunc2: BOOLEAN _ FALSE, ignoreCase: BOOLEAN _ TRUE] RETURNS [Relation] = {RETURN[equal]}; <> AppendDecimal: PUBLIC PROC [s: String, n: INTEGER] RETURNS [String] = BEGIN IF s= NIL THEN s _ NEW[TEXT[100]]; RETURN[Convert.AppendInt[s, n]]; END; AppendOctal: PUBLIC PROC [s: String, n: UNSPECIFIED] RETURNS [String] = BEGIN IF s= NIL THEN s _ NEW[TEXT[100]]; RETURN[Convert.AppendCard[s, n, 8]]; END; AppendLongNumber: PUBLIC PROC [s: String, n: LONG UNSPECIFIED, radix: CARDINAL _ 10] RETURNS [String] = BEGIN IF s= NIL THEN s _ NEW[TEXT[100]]; RETURN[Convert.AppendCard[s, n, LOOPHOLE[radix]]]; END; AppendLongDecimal: PUBLIC PROC [s: String, n: LONG INTEGER] RETURNS [String] = BEGIN IF s= NIL THEN s _ NEW[TEXT[100]]; RETURN[Convert.AppendCard[s, n]]; END; AppendNumber: PUBLIC PROC [s: String, n: UNSPECIFIED, radix: CARDINAL _ 10] RETURNS [String] = BEGIN IF s= NIL THEN s _ NEW[TEXT[100]]; RETURN[Convert.AppendCard[s, n, LOOPHOLE[radix]]]; END; StringToNumber: PUBLIC PROC [s: String, radix: CARDINAL _ 10] RETURNS [UNSPECIFIED] = BEGIN ENABLE Convert.Error => ERROR InvalidNumber; i: INTEGER; IF s=NIL THEN RETURN[0]; i _ Convert.IntFromRope[RefText.TrustTextAsRope[s], LOOPHOLE[radix]]; RETURN[LOOPHOLE[i]]; END; <> StringFromMesaString: PUBLIC PROC [s: MesaString] RETURNS [String] = {RETURN[s]}; <> AppendToMesaString: PUBLIC PROC [to: MesaString, from: String] = {[] _ RefText.Append[to, from]}; ValidAsMesaString: PUBLIC PROC [s: String] RETURNS [BOOLEAN] = {RETURN[TRUE]}; <> <> <= the length of the string. The maxlength field may, of course, be set by the client after deserialization to match the length field.>> <<-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---->> <> <<-- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---->> InvalidNumber: PUBLIC ERROR = CODE; -- raised by StringToDecimal if the characters do not represent a decimal number. This is a SIGNAL is String.mesa InvalidString: PUBLIC ERROR = CODE; <> <> StringBoundsFault: PUBLIC SIGNAL [old: String, increaseBy: CARDINAL] RETURNS [new: String] = CODE; <> END. -- of NSString LOG ( date - person - action ) February 26, 1981 - Kabcenell - Creation. - - - - FILING 5.0 - - - - 1-Mar-82 14:07:59 - Hamilton - Add SubString and StringToDecimal stuff. 19-Apr-82 15:59:12 - Hamilton - Add remaining ops that String.mesa has and NSString.mesa doesn't. August 2, 1982 - Hanzel - Define Characters, ExpandString, and Freecharacters in support of character-level access. August 5, 1982 - Kiser - Added increaseBy to StringBoundsFault. 5-Aug-82 19:18:52 - Kabcenell - Changed order of arguments in ExpandString and FreeCharacters; made Characters a LONG DESCRIPTOR. 2-Sep-82 15:50:35 - Kiser - Made internal structure of Character visible; added DescribeString. 22-Sep-82 21:00:195 - Kiser - Changed NOTE comment: StringBoundsFault always leaves a well-formed string.