Many languages have powerful and useful (binary safe) string manipulation functions, while others don't, making it harder for these languages to accomplish some tasks.

This task is about creating functions to handle binary strings (strings made of arbitrary bytes, i.e. byte strings according to Wikipedia) for those languages that don't have built-in support for them.

If your language of choice does have this built-in support, show a possible alternative implementation for the functions or abilities already provided by the language.

In particular the functions you need to create are:

 String creation and destruction (when needed and if there's no garbage collection or similar mechanism)
 String assignment
 String comparison
 String cloning and copying
 Check if a string is empty
 Append a byte to a string
 Extract a substring from a string
 Replace every occurrence of a byte (or a string) in a string with another string
 Join strings


Possible contexts of use: compression algorithms (like LZW compression), L-systems (manipulation of symbols), many more.




\ Rosetta Code Binary Strings Demo in Forth
\ Portions of this code are found at http://forth.sourceforge.net/mirror/toolbelt-ext/index.html
 
\ String words created in this code:
\       STR<    STR>    STR=    COMPARESTR      SUBSTR  STRPAD  CLEARSTR
\       =""     ="      STRING: MAXLEN  REPLACE-CHAR    COPYSTR WRITESTR
\       ,"      APPEND-CHAR     STRING, PLACE   CONCAT  APPEND  C+!  ENDSTR
\       COUNT   STRLEN
 
: STRLEN  ( addr -- length)  c@ ;        \ alias the "character fetch" operator
 
: COUNT   ( addr --  addr+1 length)      \ Standard word. Shown for explanation
          dup  strlen swap 1+ swap ;     \ returns the address+1 and the length byte on the stack
 
: ENDSTR  ( str -- addr)                 \ calculate the address at the end of a string
          COUNT + ;
 
: C+!     ( n addr -- )                  \ primitive: increment a byte at addr by n
          DUP C@ ROT + SWAP C! ;
 
: APPEND  ( addr1 length addr2 -- )      \ Append addr1 length to addr2
          2dup 2>r  endstr swap move 2r> c+! ;
 
: CONCAT  ( string1 string2 -- )          \ concatenate counted string1 to counted string2
           >r  COUNT  R> APPEND ;
 
: PLACE  ( addr1 len addr2 -- )           \ addr1 and length, placed at addr2 as counted string
           2dup 2>r  char+  swap  move  2r> c! ;
 
: STRING, ( addr len -- )                 \ compile a string at the next available memory (called 'HERE')
            here  over char+  allot  place ;
 
: APPEND-CHAR  ( char string -- )         \ append char to string
           dup >r  count dup 1+ r> c! + c! ;
 
: ,"       [CHAR] " PARSE  STRING, ;      \ Parse input stream until '"' and compile into memory
 
 
: WRITESTR ( string -- )                  \ output a counted string with a carriage return
           count  type CR ;
 
: COPYSTR  ( string1 string3 -- )         \ String cloning and copying COPYSTR
           >r  count  r> PLACE ;
 
: REPLACE-CHAR ( char1 char2 string -- )  \ replace all char2 with char1 in string
          count                           \ get string's address and length
          BOUNDS                          \ calc start and end addr of string for do-loop
          DO                              \ do a loop from start address to end address
             I C@ OVER =                  \ fetch the char at loop index compare to CHAR2
             IF
                OVER I C!                 \ if its equal, store CHAR1 into the index address
             THEN
          LOOP
          2drop ;                         \ drop the chars off the stack
 
 
 256 constant maxlen                      \ max size of byte counted string in this example
 
: string:   CREATE    maxlen ALLOT ;      \ simple string variable constructor
 
 
: ="      ( string -- )                   \ String variable assignment operator (compile time only)
          [char] " PARSE  ROT  PLACE ;
 
: =""     ( string -- )  0 swap c! ;      \ empty a string, set count to zero
 
 
: clearstr ( string -- )                  \ erase a string variables contents, fill with 0
           maxlen erase ;
 
 
  string: strpad                           \ general purpose storage buffer
 
: substr  ( string1 start length -- strpad) \ Extract a substring of string and return an output string
          >r >r                             \ push start,length
          count                             \ compute addr,len 
          r> 1- /string                     \ pop start, subtract 1, cut string 
          drop r>                           \ drop existing length, pop new length
          strpad place                      \ place new stack string in strpad
          strpad ;                          \ return address of strpad
 
\ COMPARE takes the 4 inputs from the stack (addr1 len1  addr2 len2 )
\ and returns a flag for equal (0) , less-than (1)  or greater-than (-1) on the stack
 
  : comparestr ( string1 string2 -- flag)  \ adapt for use with counted strings
              count rot count compare ;
 
\ now it's simple to make new operators
  : STR=   ( string1 string2 -- flag)
             comparestr  0= ;
 
  : STR>   ( string1 string2 -- flag)
             comparestr -1 = ;
 
  : STR<   ( string1 string2 -- flag)
             comparestr 1 = ;
 
 