using dynamic allocation instead of fixed length stack strings.

This commit is contained in:
Norayr Chilingarian 2024-01-23 19:20:23 +04:00
parent 8ee5252223
commit 90a1d51b24

View file

@ -1,27 +1,21 @@
MODULE vpkHttp; MODULE vpkHttp;
IMPORT Strings, Internet, vpkLogger, Out; IMPORT Strings, Internet, vpkLogger, Out;
CONST
MAXARRAYNUMBER = 10000; TYPE
MAXARRAYNUMBEREXTENDED = 100000; PString = POINTER TO ARRAY OF CHAR;
TYPE
PSTRING = POINTER TO ARRAY OF CHAR;
VAR VAR
buff, buff2: ARRAY MAXARRAYNUMBEREXTENDED OF CHAR; buff, buff2: PString;
PROCEDURE Empty *(VAR string: ARRAY OF CHAR); PROCEDURE Empty*(VAR string: PString);
VAR
i : LONGINT;
BEGIN BEGIN
FOR i := 0 TO LEN(string) - 1 DO string[i] := 0X END; NEW(string, 1);
COPY("", string); string[0] := 0X;
END Empty; END Empty;
PROCEDURE getClean *(buff: ARRAY OF CHAR; VAR clean: ARRAY OF CHAR); PROCEDURE getClean*(buff: ARRAY OF CHAR; VAR clean: PString);
VAR VAR
i: INTEGER; i: INTEGER;
newLine: ARRAY 2 OF CHAR;
lineIsHeader, EOL, notFirstLine: BOOLEAN; lineIsHeader, EOL, notFirstLine: BOOLEAN;
BEGIN BEGIN
i := 0; i := 0;
@ -43,102 +37,102 @@ BEGIN
INC(i); INC(i);
UNTIL (i + 2 > Strings.Length(buff)) OR (~lineIsHeader & EOL & notFirstLine); UNTIL (i + 2 > Strings.Length(buff)) OR (~lineIsHeader & EOL & notFirstLine);
Strings.Extract(buff, i, Strings.Length(buff), clean); NEW(clean, Strings.Length(buff) - i + 1);
Strings.Extract(buff, i, Strings.Length(buff), clean^);
END getClean; END getClean;
PROCEDURE AppendEOLAndClean(buff: ARRAY OF CHAR; VAR buffClean: PSTRING); PROCEDURE AppendEOLAndClean(buff: ARRAY OF CHAR; VAR buffClean: PString);
VAR i: LONGINT; VAR
i: LONGINT;
BEGIN BEGIN
i := Strings.Length(buff); i := Strings.Length(buff);
NEW(buffClean, i + 3); NEW(buffClean, i + 3);
COPY(buff, buffClean^);
COPY(buff, buffClean^);
buffClean[i] := 0DX; buffClean[i] := 0DX;
buffClean[i + 1] := 0AX; buffClean[i + 1] := 0AX;
buffClean[i + 2] := " "; buffClean[i + 2] := 0X;
END AppendEOLAndClean; END AppendEOLAndClean;
PROCEDURE addHeader(key, val: ARRAY OF CHAR; VAR buff: PSTRING); PROCEDURE addHeader(key, val: ARRAY OF CHAR; VAR buff: PString);
VAR VAR
header: ARRAY MAXARRAYNUMBER OF CHAR; header: PString;
headerLength: LONGINT;
BEGIN BEGIN
Empty(header); headerLength := Strings.Length(key) + Strings.Length(val) + 2; (* 2 for ": " *)
Strings.Append(key, header); NEW(header, headerLength + 1); (* +1 for null terminator *)
Strings.Append(": ", header);
Strings.Append(val, header); COPY(key, header^);
AppendEOLAndClean(header, buff); Strings.Append(": ", header^);
Strings.Append(val, header^);
AppendEOLAndClean(header^, buff);
END addHeader; END addHeader;
PROCEDURE getHeader(buff, key: ARRAY OF CHAR; VAR val: ARRAY OF CHAR); PROCEDURE getHeader(buff, key: ARRAY OF CHAR; VAR val: PString);
VAR VAR
positionStart, valPositionStart, i: LONGINT; positionStart, valPositionStart, i: LONGINT;
BEGIN BEGIN
positionStart := Strings.Pos(key, buff, 0); positionStart := Strings.Pos(key, buff, 0);
valPositionStart := positionStart + Strings.Length(key) + 1; valPositionStart := positionStart + Strings.Length(key) + 1;
NEW(val, Strings.Length(buff) - valPositionStart + 1);
i := 0; i := 0;
REPEAT REPEAT
val[i] := buff[valPositionStart + i]; val[i] := buff[valPositionStart + i];
INC(i); INC(i);
UNTIL (ORD(val[i]) = 10) (* 0DX number(newline)*) OR UNTIL (ORD(val[i]) = 10) OR (i > Strings.Length(buff));
(i > Strings.Length(buff));
END getHeader; END getHeader;
PROCEDURE get *(host, port, path: ARRAY OF CHAR; VAR buff: ARRAY OF CHAR); PROCEDURE get*(host, port, path: ARRAY OF CHAR; VAR buff: PString);
VAR VAR
socket : Internet.Socket; socket: Internet.Socket;
connectionFlag: BOOLEAN; connectionFlag: BOOLEAN;
valueContentLength: REAL; valueContentLength: REAL;
send, valueContentLengthString: ARRAY MAXARRAYNUMBER OF CHAR; send, valueContentLengthString: PString;
sendClean: PSTRING; sendClean: PString;
httpTail: ARRAY 16 OF CHAR; httpTail: ARRAY 16 OF CHAR;
endOfLine: ARRAY 3 OF CHAR; tmpBuff: PString;
tmpBuff: ARRAY MAXARRAYNUMBER OF CHAR; sendLength: LONGINT;
BEGIN BEGIN
Empty( buff); Empty(buff);
httpTail := " HTTP/1.1"; httpTail := " HTTP/1.1";
connectionFlag := Internet.Connect(host, port, socket);
send := "GET ";
Strings.Append(path, send); sendLength := Strings.Length(path) + Strings.Length(httpTail) + 4; (* 4 for "GET " *)
Strings.Append(httpTail, send); NEW(send, sendLength);
COPY("GET ", send^);
Strings.Append(path, send^);
Strings.Append(httpTail, send^);
AppendEOLAndClean(send, sendClean); AppendEOLAndClean(send^, sendClean);
connectionFlag := Internet.Write(socket, sendClean^); connectionFlag := Internet.Write(socket, sendClean^);
addHeader("HOST", host, sendClean);
connectionFlag := Internet.Write(socket, sendClean^);
addHeader("User-Agent", "oberon-http-client/1.0", sendClean);
connectionFlag := Internet.Write(socket, sendClean^);
addHeader("Accept", "*/*", sendClean); addHeader("HOST", host, sendClean);
connectionFlag := Internet.Write(socket, sendClean^); connectionFlag := Internet.Write(socket, sendClean^);
AppendEOLAndClean("", sendClean); addHeader("User-Agent", "oberon-http-client/1.0", sendClean);
connectionFlag := Internet.Write(socket, sendClean^); connectionFlag := Internet.Write(socket, sendClean^);
REPEAT
Empty( tmpBuff);
connectionFlag := Internet.Read(socket, tmpBuff); addHeader("Accept", "*/*", sendClean);
Strings.Append(tmpBuff, buff); connectionFlag := Internet.Write(socket, sendClean^);
getHeader(buff, "Content-Length", valueContentLengthString);
Strings.StrToReal(valueContentLengthString, valueContentLength); AppendEOLAndClean("", sendClean);
(* Out.Real(valueContentLength, 6); connectionFlag := Internet.Write(socket, sendClean^);
Out.Ln;
vpkLogger.LogIntLn(Strings.Length(buff)); REPEAT
*) Empty(tmpBuff);
(* vpkLogger.Log(buff); *) connectionFlag := Internet.Read(socket, tmpBuff^);
UNTIL ~connectionFlag OR (Strings.Length(buff) > valueContentLength); Strings.Append(tmpBuff^, buff^);
Internet.Disconnect(socket); getHeader(buff^, "Content-Length", valueContentLengthString);
Strings.StrToReal(valueContentLengthString^, valueContentLength);
UNTIL ~connectionFlag OR (Strings.Length(buff^) > valueContentLength);
Internet.Disconnect(socket);
END get; END get;
BEGIN BEGIN
(* get("norayr.am", "/tmp/", "80", buff); (* Example usage of the get procedure *)
getClean(buff, buff2); (* get("example.com", "80", "/path", buff);
vpkLogger.Log(buff2); *) getClean(buff^, buff2);
vpkLogger.Log(buff2^); *)
END vpkHttp. END vpkHttp.