Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Reading HTTP, NNTP, IMAP, SMTP, NTP etc.; UTF 8|16 or binary.

29 views
Skip to first unread message

Jeff-Relf.Me

unread,
Jan 14, 2017, 11:56:38 PM1/14/17
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
Reading HTTP, NNTP, IMAP, SMTP, NTP etc.; UTF 8|16 or binary:

  //  DownLoad Example:  http://Jeff-Relf.Me/Posts.TXT
  //  Help/Settings:  http://Jeff-Relf.Me/X.HTM
  // 
  //  "More()", below, reads a random number of bytes from a server,
  //  marking the start and end of a line, "chunk", header, body etc.

  int More() { int  rv, Room, _Cmd, _Append, Done ;  
    _LnP  B, P, E, D ;  double  Mark ;
    _Cmd = Cmd, _Append = Append, Cmd = Append = Done = 0 ;
    if ( !_Append )
      //  Mark the start of the _header, instead of adding to it.
      //  The Header can't be larger than a MeagaByte, ha ha.
      //  
      //  Actually, "B_Head" marks the start of _any received data.
      //  Initially:  P_In = E_In = B_In ;  uchar B_In[ OneMeg ];
      B_Head = P_In ;

    //  E_In is the end of the received data;
    //  here, it's extended by szII, the size of the previous line fragment.
    *E_In = Ch_E_In, E_In += szII, szII = Ch_E_In = *E_In = 0 ;

    if ( ( B_SubHdr ? B_SubHdr : P_In ) + 5 > E_In ) {

      //  We got 5 or fewer bytes (or a line fragment) from the server;
      //  check for more.  B_SubHdr is used when a URL is "chunked".

      Recv:    if ( rv = B_Head - B_In )

                 //  memmove() "B_Head" to "B_In[]".
                 memmove( B_In, B_Head, E_In - B_Head ), B_Head -= rv,
                 B_SubHdr -= ( B_SubHdr ? rv : 0 ), P_In -= rv, E_In -= rv ;

               //  Calculated the (free) buffer size and start the timer.  
               *E_In = 0, Room = OneMeg - ( E_In - B_In ) - 9, Mark = Secs ;

               if ( Room < MaxLineLen ) {
                 Notice( L"Rogue Post: a %d KiloByte line.",
                     OneMeg / 1000 ), disConn;  Rtn(-1);  }

               LOOP { 

                 if ( Sz = recv( Connected, __LnP( E_In ), Room, 0 ),
                      !Sz && ( Count_Down = 0, Done = _ViaHTTP ) || Sz > 0 )

                   //  Got data.  Note if the URL is downloaded.
                   goto OnLine ;

                 if ( rv = WSAGetLastError(), rv == WSAEWOULDBLOCK ) { 

                   //  More data to come, server says.
                   if ( Secs > Mark + Time_Out ) { 
                     Notice( L"User Timed Out, %d seconds.", Time_Out ),
                     disConn;  Rtn(-2);  }

                   if ( Respond(), Game != ServerIO ) 
                     //  Respond() says the User Canceled the DownLoad.
                     Rtn(-3);

                   //  Check the server ( BusyRead ) again.
                   continue ;  }

                 Notice( L"Server Timed Out, WSAGetLastError(): %d.", rv ),
                 disConn;  Rtn(-4);  }

             //  Data was DownLoaded; Mark the end. 
      OnLine:    E_In += Sz, *E_In = Ch_E_In = 0 ;  }

    if ( Done || _BinBody )
      //  An OK download ( for _BinBody or URL ).
      Rtn(0);

    B = P_In, E = E_In, D = ER( B, E - MaxLineLen );
    if ( UTF16 ) { while( E - 1 > D && !( !*--E && *--E == 10 ) );  } 
    else { while( E > D && *--E != 10 );  }

    if ( *E != 10 )
      //  No Line Feed, it's a line fragment; check the server again.
      goto Recv;

    if ( E_Enc = E += 1 + ( UTF16 && !E[1] ), !_Cmd && !_ViaHTTP && E[-2] == 13 )
      //  "E_Enc" marks the end of the line ( in a text message ).
      //  "_Cmd" is true when reading a server's response to a command.
      if ( !E_Hdr && *B == 13 && B[1] == 10 ) 
        //  Mark the end of the header ( HTTP, NNTP, IMAP ).
        E_Hdr = B + 2 ;
      else if ( !E_Art && *B == '.' && B[1] == _13 && B[2] == _10 )
        //  Mark the end of the body.
        //  NNTP messages end with: ".\r\n".  _13 == 13
        //  IMAP messages end with: ".\x7F\x7F OK".   _13 == 127
        E_Enc = E_Hdr = B, Loc( uc0, B ), P_In = E_Art = E = ::_P + CRorLF + CRnLF ;

    //  An OK download; set the line fragment aside.
    szII = E_In - E, E_In = E, Ch_E_In = *E_In, *E_In = 0 ;  Rtn(0);  }

Near Globals:

  const int  OneMeg = 999000, MaxLineLen = 999 ;

  #define Rtn( Err )  return !( ErrDia = Err )

  int UTF16, _ViaHTTP, _BinBody, Cmd, Count_Down, szII, Append, _13 = 13, _10 = 10 ;
  uchar  Ch_E_In, B_In[ OneMeg ]; 
  _LnP  B_SubHdr, B_Head, P_In, E_In, E_Enc, E_Hdr, E_Art ;

Far Globals:

  const int  szChr = sizeof( wchar );

  typedef wchar_t  wchar ;  typedef unsigned char  uchar ;
  typedef wchar  *LnP ;  typedef uchar  *_LnP ;  typedef char  *__LnP ;
  typedef LARGE_INTEGER  DubInt ;

  #define  Tics ( QueryPerformanceCounter( ( DubInt * ) & _Tics ), _Tics )
  #define  Secs ( _Secs = Tics / _Hz )
  #define  Str_Stk  _vsnwprintf

   //  "ErrDia" holds a ServerDialog Error.
  int ForAppDone, ErrDia ;  u64  _Tics, Hz ;  double _Secs, _Hz ;

  //  Get the CPU's Hz ( tic rate ).
  QueryPerformanceFrequency( ( DubInt * ) & Hz ), _Hz = Hz ;
 
  //  Responds to System/User Events.
  void Respond();

  //  Set the TaskBar text and the StatusBar of my custom console.
  Notice( LnP S, ... );

  //  Return the bigER one.
  int ER( int X, int Y ) { return X > Y ? X : Y ;  } 

Jeff-Relf.Me

unread,
Jan 15, 2017, 9:11:16 AM1/15/17
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
[ Oops, this corrects my previous code/post ]
Reading HTTP, NNTP, IMAP, SMTP, NTP etc.; UTF 8|16 or binary:

// DownLoad Example: http://Jeff-Relf.Me/Posts.TXT
// Help/Settings: http://Jeff-Relf.Me/X.HTM
//
// "LineOrHdr()", below, reads in a full line, a full header,
// and/or a full "chunk header", as servers will split them.

int LineOrHdr() { int rv, Room, _Append, Done ; double Mark ;
_LnP B, P, E ; _Append = Append, Append = Done = 0 ;
if ( !_Append )
// Mark the start of the _header, instead of adding to it.
// The Header can't be larger than a MeagaByte.
//
// "B_Head" marks the start of a _full line, or a _full header;
// "P_In" is scanning into it.
// Initially: P_In = E_In = B_In ; uchar B_In[ OneMeg ];
B_Head = P_In ;

// E_In is the end of the received data;
// here, it's extended by szII, the size of the previous line fragment.

*E_In = Ch_E_In, E_In += szII, szII = Ch_E_In = *E_In = 0 ;

if ( ( B_SubHdr ? B_SubHdr : P_In ) + MinSubHdr > E_In ) {

// "Transfer-Encoding" "chunked" ( B_SubHdr ) has many "chunk headers"
// which must be at least MinSubHdr bytes long.
// Keep coming here, "Recv:", until you get a _full line.

Recv: if ( rv = B_Head - B_In )

// Reclaim space; memmove() "B_Head" to "B_In[]".
memmove( B_In, B_Head, E_In - B_Head ), B_Head -= rv,
B_SubHdr -= ( B_SubHdr ? rv : 0 ), P_In -= rv, E_In -= rv ;

// Calculate the (free) buffer size and start the timer.
*E_In = 0, Room = OneMeg - ( E_In - B_In ) - 9, Mark = Secs ;

if ( Room < 99 ) {
Notice( L"No \"Text\" line may exceed 1 MegaByte." ), disConn; Rtn(-1); }

LOOP {

if ( Sz = recv( Connected, __LnP( E_In ), Room, 0 ),
!Sz && ( Count_Down = 0, Done = _ViaHTTP ) || Sz > 0 )

// Got data. Note if the URL is downloaded.
goto OnLine ;

if ( rv = WSAGetLastError(), rv == WSAEWOULDBLOCK ) {

// Data will come later, the server says.
if ( Secs > Mark + Time_Out ) {
Notice( L"User Timed Out, %d seconds.", Time_Out ),
disConn; Rtn(-2); }

if ( Respond(), Game != ServerIO )
// Respond() says the User Canceled the DownLoad.
Rtn(-3);

// Check the server ( BusyRead ) again.
continue ; }

Notice( L"Server Timed Out, WSAGetLastError(): %d.", rv ),
disConn; Rtn(-4); }

// Data was DownLoaded; Mark the end.
OnLine: E_In += Sz, *E_In = Ch_E_In = 0 ; }

if ( Done || _BinBody )
// An OK download ( _BinBody or a completed HTTP download ).
Rtn(0);

// Scan backwards, looking for a NewLine.
// Google will send _over 64 KiloBytes at a time, in one recv();
// yet, at times, there's no NewLine; and it doesn't use CR LF.
B = P_In, E = E_In ;
if ( !InBody ) while( E > B && *--E != 10 );
else if ( !UTF16 ) while( E > B && ( Ch = *--E, !CRorLF ) );
else while( E - 1 > B && ( *--E || ( Ch = *--E, !CRorLF ) ) );

if ( !InBody ? *E != 10 : !CRorLF )

// No full line, just a fragment; check the server again.
// Max Line Length is: " OneMeg - 99 ".
//
// Headers and such _Must end in CR LF ( 13, 10 );
// "InBody", 13 and/or 10 is OK.

goto Recv;

// An OK download, found a full line; set the line fragment aside.
E += 1 + UTF16, szII = E_In - E, E_In = E,
Ch_E_In = *E_In, *E_In = 0 ; Rtn(0); }

Near Globals:

const int OneMeg = 999000, MinSubHdr = 5 /* "\r\n0\r\n", Hex */ ;

#define Rtn( Err ) return !( ErrDia = Err )

int UTF16, _ViaHTTP, _BinBody, Count_Down, szII, Append, InBody ;
uchar Ch_E_In, B_In[ OneMeg ];
_LnP B_SubHdr, B_Head, P_In, E_In ;

Mr Flibble

unread,
Jan 15, 2017, 12:50:25 PM1/15/17
to
On 15/01/2017 04:56, Jeff-Relf.Me wrote:
> Reading HTTP, NNTP, IMAP, SMTP, NTP etc.; UTF 8|16 or binary:
[vomit puddle snipped]

Your coding style including the use of the "goto" keyword is egregious
mate. Please stop spamming your shit to this newsgroup.

/Flibble

woodb...@gmail.com

unread,
Jan 15, 2017, 3:12:20 PM1/15/17
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
On Sunday, January 15, 2017 at 11:50:25 AM UTC-6, Mr Flibble wrote:

Please don't swear here.


Brian
Ebenezer Enterprises - In G-d we trust.
http://webEbenezer.net

Mr Flibble

unread,
Jan 15, 2017, 4:10:42 PM1/15/17
to
On 15/01/2017 20:12, woodb...@gmail.com wrote:
> On Sunday, January 15, 2017 at 11:50:25 AM UTC-6, Mr Flibble wrote:
>
> Please don't swear here.

Fuck off you annoying cunt.

Jeff-Relf.Me

unread,
Jan 16, 2017, 1:19:10 AM1/16/17
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
You ( Leigh Johnston ) replied ( to me ):
> > Reading HTTP, NNTP, IMAP, SMTP etc.; UTF 8|16 or binary:
> [ vomit puddle snipped ]
>
> Your coding style, including the use of "goto",
> is egregious, mate.
> Please stop spamming your shit to this newsgroup.

"#define" and "goto" are like fast cars;
Yes, they're dangerous, but I _love them anyway.

The code I post here not for you, or anyone else,
but for myself, so I can think about it, and change it;
I'm changing it now, and continue doing so.

Whenever you see a lot of WhiteSpace and comments,
as here, you know _immediately that there's _problems.

My latest:

// DownLoad Example: http://Jeff-Relf.Me/Posts.TXT
// Help/Settings: http://Jeff-Relf.Me/X.HTM
//
// "Text" servers give you bits and pieces, line fragments.
// "gFull()", below, ensures that you get full lines;
// or, optionally, a full header ( HTTP, NNTP, IMAP ).

int gFull() { int rv, Ch0, Ch, Ch2, Room, _FullHdr, Done ; double Mark ;
_LnP B, P, E ; _FullHdr = FullHdr, Ch = FullHdr = Done = 0 ;

// "P_In" marks the start of a _full line, or a _full header;
// Initially: P_In = E_In = B_In ; uchar B_In[ OneMeg ];
// E_In is the end of the received data;
// here, it's extended by szII, the size of the previous line fragment.

*LnP(E_In) = Ch_E_In, E_In += szII, szII = Ch_E_In = *LnP(E_In) = 0 ;

if ( ( B_Chunk ? B_Chunk : P_In ) >= E_In ) {

// Previous data has been used up, get more.
// In a "Transfer-Encoding" "chunked" body,
// "B_Chunk" points to a "chunk header".
//
// Return here, to "Recv:", to get a _Full line|header.

Recv: if ( rv = P_In - B_In )

// Reclaim space; memmove() "P_In" to "B_In[]".

memmove( B_In, P_In, E_In - P_In + 2 ),
P_In -= rv, E_In -= rv, !B_Chunk ? 0 : ( B_Chunk -= rv ) ;

// Calculate the (free) buffer size and start the timer.
*E_In = 0, Room = OneMeg - ( E_In - B_In ) - 9, Mark = Secs ;

if ( Room < 99 ) {
Notice( L"No Header ( or line ) may exceed 1 MegaByte." ),
disConn; Rtn(-1); }

LOOP {

if ( Sz = recv( Connected, __LnP( E_In ), Room, 0 ),
!Sz && ( E_Art = E_In + Sz, Done = _ViaHTTP ) || Sz > 0 )

// Got data. When "Done", "E_Art" marks the end.
goto OnLine ;

if ( rv = WSAGetLastError(), rv == WSAEWOULDBLOCK ) {

// Wait on the server.

if ( Secs > Mark + Time_Out ) {
Notice( L"The User Timed Out, %d seconds.", Time_Out ),
disConn; Rtn(-2); }

if ( Respond(), Game != ServerIO )

// The User Canceled the DownLoad.
Rtn(-3); continue ; }

Notice( L"The Server Timed Out, WSAGetLastError(): %d.", rv ),
disConn; Rtn(-4); }

// Got Data; Null and "E_In" mark the end.
OnLine: E_In += Sz, *LnP(E_In) = Ch_E_In = 0 ; }

if ( Done || _BinBody ) Rtn(0);

if ( P = P_In, _FullHdr ) {

// When it's just a header, no body,
// we need the "\r\n.\r\n"; otherwise get "\r\n\r\n".

LoopP( Ch != 13 || Ch2 != 10 || !( Ch0 == 10 || Ch0 == '.' && P[-2] == 10 ) );
Ch = Ch2 ; }

// Headers and such _Must end in CR LF ( 13, 10 );
// "InBody", 13 and/or 10 is OK.

else if ( !InBody ) { LoopP( Ch != 10 ); }
else if ( !UTF16 ) { LoopP( !CRorLF ); }
else { LnP P = LnP( P_In ), B = P ; LoopP( !CRorLF ); }

if ( !Ch )
// No full Header|Line, just a fragment; ReadIn more.
goto Recv;

if ( !InBody ) Rtn(0);

// Scan backwards for the line fragment, in the body.

if ( B = P_In, E = E_In, !UTF16 )
while( E > B && ( Ch = *--E, !CRorLF ) );
else while( E - 1 > B && ( *--E || ( Ch = *--E, !CRorLF ) ) );

// An OK download, got one full line, at least.
// "szII", "E_In" and "Ch_E_In" MarkOff the line fragment.

E += 1 + UTF16, szII = E_In - E, E_In = E,
Ch_E_In = *LnP(E_In), *LnP(E_In) = 0 ; Rtn(0); }

Near Globals:

const int OneMeg = 999000 ;

#define Rtn( Err ) return !( ErrDia = Err )

// "ErrDia" holds a ServerDialog Error.

int ErrDia, UTF16, _ViaHTTP, _BinBody, szII, FullHdr, InBody ;
wchar Ch_E_In ; uchar B_In[ OneMeg ];
_LnP B_Chunk, P_In, E_In, E_Art ;

Far Globals:

const int szChr = sizeof( wchar );

typedef wchar_t wchar ; typedef unsigned char uchar ;
typedef wchar *LnP ; typedef uchar *_LnP ; typedef char *__LnP ;
typedef LARGE_INTEGER DubInt ;

#define Tics ( QueryPerformanceCounter( ( DubInt * ) & _Tics ), _Tics )
#define Secs ( _Secs = Tics / _Hz )
#define CRorLF ( Ch == 13 || Ch == 10 )

// "LoopP()" loops P through a null terminated line.
// When "Bool" allows, it loops up to, and including, the null,
// setting Ch0, Ch, and Ch2 ( for Bool ), as it goes.

#define LoopP( Bool ) Ch = 1, Ch2 = 0, P-- ; \
while( ( Ch0 = Ch ) && ( Ch = *++P, Ch2 = !Ch ? 0 : P[1], Bool ) )

David Brown

unread,
Jan 16, 2017, 2:46:43 AM1/16/17
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
On 16/01/17 07:18, Jeff-Relf.Me wrote:
> You ( Leigh Johnston ) replied ( to me ):
>>> Reading HTTP, NNTP, IMAP, SMTP etc.; UTF 8|16 or binary:
>> [ vomit puddle snipped ]
>>
>> Your coding style, including the use of "goto",
>> is egregious, mate.
>> Please stop spamming your shit to this newsgroup.
>
> "#define" and "goto" are like fast cars;
> Yes, they're dangerous, but I _love them anyway.

No, they are nothing like fast cars. #define has its uses - but what
you write is abuse. It is obfuscation.

>
> The code I post here not for you, or anyone else,
> but for myself, so I can think about it, and change it;
> I'm changing it now, and continue doing so.
>

Since your code is not meant for anyone else, and everyone else thinks
it is hideous (I honestly thought your "style guide" was a humorous list
of every bad idea you could imagine), just don't post it. People who
are experienced programmers will immediately reject your mess, but it's
possible that people new to C++ might think this is what code is
supposed to look like.

Jeff-Relf.Me

unread,
Jan 19, 2017, 6:49:48 AM1/19/17
to
Why this is marked as abuse? It has been marked as abuse.
Report not abuse
You ( MeSham ) asked me:
> You have to post your crap code on a ng to look at it yourself?

Yes.  Posting code helps me concentrate.

Usenet is the wild, wild west, anything goes.

99% of what I write is ignored, "meh".
99% if the rest is just insults.
1% of 1% is a (scary) "I liked it".
0 new messages