Main Menu

Recent posts

#1
OxygenBasic Examples / Re: Notes on JSON format
Last post by Charles Pegge - Today at 12:01:33 AM
A one piece JSON parser for testing. It should be able to cope with deeply recursive JSON structures.

'09/02/2025
'JSON PARSING
'
uses console
'
'INPUT
'
string s=quote
~~~

{
"employees":[
    {"firstName":"John", "lastName":"Doe", value:30.5 },
    {"firstName":"Anna", "lastName":"Smith"},
    {"firstName":"Peter", "lastName":"Jones"}
]
}

~~~

indexbase 1
string name[1000]
string  dat[1000]
int    dmap[1000]
int    dlvl[1000]
int je
'
====================
subroutine JsonParse
====================
int i,j
int gf,bf,be,cc,sc,db,ty,dm
int qc,qf,qe,td,tf,te,sa,sd,nc
byte*b
@b=strptr(s)-1 'byte overlay
i=0            'char iterator
j=0            'index items
sa=0           'array capture flag
sd=0           'array items flag
'
'========
NextItem:
=========
'
j++          'increment name / dat index
qf=0         'quote flag start
qe=0         'quote end
qc=0         'quote toggle
tf=0         'text flag
bf=0         'object flag
gf=0         'array fkag stt
cc=0         '{} object depth
sc=0         '[] array depth
td=0         'end of text flag
ty=0         'type of direct data
dm=0         'dmap assigned flag
nc=0         'nesting counter
ty=0         'raw data flgs
db=sa        'data flag

==========
do 'parse
==========
@b++
i++
td=0 'assume delimiting char
select b
'
=========
case   0 ' ' end of string
=========
  '
  exit do
  '
=========
case 1 to 32 ' ' white space
=========
  '
  continue do
  '
=========
case  "\" 'escape char
=========
  @b++ : i++ : td=1
  'itr edit out '\'
  if b=0 then exit do
=========
case  34 '"' quote flag toggle
=========
  qc xor=1
  if qc then
    qf=i
  else
    qe=i
    if gf+bf=0
      if db
        dat(j)=mid(s,qf+1,qe-qf-1)
        if dm=0
          dmap[j]=qf+1
          dlvl[j]=nc
        endif
        goto nextitem
      else
        name(j)=mid(s,qf+1,qe-qf-1)
        dmap[j]=qf+1
        dlvl[j]=nc
        dm=1
        tf=0 'text flag
        td=0 'in text flag
        db=1 'data flag (expecting)
        continue do
      endif
    endif
  endif
=========
case qc<>0
=========
  '
  continue do
  '
=========
case ","
=========
  'capture unquoted data
  gosub captData
  if ty
    goto nextitem
  endif
=========
case  ":"
=========
  if gf+bf=0
    if qf=0 then
      name[j]=mid(s,tf,te-tf+1) 'raw name
      dmap[j]=tf
      dlvl[j]=nc
      dm=1
    endif
    qf=0 'clear quote flag
    tf=0 'text flag
    db=1 'data flag (expecting)
    continue do
  endif
=========
case  "["
=========
  nc++
  if db
    sc++
    if gf+bf=0
      if sc=1 'start array
        bf=i
        sa=1 'array capture flag
      endif
    endif
  else 'db=0
    'splitting array into separate items
    'no name assigned
    name(j)=""
    sd=1
  endif
=========
case  "]"
=========
  nc--
  sc--
  gosub CaptData
  if sc=0 'end inner array
    sa=0
    if ty=0
      dat[j]=mid(s,bf,i-bf+1)   'brackets included
      if dm=0
        dmap[j]=bf
        dlvl[j]=nc
      endif
    endif
    goto nextitem
  elseif sc<0
    sc=0
    sa=0
    sd=0
    if nc<=0
      if ty
        j++
      endif
      exit do 'splitting array complete
    else
      goto nextitem
    endif
  endif
=========
case "{"
=========
  nc++
  if sa+sd
    db=1 'objects inside an array
  endif
  if db
    cc++
    if cc=1 'inner object
      gf=i  'start of {} block
    endif
  else 'db=0
    'splitting an object into parts
  endif
=========
case "}"
=========
  nc--
  cc--
  gosub CaptData
  if cc=0 'end inner object
    if sa=0 'not inside array
      dat[j]=mid(s,gf,i-gf+1) 'brackets included
      if dm=0
        dmap[j]=gf
        dlvl[j]=nc
      endif
      goto nextitem
    endif
  elseif cc<0
    cc=0
    if nc<=0
      if ty
        j++
      endif
      exit do 'splitting array complete
    else
      goto nextitem
    endif
  endif
=========
case else 'covers all other ascii
=========
  td=1
  if gf+bf=0
    if tf=0
      tf=i
      'start of unquoted /
      'name/number/true/flse/null
    endif
    te=i
  endif
end select
'
'
========
end do
========

SubRoutine CaptData
===================
'
ty=0
if gf+bf+td+qf=0
  if tf
    if db
      'unquoted data
      dat[j]=mid(s,tf,te-tf+1)
      if dm=0
        dmap[j]=tf
        dlvl[j]=nc
      endif
      'numbers/true/falsr/null
      ty=1
    endif
  endif
endif
end subroutine 'CaptData

je=j-1 'end of data

end subroutine 'JsonParse
'
'TEST OUTPUT
'===========
'
int i
print cr
gosub JsonParse
for i=1 to je
  print i " NAME: " name[i] cr
  print i " DATA: " dat[i] cr
next
print cr cr
'
print "split array" cr
s=dat(1)
gosub JsonParse
for i=1 to je
  print i " NAME: " name[i] cr
  print i " DATA: " dat[i] cr
next
print cr

print "split object" cr
s=dat(1)
gosub JsonParse
for i=1 to je
  print i " NAME: " name[i] cr
  print i " DATA: " dat[i] cr
next
print cr

wait
#2
Freebasic / Re: Rich Edit Text Object Mode...
Last post by Johan Klassen - Yesterday at 01:00:35 PM
very interesting José
#3
Freebasic / Re: Rich Edit Text Object Mode...
Last post by José Roca - Yesterday at 11:33:24 AM
I was very disappointed when Bob incorporated a graphic control that could only work with DDT. Also, because it was a subclassed image static control, it could not deal with alpha blended images. Therefore, I made my own graphic control that not only supported alpha blended images, but also has support for GDI, GDI+ and OpenGL, whereas the PB Graphic control only has native support for GDI.

Classes work so well in FreeBasic, that I'm thinking in writing several more that will incorporate related procedures of my framework.

For example, a CString class, with these methods (other that the intrinsic ones already provided by the language):

ClipLeft
ClipMid
ClipRight
Cset
Delete
Extract
Insert
Join
LCase
LSet
Parse
ParseCount
Remain
Remove
Repeat
Replace
Retain
Reverse
RSet
Shrink
Split
Spn
Tally
UCase
UnWrap
Verify
Wrap

and some more specialized such

Base64Decore
Base64Encode
CryotBinarytoString
CryptStringToBinary
etc.
#4
Freebasic / Re: Rich Edit Text Object Mode...
Last post by José Roca - Yesterday at 10:19:17 AM
If you bother to read the documentation of my WinFBX framework, you will seee that I offer all that PowerBasic offers and much more, and my CWindow class is better than DDT and as easy to use, and it has the advantage that is 100% SDK compatible.

See: https://github.com/JoseRoca/WinFBX/blob/master/docs/Windows%20GUI/CWindow%20Class.md

I also write extensive documentation and provide many examples. I consider that good documentation is essential, even if it takes me more time that to write the code.

An editor as complex as WinFBE (by Paul Squires) has been written entirely using my framework. This is a proof of how powerful it is.

And if I die, I'm providing the source code.

And if nobody uses it, I don't care. I'm working on it to keep my mind in good shape.


#5
Freebasic / Re: Rich Edit Text Object Mode...
Last post by José Roca - Yesterday at 09:47:29 AM
A new compiler made by a man alone is a project of at least 10 years (ask Charles). I'm too old to wait. FreeBasic offers what I need and all the code that I write can be compiled to 32 or 64 bit without changes.

BTW I'm going to add methods to work easily with fonts: Bold, Italic, StrikeOut, Underline, Height, FaceName, Offset and color. Having to fill a CHARFORMAT structure and read the documentation each time to see which values and flags you have to set is very tedious and time consuming.

So, instead of
`
pRichEdit->ExSetSel(98, 113)          ' // Select word at position 98, 113
DIM cf AS CHARFORMAT
cf.dwMask = CFM_BOLD                  ' // Character effects
cf.dwEffects = CFE_BOLD               ' // The CFE_BOLD value of the dwEffects member is valid
pRichEdit->SelectionCharFormat = cf   ' // Set the color
pRichEdit->HideSelection(TRUE)        ' // Hide selection

you will use

pRichEdit->SetSelFontBold(98,113)
#6
OxygenBasic Examples / Re: Notes on JSON format
Last post by Theo Gottwald - Yesterday at 09:20:52 AM
Quote from: Charles Pegge on February 08, 2025, 03:27:39 PMThanks Theo, that has given me some ideas for a compact JSON parser. I can almost visualize the code.


If you can visualize code you can use that ability to create new commands that can shorten the code.
#7
Freebasic / Re: Rich Edit Text Object Mode...
Last post by Theo Gottwald - Yesterday at 09:18:53 AM
I am still using Bob's PowerBasic and i do not plan to switch until Jürgen has something better.
He is still working on it. While there are some strange symptoms when compiling (sometimes no need to declare local variables, sometimes Labels and variables, or Labels and Function names get into conflict) i did not run against a limit.
Must say that the whole Object things that was implemented lastly seems to produce memory leaks so i do not use it for stuff that is often called.
#8
Freebasic / Re: Rich Edit Text Object Mode...
Last post by José Roca - Yesterday at 02:10:40 AM
I have added methods to save the entire contents or a selection of the contents of a rich edit control in RTF format (with or without the inclusion of inserted images or COM objects) or in text format.
#9
Freebasic / Re: Rich Edit Text Object Mode...
Last post by José Roca - February 08, 2025, 09:22:24 PM
> @José Roca
> Just ask Qwen KI he knows that.

Thanks, but as I'm not using C#, that code is completely useless to me.

I already have a couple of ideas of how to do it.
#10
OxygenBasic Examples / Re: Notes on JSON format
Last post by Frank Brübach - February 08, 2025, 08:24:02 PM
For Charles: you can also have a Look at Here:

https://github.com/StringEpsilon/fbJson/tree/master

#include "fbJson.bi"

' JSON-Daten als String
dim as string jsonString = "{""name"": ""Max"", ""age"": 25, ""skills"": [""FreeBASIC"", ""JSON""]}"

' JSON-Daten parsen
dim as jsonItem jsonData = JsonItem(jsonString)

' Zugriff auf JSON-Elemente
print "Name: " & jsonData["name"].asString()
print "Alter: " & jsonData["age"].asInteger()

' Zugriff auf Array-Werte
dim as jsonItem skillsArray = jsonData["skills"]
for i as integer = 0 to skillsArray.count() - 1
    print "Skill " & (i + 1) & ": " & skillsArray[i].asString()
next

' JSON-Daten manipulieren
jsonData["city"] = JsonItem("Berlin") ' Neues Element hinzufügen
print "Stadt: " & jsonData["city"].asString()

' Serialisieren (zurück in einen JSON-String)
print "Serialisiertes JSON: " & jsonData.toString()