Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 08:27 24 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Longstring Split

Author Message
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 228
Posted: 12:07am 05 Oct 2024
Copy link to clipboard 
Print this post

With lots of coding using the WebMite, I find there's a lot of string manipulation - sometimes with longstrings and sometimes normal strings with conversions back and forth, finding character positions, extracting strings and so on... So I wondered if there was maybe another way to tackle it.
I miss the old VB6 'Split' function, so based on that, I tried a similar idea for longstrings.

This function takes a longstring, splits it at a delimiter character and stores the results in an array of 'normal' strings to be worked on later.

Usage: Call the function and pass the longstring + the delimiter character, and the number of array elements created are passed back. ie:
     timer = 0
     ArrElements = LSplit(ConnData(), "&")
     ? "Elapsed time stamp " + str$(timer)
     for i = 1 to ArrElements
       ? "Next element : ";
       ? SplitArr(i)
     next i


function LSplit(LSplitStr() as integer, Delimiter as string) as integer
 local integer i = 0, j = 0, NextPos = 0, LastPos = 0
 if LCheck(LSplitStr(), Delimiter) = 0 then 'check if we have valid parameters
   exit function
 endif
 do
   NextPos = linstr(LSplitStr(), Delimiter, NextPos + 1) 'find the next delimiter
   if NextPos = 0 then 'if it's not found
     exit do 'there's nothing more to look for, get out
   else 'otherwise
     j = j + 1 'add to the variable
   endif
 loop 'go and look again
 on error skip 'in case the array doesn't exist
 erase SplitArr() 'get rid of any existing array
 dim string SplitArr(j + 1) 'create a new array for the split results... +1 for the last result
 for j = 1 to bound(SplitArr()) '1 to the number of elements in the array
   NextPos = linstr(LSplitStr(), Delimiter, LastPos + 1) 'get the next delimiter position
   if NextPos = 0 then 'if there's none left
     NextPos = llen(LSplitStr()) + 1 'set the nextpos to the end of the string (+1 to be subtracted later)
   endif
   SplitArr(j) = lgetstr$(LSplitStr(), LastPos + 1, NextPos - LastPos) 'add the string to the array
   on error skip
   if right$(splitarr(j), 1) = delimiter then
     SplitArr(j) = left$(SplitArr(j), len(SplitArr(j)) - 1) 'remove the delimter char from the stored string
   endif
   LastPos = NextPos 'reset the variables for the next loop around
   LSplit = j 'keep track of how many elements there are
 next j
end function

function LCheck(LSplitStr() as integer, Delimiter as string) as integer
 if llen(LSplitStr()) = 0 then 'zero length string
   ? "Longstring is required" 'as it says
   LCheck = 0
   exit function 'get out
 endif
 if Delimiter = "" then 'no delimiter
   ? "Delimiter is required" 'as it says
   LCheck = 0
   exit function 'get out
 endif
 if len(Delimiter) > 1 then
   ? "Too many characters in the delimiter"
   LCheck = 0
   exit function
 endif
 if linstr(LSplitStr(), Delimiter, 1) = 0 then
   ? "Delimiter char not found" 'as it says
   LCheck = 0
   exit function 'get out
 endif
 LCheck = 1
end function


So far seems to work OK, hopefully others might find it useful  

Edit: Fixed a line of code that could result in losing a character on the fina; element of the array
Edited 2024-10-05 10:43 by Malibu
John
 
EDNEDN
Senior Member

Joined: 18/02/2023
Location: United States
Posts: 118
Posted: 03:33am 05 Oct 2024
Copy link to clipboard 
Print this post

I think a better solution would be a string type that can expand or shrink to whatever size is needed to hold the data.   There were limitations on the max string length in the Microsoft Basic.   But those limitations can be ignored now days.

Wouldn't it make sense to have strings of arbitrary length and self-adjusting in memory usage in MMBasic?

In the Microsoft system the first byte said how long the string was.   If the first 3 (or 4) bytes specified the string length in MMBasic, your needs would be met?

The biggest problem I see is the garbage collection.   It would chew up and fragment the heap.   But even that isn't too big of a deal.   Doing the garbage collection to de-fragment the free memory area of the heap would be almost trivial.  (With the understanding that defragmentation is expensive computationally and if you are operating at the edge of free memory your program is going to slow down.)
 
Malibu
Senior Member

Joined: 07/07/2018
Location: Australia
Posts: 228
Posted: 05:31am 05 Oct 2024
Copy link to clipboard 
Print this post

Sorry EDN, I might have been a little confusing in my post. It took me a few reads of your post for me to understand what your suggestion was pointing to...
I don't mean a string of a long length, I mean a LongString of the data type  

From the manual
  Quote  Long String Variables
Variables for holding long strings must be defined as integer arrays. The long string routines do not keep
numbers in these arrays but just use them as blocks of memory for holding long strings.


In my case, a longstring is the data that comes in as a HTTP request, sometimes containing POST data that needs to be tended to.
I find it's easier to break a 'longstring' into a 'normal' string (or array) and deal with smaller chunks.
A HTTP request from this
  Quote  POST /index.html?aZ3f7b0oqEyeZNXHJRdvTIYE6Pn02 HTTP/1.1
Host: 192.168.0.106
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Origin: http://192.168.0.106
Connection: keep-alive
Referer: http://192.168.0.106/index.html?aZ3f7b0oqEyeZNXHJRdvTIYE6Pn02
Upgrade-Insecure-Requests: 1

page=index&TestButton=Click+Me&passkey=aZ3f7b0oqEyeZNXHJRdvTIYE6Pn02

to this
  Quote  page=index
TestButton=Click+Me
passkey=aZ3f7b0oqEyeZNXHJRdvTIYE6Pn02

...is easier for my barely functioning brain-cells to follow  
John
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 3800
Posted: 06:33am 05 Oct 2024
Copy link to clipboard 
Print this post

  EDNEDN said  The biggest problem I see is the garbage collection.   It would chew up and fragment the heap.

It's also going to mess with the (mostly?) predictable real-time nature of MMBasic.

(Not to mention adding quite complex code liable to have bugs.)

I suspect it wouldn't fit on several/most PIC32 CPUs as space is at a real premium on them.

John
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6778
Posted: 07:23am 05 Oct 2024
Copy link to clipboard 
Print this post

One of the beautiful things about MMBasic is that it has no garbage collection and doesn't need it. It's an elegant system designed for machines with little RAM.

If you even hint that it might be a good idea to introduce it Geoff and Peter will likely "send the boys round" to persuade you differently.  ;)
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024