Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active June 26, 2024 08:23
Show Gist options
  • Save hodzanassredin/f86b1536ea947410b239132b68728851 to your computer and use it in GitHub Desktop.
Save hodzanassredin/f86b1536ea947410b239132b68728851 to your computer and use it in GitHub Desktop.
Blackbox implementation for issues load from github
MODULE TestJson;
IMPORT Log, W3cObjects, HttpClient, W3cStreams, W3cJSON, Strings, Meta, HttpParser, AosStreams;
TYPE
Issue* = POINTER TO RECORD
url*, title*: ARRAY 64 OF CHAR;
id*: INTEGER;
END;
Issues = POINTER TO ARRAY OF Issue;
W3cStreamAdapter = POINTER TO RECORD(W3cStreams.Reader)
r : AosStreams.Reader;
END;
PROCEDURE (this: W3cStreamAdapter) Get (): CHAR;
VAR ch16 : INTEGER;
BEGIN
IF (this.r.res = AosStreams.Ok) & (this.r.UTF8Char(ch16)) THEN
RETURN CHR(ch16);
ELSE
this.ok := FALSE;
RETURN 0X
END
END Get;
PROCEDURE JsonObjToRecord(obj: W3cJSON.Object; rec : ANYPTR);
VAR
it: Meta.Item; sc: Meta.Scanner; nm: Meta.Name;
isOk: BOOLEAN; tmpInt: INTEGER;tmpStr: POINTER TO ARRAY OF CHAR;
res : INTEGER;
any : ANYPTR;
BEGIN
Meta.GetItem(rec, it);
sc.ConnectTo(it);
sc.Scan;
ASSERT(~sc.eos);
WHILE ~sc.eos DO
sc.GetObjName(nm);
(*Log.String(nm); Log.Int(sc.this.obj); Log.Int(sc.this.typ); Log.Ln;*)
CASE sc.this.typ OF
| Meta.arrTyp:
tmpStr := obj.entries.Get(nm)(W3cJSON.String).val;
sc.this.PutStringVal(tmpStr, isOk);
| Meta.intTyp:
tmpInt := SHORT(obj.entries.Get(nm)(W3cJSON.Number).intVal);
sc.this.PutIntVal(tmpInt);
END;
sc.Scan;
END;
END JsonObjToRecord;
PROCEDURE Parse (stream: AosStreams.Reader) : Issues;
VAR
jsonParser: W3cJSON.Parser;
in: W3cStreamAdapter; err : W3cJSON.ErrorHandler;
val : W3cJSON.Value;
arr : W3cJSON.Array;
enum : W3cObjects.Enumerator;
obj: W3cJSON.Object;
issues : POINTER TO ARRAY OF Issue;
count, res : INTEGER;
BEGIN
NEW(err);err.Init();
NEW(in);in.r := stream; in.ok := TRUE;
jsonParser := W3cJSON.NewParser(in, err);
val := jsonParser.Parse();
arr := val(W3cJSON.Array);
NEW(issues, arr.elems.GetNumberOfElements());
enum := arr.elems.GetEnumerator();
count := 0;
WHILE enum.HasMoreElements() DO
obj := enum.GetNext()(W3cJSON.Object);
NEW(issues[count]);
JsonObjToRecord(obj, issues[count]);
INC(count);
END;
RETURN issues;
END Parse;
PROCEDURE Print(issues : Issues);
VAR i : INTEGER;
BEGIN
Log.String("Count "); Log.Int(LEN(issues)); Log.Ln;
FOR i := 0 TO LEN(issues) - 1 DO
Log.String("Issue "); Log.String(issues[i].url);Log.Ln;
END;
END Print;
PROCEDURE Do*;
VAR
client: HttpClient.HTTPConnection;
r: AosStreams.Reader;
res: INTEGER;
issues: Issues;
BEGIN
NEW(client);client.New();
client.Get("https://api.github.com/repos/facebook/react/issues", TRUE, r, res);
IF res = HttpClient.Ok THEN
Log.String(LONG(client.responseHeader.reasonphrase)); Log.Ln;
issues := Parse(r);
Print(issues)
ELSE
Log.Int(client.responseHeader.statuscode);
Log.String(LONG(client.responseHeader.reasonphrase));
END;
END Do;
END TestJson.
TestJson.Do
MODULE TestJson;
IMPORT Log, W3cObjects, HttpClient, W3cStreams, W3cJSON, Strings, Meta, HttpParser, AosStreams;
VAR jsonStr* : POINTER TO ARRAY OF CHAR;
TYPE
Issue* = POINTER TO RECORD
url*, title*: ARRAY 64 OF CHAR;
id*: INTEGER;
END;
Issues = POINTER TO ARRAY OF Issue;
W3cStreamAdapter = POINTER TO RECORD(W3cStreams.Reader)
r : AosStreams.Reader;
END;
W3cStringAdapter = POINTER TO RECORD(W3cStreams.Reader)
str : POINTER TO ARRAY OF CHAR;
pos, len : INTEGER;
END;
PROCEDURE (this: W3cStreamAdapter) Get (): CHAR;
VAR ch16 : INTEGER;
BEGIN
IF (this.r.res = AosStreams.Ok) & (this.r.UTF8Char(ch16)) THEN
RETURN CHR(ch16);
ELSE
this.ok := FALSE;
RETURN 0X
END
END Get;
PROCEDURE (this: W3cStringAdapter) Get (): CHAR;
BEGIN
INC(this.pos);
IF (this.pos < this.len) THEN
RETURN this.str[this.pos];
ELSE
this.ok := FALSE;
RETURN 0X
END
END Get;
PROCEDURE JsonObjToRecord(obj: W3cJSON.Object; rec : ANYPTR);
VAR
it: Meta.Item; sc: Meta.Scanner; nm: Meta.Name;
isOk: BOOLEAN; tmpInt: INTEGER;tmpStr: POINTER TO ARRAY OF CHAR;
res : INTEGER;
any : ANYPTR;
BEGIN
Meta.GetItem(rec, it);
sc.ConnectTo(it);
sc.Scan;
ASSERT(~sc.eos);
WHILE ~sc.eos DO
sc.GetObjName(nm);
(*Log.String(nm); Log.Int(sc.this.obj); Log.Int(sc.this.typ); Log.Ln;*)
CASE sc.this.typ OF
| Meta.arrTyp:
tmpStr := obj.entries.Get(nm)(W3cJSON.String).val;
sc.this.PutStringVal(tmpStr, isOk);
| Meta.intTyp:
tmpInt := SHORT(obj.entries.Get(nm)(W3cJSON.Number).intVal);
sc.this.PutIntVal(tmpInt);
END;
sc.Scan;
END;
END JsonObjToRecord;
PROCEDURE Parse (stream: AosStreams.Reader) : Issues;
VAR
jsonParser: W3cJSON.Parser;
in: W3cStreamAdapter; err : W3cJSON.ErrorHandler;
val : W3cJSON.Value;
arr : W3cJSON.Array;
enum : W3cObjects.Enumerator;
obj: W3cJSON.Object;
issues : POINTER TO ARRAY OF Issue;
count, res : INTEGER;
BEGIN
NEW(err);err.Init();
NEW(in);in.r := stream; in.ok := TRUE;
jsonParser := W3cJSON.NewParser(in, err);
val := jsonParser.Parse();
arr := val(W3cJSON.Array);
NEW(issues, arr.elems.GetNumberOfElements());
enum := arr.elems.GetEnumerator();
count := 0;
WHILE enum.HasMoreElements() DO
obj := enum.GetNext()(W3cJSON.Object);
NEW(issues[count]);
JsonObjToRecord(obj, issues[count]);
INC(count);
END;
RETURN issues;
END Parse;
PROCEDURE ReadString(stream: AosStreams.Reader) : POINTER TO ARRAY OF CHAR;
VAR
jsonParser: W3cJSON.Parser;
in: W3cStreamAdapter; err : W3cJSON.ErrorHandler;
val : W3cJSON.Value;
BEGIN
NEW(err);err.Init();
NEW(in);in.r := stream; in.ok := TRUE;
jsonParser := W3cJSON.NewParser(in, err);
val := jsonParser.Parse();
RETURN W3cJSON.Stringify(val, "");
END ReadString;
PROCEDURE Print(issues : Issues);
VAR i : INTEGER;
BEGIN
Log.String("Count "); Log.Int(LEN(issues)); Log.Ln;
FOR i := 0 TO LEN(issues) - 1 DO
Log.String("Issue "); Log.String(issues[i].url);Log.Ln;
END;
END Print;
PROCEDURE PrintLen*;
BEGIN
Log.Int(LEN(jsonStr));
END PrintLen;
PROCEDURE Load*;
VAR
client: HttpClient.HTTPConnection;
r: AosStreams.Reader;
res: INTEGER;
BEGIN
NEW(client);client.New();
client.Get("https://api.github.com/repos/facebook/react/issues", TRUE, r, res);
IF res = HttpClient.Ok THEN
Log.String(LONG(client.responseHeader.reasonphrase)); Log.Ln;
jsonStr := ReadString(r);
ELSE
Log.Int(client.responseHeader.statuscode);
Log.String(LONG(client.responseHeader.reasonphrase));
END;
END Load;
PROCEDURE ParseStr*;
VAR jsonParser: W3cJSON.Parser;
in: W3cStringAdapter; err : W3cJSON.ErrorHandler;
val : W3cJSON.Value;i:INTEGER;
BEGIN
NEW(err);err.Init();
NEW(in);in.str := jsonStr; in.len := LEN(jsonStr);
NEW(jsonParser);
FOR i := 0 TO 1000 DO
in.pos := -1; in.ok := TRUE;
jsonParser.Init(in, err);
jsonParser.SetStringPooling(W3cJSON.DefaultStringPooling);
val := jsonParser.Parse();
ASSERT(val#NIL);
val := NIL;
END;
END ParseStr;
PROCEDURE ParseStr2*;
VAR i : INTEGER;val : W3cJSON.Value;
BEGIN
FOR i := 0 TO 2000 DO
val := W3cJSON.Parse(jsonStr);
END;
END ParseStr2;
END TestJson.
TestJson.Load
TestJson.PrintLen
TestJson.ParseStr
TestJson.ParseStr2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment