Safe string type

Source-code only - please, don't post questions here.
stylin
Posts: 1253
Joined: Nov 06, 2005 5:19

Safe string type

Postby stylin » Jul 07, 2007 13:09

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

Postby 1000101 » Jul 07, 2007 14:27

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

Postby stylin » Jul 07, 2007 19:47

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: 5317
Joined: May 27, 2005 6:42
Location: Illinois
Contact:

Postby cha0s » Jul 07, 2007 22:37

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

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 3 guests