Safe string type

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Safe string type

Post by stylin »

A small type to make strings safer to use. (beginners, don't worry about passing strings by value, just use this..)

Code: Select all

/' SafeString interface
::
'/

'' A wrapper for STRING allowing correct byval/byref behavior and
'' providing NEW/NEW[]/DELETE/DELETE[] support.
type SafeString
public:
	'' Constructs from another string (if possible).
	declare constructor (byval zs as zstring ptr = 0)
	'' (default copy ctor, copy assignment and destructor are fine.)
	
	'' Gets a reference (pointer) to the underlying string.
	declare function Reference () as string ptr
	'' Gets the value of the underlying string.
	declare function Value () as string
	
	'' Gets the address of the character data.
	declare function GetData () as zstring ptr
	' Gets the length of the string in characters.
	declare function GetLength () as integer
	
	'' Implicitly casts to a string value, making usage with most runtime
	'' library procedures transparent.
	declare operator cast () as string
private:
	m_impl		as string
end type

'' Mirrors SafeString.Reference, provided only to make referencing the
'' underlying string easier.
declare operator * (byref as SafeString) as string ptr

/' SafeString implementation
::
'/

'' :::::
constructor SafeString (byval zs as zstring ptr)
	m_impl = *iif(zs, zs, @"")
end constructor

'' :::::
function SafeString.Reference () as string ptr
	return @m_impl
end function

'' :::::
function SafeString.Value () as string
	return m_impl
end function

'' :::::
function SafeString.GetData () as zstring ptr
	return strptr(m_impl)
end function

'' :::::
function SafeString.GetLength () as integer
	return len(m_impl)
end function

'' :::::
operator * (byref self as SafeString) as string ptr
	return self.Reference()
end operator

'' :::::
operator SafeString.cast () as string
	return m_impl
end operator

/' SafeString demo
::
'/

'' Passing convention testors.
sub f (byval ss as SafeString)
	ss = "modified"
end sub
sub g (byref ss as SafeString)
	ss = "modified"
end sub

		'' ::::: (main)
		' easy initialization with NEW/NEW[] support..
		dim s1 as SafeString = "Hello, "
		var s2 = new SafeString("world!")
		print s1, *s2
		
		' indexing..
		(**s1)[0] = asc("h")
		(***s2)[0] = asc("W")
		print s1, *s2
		
		' concatenation..
		s1 &= *s2
		print s1, *s2
		
		' safe to pass by value..
		f(s1) : g(*s2)
		print s1, *s2
		
		' DELETE/DELETE[] support..
		delete s2
and now the obligatory, i want my byval back byval back byval back byval back byval back byval back byval back byval back - i want my byval back.. =>

edit: sorry, meant to put this in tips and tricks, must have pushed the wrong button.

edit2: added SafeString.GetData/.GetLength
1000101
Posts: 2556
Joined: Jun 13, 2005 23:14
Location: SK, Canada

Post by 1000101 »

The Reference function is slighty dangerous.

It's returning the first entry of the string descriptor, which happens to be the pointer to the string data, but I have been informed by mr_cha0s in irc that the "correct" and safe way to do it is this:

Code: Select all

zsptr = @string[0]
This allows for the string descriptor to change without causing your code to stop functioning properly.
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Post by stylin »

SafeString.Reference is supposed to return the address of the descriptor, ie, a reference to the 'string object' itself, so you can dereference it and have direct access to the underlying string. SafeString.operator * is a shortcut for SafeString.Reference. This allows you to do 'ProcTakingAStringByReference(*x.Reference())' or 'ProcTakingAStringByReference(**x), to pass the string directly, rather than a copy.

The string character data ('@s[0]') can be retrieved using SafeString.GetData.
cha0s
Site Admin
Posts: 5319
Joined: May 27, 2005 6:42
Location: USA
Contact:

Post by cha0s »

Use strptr(string) for that, same thing and "cleaner".
Post Reply