Παρασκευή 9 Σεπτεμβρίου 2022

Url Encoding (using OOP plus convertions from and to UTF8 and UTF16)

First apear here: https://rosettacode.org/wiki/URL_encoding#M2000_Interpreter

A Module in M2000 is like a procedure, which has own namespace (may contain other modules/functions).

Module checkit has a function decodeUrl$() which finally use decoding from utf8 to utf16LE (for proper reender to M2000 console). This module also has an object Parse$. The $ in Parse$ means that this object return a string (see the Value part of this group), and also has a set function to get a new string value as Parse$()= stringExpUtf16LE or Parse$(variationType) = stringExpUtf16LE. The group formed direct from a Group statement, so it is like a local variable, which deleted at the end of the module execution. The name Parse and Parse$() are reserved. The first one Parse used with dot notation. By default all members are public, so Parse.HTML5 is public too, and has type UrlType.

At the main part of Checkit, we see this m=each(Parse.UrlType), where m is a local object used to walk through each Parse.UrlType using a While End While structure (or While { }, we see that on original post in rosettacode.org). So see at decodeUrl$() the use of each() for arrays, where we use a start value of 2 (the second from start). There we have k as the object, and the k^ is the return value from internal counter. The Chr$(StrExp) and Str$(StrExp) usd for conversions from 8 bit to 16bit. Use Help Chr$ to find out how this works.

So we feed UTF16LE to parse object, and internal this converted to UTF8. The parse.decode$() return string with UTF8 and Url Enconding, and decodeUrl() get the UTF8 string and return a UTF16LE, which we can print it to M2000 console.


module Checkit {
function decodeUrl$(a$) {
dim a$()
a$()=Piece$(a$, "%")
if len(a$())=1 then =str$(a$):exit
k=each(a$(),2)
acc$=str$(a$(0))
while k
acc$+=str$(Chr$(Eval("0x"+left$(a$(k^),2)))+Mid$(a$(k^),3))
end while
=string$(acc$ as utf8dec)
}
group Parse$ {
all$, c=1
tc$=""
Enum UrlType {None=0, RFC3986, HTML5}
variation
TypeData=("","-._~","-._*")
function Next() {
.tc$<=mid$(.all$,.c,1)
.c++
=.tc$<>""
}
Value {
=.tc$
}
function DecodeOne$() {
if .tc$="" then exit
if .tc$ ~"[A-Za-z0-9]" then =.tc$ : exit
If .tc$=" " Then =if$(.variation=.HTML5->"+","%20") :exit
if instr(.TypeData#val$(.variation),.tc$)>0 then =.tc$ :exit
="%"+hex$(asc(.tc$), 1)
}
function Decode$() {
acc$=""
.c<=1
while .Next()
acc$+=.DecodeOne$()
end while
=acc$
}
Set () {
\\ using optional argument
var=.None
Read a$, ? var
a$=chr$(string$(a$ as utf8enc))
.variation<=var
.all$<=a$
.c<=1
}
}
\\ MAIN
Parse$()="http://foo bar/"
print Quote$(Parse.Decode$())
Parse.variation=Parse.HTML5
print Quote$(Parse.Decode$())
Parse.variation=Parse.RFC3986
print Quote$(Parse.Decode$())
Parse$(Parse.RFC3986) ={mailto:"Irma User" <irma.user@mail.com>}
print Quote$(Parse.Decode$())
Parse$(Parse.RFC3986) ={http://foo.bar.com/~user-name/_subdir/*~.html}
m=each(Parse.UrlType)
while m
Parse.variation=eval(m)
print Quote$(Parse.Decode$())
print decodeUrl$(Parse.Decode$())
end while
}
Rem {This example print this on M2000 console:
"http%3A%2F%2Ffoo%20bar%2F"
"http%3A%2F%2Ffoo+bar%2F"
"http%3A%2F%2Ffoo%20bar%2F"
"mailto%3A%22Irma%20User%22%20%3Cirma.user%40mail.com%3E"
"http%3A%2F%2Ffoo%2Ebar%2Ecom%2F%7Euser%2Dname%2F%5Fsubdir%2F%2A%7E%2Ehtml"
http://foo.bar.com/~user-name/_subdir/*~.html
"http%3A%2F%2Ffoo.bar.com%2F~user-name%2F_subdir%2F%2A~.html"
http://foo.bar.com/~user-name/_subdir/*~.html
"http%3A%2F%2Ffoo.bar.com%2F%7Euser-name%2F_subdir%2F*%7E.html"
http://foo.bar.com/~user-name/_subdir/*~.html
}
Form 80, 28

CheckIt 

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.