text:
<repo_name>peiranli/KNN<file_sep>/hw2.py
import numpy as np
import math
# Load data set and code labels as 0 ='NO', 1='DH', 2='SL'
labels = ['NO','DH','SL']
data = np.loadtxt('column_3C.dat',converters={6: lambda s: labels.index(s)})
# Separate features from labels
x = data[:, 0:6]
y = data[:, 6]
#Divide into training and test set
training_indices = range(0,80)+range(100,148)+range(160,280)
test_indices = range(80,100)+range(148,160)+range(280,310)
trainx = x[training_indices, :]
trainy = y[training_indices]
testx = x[test_indices, :]
testy = y[test_indices]

def L1_distance(x1,x2):
    distance = 0
    for index in range(0,6):
        distance_i = abs(x1[index]-x2[index])
        distance += distance_i
    return distance

def L2_distance(x1,x2):
    distance = 0
    for index in range(0,6):
        distance_i = math.pow((x1[index]-x2[index]),2)
        distance += distance_i
    return math.sqrt(distance)

def create_result_vector(length):
    result = []
    for i in range(length):
        result.append(-1)
    return result

def nearest_neighbor_classifier(testx, trainx, testy, trainy, distance_function):
    test_length = len(testx)
    train_length = len(trainx)
    result = create_result_vector(test_length)
    for i in range(test_length):
        min_distance = distance_function(testx[i], trainx[0])
        label = trainy[0]
        for j in range(train_length):
            distance_j = distance_function(testx[i], trainx[j])
            if distance_j < min_distance:
                min_distance = distance_j
                label = trainy[j]
        result[i] = label
    return result

def calculate_err_rate(result, testy):
    err = 0
    for i in range(len(testy)):
        if result[i] != testy[i]:
            err += 1
    return float(err)/float(len(testy))

def confusion_matrix(result, testy):
    matrix = np.zeros(shape=(3,3))
    for i in range(len(result)):
            if testy[i] == 0 and result[i] == 0:
                matrix[0][0] += 1
            if testy[i] == 0 and result[i] == 1:
                matrix[0][1] += 1
            if testy[i] == 0 and result[i] == 2:
                matrix[0][2] += 1
            if testy[i] == 1 and result[i] == 0:
                matrix[1][0] += 1
            if testy[i] == 1 and result[i] == 1:
                matrix[1][1] += 1
            if testy[i] == 1 and result[i] == 2:
                matrix[1][2] += 1
            if testy[i] == 2 and result[i] == 0:
                matrix[2][0] += 1
            if testy[i] == 2 and result[i] == 1:
                matrix[2][1] += 1
            if testy[i] == 2 and result[i] == 2:
                matrix[2][2] += 1
    return matrix

result_l1 = nearest_neighbor_classifier(testx, trainx, testy, trainy, L1_distance)
err_rate_l1 = calculate_err_rate(result_l1, testy)
print "error rate for l1 distance: {0}".format(err_rate_l1)
print confusion_matrix(result_l1, testy)

result_l2 = nearest_neighbor_classifier(testx, trainx, testy, trainy, L2_distance)
err_rate_l2 = calculate_err_rate(result_l2, testy)
print "error rate for l2 distance: {0}".format(err_rate_l2)
print confusion_matrix(result_l2, testy)<file_sep>/hw2_test.py
import numpy as np
import math
# Load data set and code labels as 0 ='NO', 1='DH', 2='SL'
labels = ['NO','DH','SL']
data = np.loadtxt('column_3C.dat',converters={6: lambda s: labels.index(s)})
# Separate features from labels
x = data[:, 0:6]
y = data[:, 6]
#Divide into training and test set
training_indices = range(0,80)+range(100,148)+range(160,280)
test_indices = range(80,100)+range(148,160)+range(280,310)
trainx = x[training_indices, :]
trainy = y[training_indices]
testx = x[test_indices, :]
testy = y[test_indices]

def L1_distance(x1,x2):
    distance = 0
    for index in range(0,6):
        distance_i = abs(x1[index]-x2[index])
        distance += distance_i
    return distance

def euclideanDist(x, xi):
    d = 0.0
    for i in range(len(x)-1):
        d += pow((float(x[i])-float(xi[i])),2)  #euclidean distance
    d = math.sqrt(d)
    return d

#KNN prediction and model training
def nn_predict(test_data, train_data):
    for i in test_data:
        dist = enclideanDist()
        for j in train_data:
            eu_dist = enclideanDist(i,j)

#Accuracy calculation function
def accuracy(test_data):
    correct = 0
    for i in test_data:
        if i[5] == i[6]:
            correct += 1
    accuracy = float(correct)/len(test_data) *100  #accuracy
    return accuracy

nn_predict(testx, trainx)
print test_dataset
print "Accuracy : ",accuracy(testx)

repo_language: Python

repo_name: peiranli/KNN


text:
<repo_name>talvane/hbstomp<file_sep>/lib/StompFrameHeader.class.prg
#include "stomp.ch"

CLASS TStompFrameHeader

  METHOD new( cName, cValue ) CONSTRUCTOR
  METHOD toString()
  METHOD getName()
  METHOD getValue()

  HIDDEN:
    DATA cName
    DATA cValue

ENDCLASS

METHOD new( cName, cValue ) CLASS TStompFrameHeader

  DO CASE
  CASE ( ValType( cName ) == "C" )
  CASE ( ValType( cName ) == "M" )
    BREAK
  OTHERWISE
    //Throw( ErrorNew( "EStompHeaderInvalidType",,, ProcName(), "Invalid type for StompHeader:Name." ) )
  END CASE

  DO CASE
  CASE ( ValType( cValue ) == "C" )
  CASE ( ValType( cValue ) == "M" )
    BREAK
  OTHERWISE
    //Throw( ErrorNew( "EStompHeaderInvalidType",,, ProcName(), "Invalid type for StompHeader:Value." ) )
  END CASE

  ::cName  := cName
  ::cValue := cValue
RETURN ( self )

METHOD getName() CLASS TStompFrameHeader
  RETURN ( ::cName )

METHOD getValue() CLASS TStompFrameHeader
  RETURN ( ::cValue )

METHOD toString() CLASS TStompFrameHeader
  RETURN ( ::cName + ":" + ::cValue )<file_sep>/include/stomp_frame.ch
#ifndef _STOMP_FRAME_CH
#define _STOMP_FRAME_CH

  // ASCII CHARACTERS

  #define CHR_NULL  chr(0)
  #define CHR_CR    chr(13)
  #define CHR_LF    chr(10)
  #define CHR_CRLF  CHR_CR+CHR_LF

  // STOMP FRAME CLIENT COMMANDS

  #define STOMP_CLIENT_COMMAND_SEND          "SEND"
  #define STOMP_CLIENT_COMMAND_SUBSCRIBE     "SUBSCRIBE"
  #define STOMP_CLIENT_COMMAND_UNSUBSCRIBE   "UNSUBSCRIBE"
  #define STOMP_CLIENT_COMMAND_BEGIN         "BEGIN"
  #define STOMP_CLIENT_COMMAND_COMMIT        "COMMIT"
  #define STOMP_CLIENT_COMMAND_ABORT         "ABORT"
  #define STOMP_CLIENT_COMMAND_ACK           "ACK"
  #define STOMP_CLIENT_COMMAND_NACK          "NACK"
  #define STOMP_CLIENT_COMMAND_DISCONNECT    "DISCONNECT"
  #define STOMP_CLIENT_COMMAND_CONNECT       "CONNECT"
  #define STOMP_CLIENT_COMMAND_STOMP         "STOMP"

  //STOMP FRAME SERVER COMMANDS

  #define STOMP_SERVER_COMMAND_CONNECTED     "CONNECTED"
  #define STOMP_SERVER_COMMAND_MESSAGE       "MESSAGE"
  #define STOMP_SERVER_COMMAND_RECEIPT       "RECEIPT"
  #define STOMP_SERVER_COMMAND_ERROR         "ERROR"

  //STOMP SUBSCRIBE SUPPORTED ACK MODES

  #define STOMP_SUBSCRIBE_AUTO_ACK_MODE               "auto"
  #define STOMP_SUBSCRIBE_CLIENT_ACK_MODE             "client"
  #define STOMP_SUBSCRIBE_CLIENT_INDIVIDUAL_ACK_MODE  "client-individual"
  #define STOMP_ACK_MODES { STOMP_SUBSCRIBE_AUTO_ACK_MODE, STOMP_SUBSCRIBE_CLIENT_ACK_MODE, STOMP_SUBSCRIBE_CLIENT_INDIVIDUAL_ACK_MODE }

#endif<file_sep>/lib/StompSocket.class.prg
#include "stomp.ch"

CLASS TStompSocket

  DATA hSocket
  DATA nStatus
  DATA oError
  DATA cBuffer
  DATA cReceivedData
  DATA cHost
  DATA nPort

  METHOD new() CONSTRUCTOR

  METHOD connect( cHost, nPort )  VIRTUAL
  METHOD send( cStompFrame )      VIRTUAL
  METHOD receive()                VIRTUAL
  METHOD disconnect()             VIRTUAL

ENDCLASS

METHOD new() CLASS TStompSocket
  LOCAL oReturn
  #ifdef __HARBOUR__
  oReturn := TStompSocketHarbour():new()
  #else
  #ifdef __PROTHEUS__
  oReturn := TStompSocketADVPL():new()
  #endif
  #endif
  RETURN ( oReturn )<file_sep>/tests/StompFrameBuilder.test.prg
#include "stomp.ch"

CLASS TTestStompFrameBuilder FROM TTestCase

  METHOD testBuildConnectFrame()
  METHOD testBuildDisconectFrame()
  METHOD testBuildConnectFrameWithoutHost()
  METHOD testBuildConnectFrameWithLoginInfo()
  METHOD testBuildSubscribeFrame()

ENDCLASS

METHOD testBuildConnectFrame() CLASS TTestStompFrameBuilder
  LOCAL oStompFrame

  oStompFrame := TStompFrameBuilder():buildConnectFrame( "127.0.0.1" )

  ::assert:true( oStompFrame:isValid(), "frame should be valid")
  ::assert:equals( oStompFrame:cCommand, STOMP_CLIENT_COMMAND_STOMP,  "Frame command should be STOMP" )
  ::assert:equals( oStompFrame:getHeaderValue( STOMP_ACCEPT_VERSION_HEADER ), STOMP_ACCEPTED_VERSIONS, "accepted-versions header should default" )
  ::assert:equals( oStompFrame:getHeaderValue("host"), "127.0.0.1", "header host should be '127.0.0.1'" )

  RETURN ( nil )

METHOD testBuildConnectFrameWithoutHost() CLASS TTestStompFrameBuilder
  LOCAL oStompFrame

  oStompFrame := TStompFrameBuilder():buildConnectFrame(,,)
  ::assert:false( oStompFrame:isValid(), "frame should not be valid without host")

  RETURN ( nil )

METHOD testBuildConnectFrameWithLoginInfo() CLASS TTestStompFrameBuilder
  LOCAL oStompFrame

  oStompFrame := TStompFrameBuilder():buildConnectFrame( , 'user', 'pass' )
  ::assert:true( oStompFrame:headerExists(STOMP_LOGIN_HEADER), "header login should exist" )
  ::assert:true( oStompFrame:headerExists(STOMP_PASSCODE_HEADER), "header passcode should exist" )

  RETURN ( nil )

METHOD testBuildDisconectFrame() CLASS TTestStompFrameBuilder
  LOCAL oStompFrame

  oStompFrame := TStompFrameBuilder():buildDisconnectFrame( "receipt-1" )

  ::assert:true( oStompFrame:isValid(), "frame should be valid" )
  ::assert:equals( oStompFrame:cCommand, STOMP_CLIENT_COMMAND_DISCONNECT, "Frame command should be DISCONNECT" )

 RETURN ( nil )

 METHOD testBuildSubscribeFrame() CLASS TTestStompFrameBuilder
   LOCAL oStompFrame

   oStompFrame := TStompFrameBuilder():buildSubscribeFrame( "/queue/destination" )

   ::assert:true( oStompFrame:isValid(), "frame should be valid" )
   ::assert:equals( oStompFrame:cCommand, STOMP_CLIENT_COMMAND_SUBSCRIBE, "Frame command should be SUBSCRIBE" )
   ::assert:equals( LEN( oStompFrame:getHeaderValue( STOMP_ID_HEADER ) ), LEN( HBSTOMP_IDS_PREFIX ) + HBSTOMP_IDS_LENGHT, "the size of id header should match" )

 RETURN ( nil )<file_sep>/Makefile
.PHONY: all build test clean

all: build

build:
	hbmk2 makefile.hbp

test:
	hbmk2 -run tests.hbp

clean:
	rm libhbunit.*<file_sep>/include/stomp_totvs_compat.ch
#ifndef _STOMP_TOTVS_COMPAT_CH
#define _STOMP_TOTVS_COMPAT_CH

  #include "tryexception.ch"

  #xtranslate HIDDEN: =>
  #xtranslate EXPORTED: =>

#endif<file_sep>/include/stomp.ch
#ifndef _STOMP_CH
#define _STOMP_CH

  #define DEBUG

  #ifdef PROTHEUS
    #define __PROTHEUS__
    #include "totvs.ch"
    #include "stomp_totvs_compat.ch"
  #else
    #ifdef __HARBOUR__
      #include "hbclass.ch"
      #include "hbsocket.ch"
    #endif
  #endif

  #include "stomp_frame.ch"
  #include "stomp_frame_header.ch"
  #include "stomp_socket.ch"

  #define STOMP_DEFAULT_PORT 61613

  // Limits -- http://stomp.github.io/stomp-specification-1.2.html#Size_Limits

  #define STOMP_HEADERS_COUNT_LIMIT 10
  #define STOMP_HEADER_SIZE_LIMIT   256
  #define STOMP_BODY_SIZE_LIMIT     (64*1024)

  #define HBSTOMP_IDS_PREFIX "hbstomp-"
  #define HBSTOMP_IDS_LENGHT 16

#endif<file_sep>/lib/StompUtils.prg
//TODO - implement real randomness ;)
FUNCTION RandonAlphabet(nLen)
  LOCAL i := 0, cReturn := "",seconds := Seconds()

  DO WHILE (i < nLen)
    rand := seconds%57 + 65
    seconds -= Seconds()%25

    IF ( INT(rand) >= 91 .AND. INT(rand) <= 96 )
      LOOP
    ELSE
      i++
      cReturn += CHR(INT(rand))
    ENDIF

  ENDDO

  RETURN ( cReturn )
<file_sep>/lib/StompClient.class.prg
#include "stomp.ch"

//TODO - handle Stomp Server ERROR frames
//TODO - handle TStompSocke exceptions
//TODO - return exceptions to users of TStompClient
//TODO - handle receipts
//TODO - handle transactions

CLASS TStompClient

  METHOD new( cHost, nPort, cLogin, cPassword, cDestination, lSendReceipt ) CONSTRUCTOR
  METHOD connect()
  METHOD disconnect()
  METHOD publish( cDestination, cMessage )
  METHOD isConnected()
  METHOD getErrorMessage()
  METHOD subscribe( cDestination, cAck )
  METHOD readFrame()
  METHOD countFramesToRead()
  METHOD addFrame()

  DATA lRequireReceipt INIT .F.

  HIDDEN:
  DATA oSocket
  DATA cHost
  DATA nPort
  DATA cLogin
  DATA cPassword
  DATA cDestination
  DATA lConnected
  DATA cErrorMessage
  DATA aFrames
  DATA lHasLoginData INIT .F.
  DATA cSessionID
  DATA lSendReceipt
  DATA cLastReceipt
  DATA cLastMessage

ENDCLASS

METHOD new( cHost, nPort, cLogin, cPassword , cDestination, lSendReceipt ) CLASS TStompClient

  ::cHost := cHost
  ::nPort := nPort
  ::cDestination := cDestination

  IIF( ValType(lSendReceipt) != 'U', ::lSendReceipt := lSendReceipt, ::lSendReceipt := .F. )

  IF ( ValType(cLogin) == 'C' .AND. ValType(cPassword) == 'C')
    ::cLogin := cLogin
    ::cPassword := <PASSWORD>
    ::lHasLoginData := .T.
  ENDIF

  ::lConnected := .F.

  RETURN ( self )

METHOD connect() CLASS TStompClient
  LOCAL oStompFrame, cFrameBuffer

  //TODO - handle socket errors
  ::oSocket := TStompSocket():new()
  ::oSocket:connect( ::cHost, ::nPort )

  IF ::lHasLoginData
    oStompFrame := TStompFrameBuilder():buildConnectFrame( ::cDestination, ::cLogin, ::cPassword )
  ELSE
    oStompFrame := TStompFrameBuilder():buildConnectFrame( ::cDestination )
  ENDIF

  ::oSocket:send( oStompFrame:build() )

  IF ( ( ::oSocket:receive() > 0 ) )
    cFrameBuffer := ::oSocket:cReceivedData
    oStompFrame := oStompFrame:parse( cFrameBuffer )

    IF ( oStompFrame:cCommand == STOMP_SERVER_COMMAND_CONNECTED )
      ::lConnected := .T.
      ::cSessionID := oStompFrame:getHeaderValue( STOMP_SESSION_HEADER )
    ELSE
      IF ( oStompFrame:cCommand == STOMP_SERVER_COMMAND_ERROR )
        ::cErrorMessage := oStompFrame:getHeaderValue( STOMP_MESSAGE_HEADER )
      ENDIF
    ENDIF

  ENDIF

  RETURN ( nil )

METHOD getErrorMessage() CLASS TStompClient
  RETURN ( ::cErrorMessage )

METHOD publish( cDestination, cMessage ) CLASS TStompClient
  LOCAL oStompFrame, cReceiptID

  oStompFrame := TStompFrameBuilder():buildSendFrame( cDestination, cMessage )

  IF ( ::lSendReceipt == .T. )
    cReceiptID := HBSTOMP_IDS_PREFIX + RandonAlphabet( HBSTOMP_IDS_LENGHT )
    oStompFrame:addHeader( TStompFrameHeader():new( STOMP_RECEIPT_HEADER,  cReceiptID) )
  ENDIF

  ::oSocket:send( oStompFrame:build() )

  //TODO - implementar tratamento do retorno, caso exista mensagem reply-to
  IF ( ( ::oSocket:receive() > 0 ) )
    cFrameBuffer := ::oSocket:cReceivedData
    oStompFrame := oStompFrame:parse( cFrameBuffer )

    DO CASE
    CASE  oStompFrame:cCommand == STOMP_SERVER_COMMAND_MESSAGE
      ::cLastMessage := oStompFrame:cBody
    CASE  oStompFrame:cCommand == STOMP_SERVER_COMMAND_RECEIPT
      ::cLastReceipt := oStompFrame:getHeaderValue( STOMP_RECEIPT_ID_HEADER )
    CASE  oStompFrame:cCommand == STOMP_SERVER_COMMAND_ERROR
      ::cErrorMessage := oStompFrame:getHeaderValue( STOMP_MESSAGE_HEADER )
    ENDCASE

  ENDIF

  RETURN ( nil )

METHOD disconnect() CLASS TStompClient
  LOCAL oStompFrame

  oStompFrame := TStompFrameBuilder():buildDisconnectFrame()
  ::oSocket:send( oStompFrame:build() )

  ::oSocket:disconnect()

  ::lConnected := .F.

  RETURN ( nil )

METHOD isConnected() CLASS TStompClient
  RETURN ( ::lConnected )

METHOD subscribe( cDestination, cAck ) CLASS TStompClient
  LOCAL oStompFrame, i := 0, cFrameBuffer

  oStompFrame := TStompFrameBuilder():buildSubscribeFrame( cDestination )
  IIF( ValType( cAck ) == 'C', oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ACK_HEADER, cAck ) ), )

  ::oSocket:send( oStompFrame:build() )

  //FIXME : split received data in individual StompFrames
  IF ( ( nLen := ::oSocket:receive() ) > 0 )
    cFrameBuffer := ::oSocket:cReceivedData

    DO WHILE ( Len( cFrameBuffer ) > 0 )
      OutStd( "Frame N: ", STR( ++i ),  hb_EOL() )

      oStompFrame := oStompFrame:parse( @cFrameBuffer )

      IF ( !oStompFrame:isValid() )
        FOR i := 1 TO oStompFrame:countErrors()
          OutStd( "ERRO: ", oStompFrame:aErrors[i] )
        NEXT
      ENDIF

      IF ( oStompFrame:cCommand == STOMP_SERVER_COMMAND_MESSAGE )
        OutStd( "Frame Dump", hb_EOL(), oStompFrame:build() , hb_EOL() )
      ELSE
        IF ( oStompFrame:cCommand == STOMP_SERVER_COMMAND_ERROR )
          ::cErrorMessage := oStompFrame:cMessage
        ENDIF
      ENDIF
    ENDDO

  ENDIF
  RETURN ( nil )

METHOD countFramesToRead() CLASS TStompClient
  RETURN ( LEN( ::aFrames ) )

METHOD addFrame( oStompFrame ) CLASS TStompClient
  AADD( ::aFrames, oStompFrame )
  RETURN ( NIL )

METHOD readFrame() CLASS TStompClient
  LOCAL oStompFrame

  RETURN ( oStompFrame )
<file_sep>/tests/AllTestSuite.test.prg
#include "stomp.ch"

FUNCTION main()

  LOCAL oRunner := TTextRunner():New()
  LOCAL oSuite := TTestSuite():New()

  oSuite:AddTest( TTestStompFrame():new() )
  oSuite:AddTest( TTestStompFrameBuilder():new() )

  oRunner:Run( oSuite )

  RETURN ( nil )<file_sep>/.travis.yml
language: c
env:
  - HB_VER=3.0.0 HB_DIR=harbour-3.0.0 HB_URL=https://downloads.sourceforge.net/harbour-project/source/3.0.0/harbour-3.0.0-src.zip
  - HB_VER=3.2-dev HB_DIR=core-master HB_URL=https://github.com/harbour/core/archive/master.zip
  - HB_VER=3.4-dev HB_DIR=harbour-core-master HB_URL=https://github.com/vszakats/harbour-core/archive/master.zip
compiler: gcc
before_install:
  - sudo apt-get -qq update
  - sudo apt-get install -qq libncurses-dev
  - sudo apt-get install -qq libslang2-dev
  - sudo apt-get install -qq libpcre3-dev
  - sudo apt-get install -qq zlib1g-dev
  - sudo apt-get install -qq unzip
install:
  - wget $HB_URL -O /tmp/harbour-$HB_VER.zip
  - cd /tmp && unzip harbour-$HB_VER.zip && cd -
  - cd /tmp/$HB_DIR && HB_INSTALL_PREFIX=/usr/local HB_BUILD_3RDEXT=no HB_BUILD_CONTRIBS=xhb make && cd -
  - cd /tmp/$HB_DIR && sudo make install && cd -
  - sudo ldconfig -f /usr/local/etc/ld.so.conf.d/harbour.conf
  - wget https://github.com/endersonmaia/hbunit/releases/download/0.0.5-alpha/hbunit-0.0.5-alpha-linux.tgz
  - tar -xvzf hbunit-0.0.5-alpha-linux.tgz libhbunit.a
script:
  - make
  - make test
<file_sep>/tests/StompFrame.test.prg
#include "stomp.ch"

CLASS TTestStompFrame FROM TTestCase

  METHOD testSetBody()
  METHOD testSetCommand()
  METHOD testAddHeader()
  METHOD testCountHeaders()
  METHOD testValidateCommand()
  METHOD testHeaderExists()
  METHOD testGetHeaderValue()
  METHOD testValidateConnectRequiredHeaders()
  METHOD testValidateConnectedSendRequiredHeaders()
  METHOD testValidateCommandSubscribeHeaders()
  METHOD testValidateSubscribeAckModes()
  METHOD testValidateCommandUnsubscribeHeaders()
  METHOD testValidateCommandBeginHeaders()
  METHOD testValidateCommandCommitHeaders()
  METHOD testValidateCommandAbortHeaders()
  METHOD testValidateCommandAckHeaders()
  METHOD testValidateCommandNackHeaders()
  METHOD testValidateCommandsMustNotHaveBody()
  METHOD testParseConnectFrame()
  METHOD testParseTwoFrames()
  METHOD testRemoveAllHeaders()

  METHOD Setup()
  METHOD Teardown()
  METHOD clearFrame()

  DATA oStompFrame

ENDCLASS

METHOD Setup() CLASS TTestStompFrame
  ::oStompFrame := TStompFrame():new()
  RETURN ( NIL )

METHOD Teardown() CLASS TTestStompFrame
  ::oStompFrame := NIL
  RETURN ( NIL )

METHOD clearFrame() CLASS TTestStompFrame
  ::oStompFrame:setBody( "" )
  ::oStompFrame:setCommand( "" )
  ::oStompFrame:removeAllHeaders()

  RETURN ( nil )

METHOD testSetBody() CLASS TTestStompFrame

  ::oStompFrame:setBody( "corpo" )

  ::assert:equals( "corpo", ::oStompFrame:cBody, "cBody should be corpo")

  RETURN ( NIL )

METHOD testSetCommand() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "CONNECT" )
  ::assert:equals( "CONNECT", ::oStompFrame:cCommand,  "cCommand should be CONNECT." )

  ::oStompFrame:setCommand( "send" )
  ::assert:equals( "SEND", ::oStompFrame:cCommand,  "setCommand('send') should set CONNECT (upper-case)." )

  RETURN ( NIL )

METHOD testAddHeader() CLASS TTestStompFrame

  ::oStompFrame:addHeader( TStompFrameHeader():new( "name", "value" ) )

  ::assert:equals( "name", ::oStompFrame:aHeaders[1]:getName(), "oHeader:getName() should be name")
  ::assert:equals( "value", ::oStompFrame:aHeaders[1]:getValue(), "oHeader:getValue() should be value")

  RETURN ( NIL )

METHOD testCountHeaders() CLASS TTestStompFrame

  ::assert:equals( 0, ::oStompFrame:countHeaders(), "StompFrame:countHeaders() should return 0 (zero) when no headers is addes to StompFrame" )

  ::oStompFrame:addHeader( TStompFrameHeader():new( "name", "value" ) )
  ::assert:equals( 1, ::oStompFrame:countHeaders(), "StompFrame:countHeaders() should return 1 (one)" )

  ::oStompFrame:addHeader( TStompFrameHeader():new( "other", "value" ) )
  ::assert:equals( 2, ::oStompFrame:countHeaders(), "StompFrame:countHeaders() should return 2 (two)" )

  RETURN ( NIL )

METHOD testValidateCommand() CLASS TTestStompFrame

  ::clearFrame()
  ::assert:false( ::oStompFrame:isValid(), "should be false when stompframe has no command" )

  ::oStompFrame:setCommand( "DISCONNECT" )
  ::assert:true( ::oStompFrame:isValid(), "should be true with valid command" )

  ::oStompFrame:setCommand( "INVALIDCOMMAND" )
  ::assert:false( ::oStompFrame:isValid(), "should be true with valid command" )

  RETURN ( NIL )

METHOD testHeaderExists() CLASS TTestStompFrame

    ::oStompFrame:addHeader( TStompFrameHeader():new( "name", "value" ) )

    ::assert:true( ::oStompFrame:headerExists( "name" ), "should return .T. after added the checked header name" )
    ::assert:false( ::oStompFrame:headerExists( "inexistent" ), "should return .F. checking for unexisting header name")

    ::oStompFrame:addHeader( TStompFrameHeader():new( "other", "value" ) )
    ::oStompFrame:addHeader( TStompFrameHeader():new( "another", "value" ) )

    ::assert:true( ::oStompFrame:headerExists( "another" ), "checking third header shoud be true" )

  RETURN ( NIL )

METHOD testGetHeaderValue() CLASS TTestStompFrame

  ::oStompFrame:addHeader( TStompFrameHeader():new( "name", "value" ) )

  ::assert:equals( "value", ::oStompFrame:getHeaderValue("name"), "should be true for an existant header")

  ::assert:null( ::oStompFrame:getHeaderValue("noheader"), "should be nil searching for an unexistant header" )

  RETURN ( NIL )

METHOD testValidateConnectRequiredHeaders() CLASS TTestStompFrame

  ::clearFrame()
  ::oStompFrame:setCommand( "CONNECT" )
  ::assert:false( ::oStompFrame:isValid(), "should be false CONNECT without required headers")
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ACCEPT_VERSION_HEADER, "1.2" ) )
  ::assert:false( ::oStompFrame:isValid(), "should be false CONNECT with just one required header" )
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_HOST_HEADER, "127.0.0.1" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true CONNECT with all required headers" )

  ::clearFrame()
  ::oStompFrame:setCommand( "STOMP" )
  ::assert:false( ::oStompFrame:isValid(), "should be false STOMP without required headers")
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ACCEPT_VERSION_HEADER, "1.2" ) )
  ::assert:false( ::oStompFrame:isValid(), "should be false STOMP with just one required header" )
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_HOST_HEADER, "127.0.0.1" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true STOMP with all required headers" )

  RETURN ( NIL )

METHOD testValidateConnectedSendRequiredHeaders() CLASS TTestStompFrame

  ::clearFrame()
  ::oStompFrame:setCommand( "SEND" )
  ::assert:false( ::oStompFrame:isValid(), "should be false CONNECT without required headers")

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_DESTINATION_HEADER, "/queue/1" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true with destination required header" )

  RETURN ( NIL )

METHOD testValidateCommandSubscribeHeaders() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "SUBSCRIBE" )
  ::assert:false( ::oStompFrame:isValid(), "should be false SUBSCRIBE without required headers")

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_DESTINATION_HEADER, "/queue/2" ) )
  ::assert:false( ::oStompFrame:isValid(), "should be false SUBSCRIBE with just one required header" )

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ID_HEADER, "123" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true SUBSCRIBE with all required headers" )

  RETURN ( NIL )

METHOD testValidateSubscribeAckModes() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "SUBSCRIBE" )
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_DESTINATION_HEADER, "/queue/2" ) )
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ID_HEADER, "123" ) )
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ACK_HEADER, "client" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true SUBSCRIBE with a valid ACK mode" )

  ::oStompFrame:removeAllHeaders()
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_DESTINATION_HEADER, "/queue/2" ) )
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ID_HEADER, "123" ) )
  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ACK_HEADER, "INVALID" ) )
  ::assert:false( ::oStompFrame:isValid(), "should be false SUBSCRIBE with an invalid ACK mode" )

  RETURN ( NIL )

METHOD testValidateCommandUnsubscribeHeaders() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "UNSUBSCRIBE" )
  ::assert:false( ::oStompFrame:isValid(), "should be false UNSUBSCRIBE without required headers")

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ID_HEADER, "123" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true UNSUBSCRIBE with id required header" )

  RETURN ( NIL )

METHOD testValidateCommandAckHeaders() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "ACK" )
  ::assert:false( ::oStompFrame:isValid(), "should be false ACK without required headers")

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ID_HEADER, "123" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true ACK with id required header" )

  RETURN ( NIL )

METHOD testValidateCommandNackHeaders() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "NACK" )
  ::assert:false( ::oStompFrame:isValid(), "should be false NACK without required headers")

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_ID_HEADER, "123" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true NACK with id required header" )

  RETURN ( NIL )

METHOD testValidateCommandBeginHeaders() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "BEGIN" )
  ::assert:false( ::oStompFrame:isValid(), "should be false BEGIN without required headers")

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_TRANSACTION_HEADER, "123" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true BEGIN with id required header" )

  RETURN ( NIL )

METHOD testValidateCommandCommitHeaders() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "COMMIT" )
  ::assert:false( ::oStompFrame:isValid(), "should be false COMMIT without required headers")

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_TRANSACTION_HEADER, "123" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true COMMIT with id required header" )

METHOD testValidateCommandAbortHeaders() CLASS TTestStompFrame

  ::oStompFrame:setCommand( "ABORT" )
  ::assert:false( ::oStompFrame:isValid(), "should be false ABORT without required headers")

  ::oStompFrame:addHeader( TStompFrameHeader():new( STOMP_TRANSACTION_HEADER, "123" ) )
  ::assert:true( ::oStompFrame:isValid(), "should be true ABORT with id required header" )

  RETURN ( NIL )

METHOD testValidateCommandsMustNotHaveBody() CLASS TTestStompFrame

  ::clearFrame()
  ::oStompFrame:setBody("body")
  ::oStompFrame:setCommand("SUBSCRIBE")
  ::assert:false( ::oStompFrame:isValid(), "should be false SUBSCRIBE with a body" )
  ::oStompFrame:setCommand("UNSUBSCRIBE")
  ::assert:false( ::oStompFrame:isValid(), "should be false UNSUBSCRIBE with a body" )
  ::oStompFrame:setCommand("BEGIN")
  ::assert:false( ::oStompFrame:isValid(), "should be false BEGIN with a body" )
  ::oStompFrame:setCommand("COMMIT")
  ::assert:false( ::oStompFrame:isValid(), "should be false COMMIT with a body" )
  ::oStompFrame:setCommand("ABORT")
  ::assert:false( ::oStompFrame:isValid(), "should be false ABORT with a body" )
  ::oStompFrame:setCommand("ACK")
  ::assert:false( ::oStompFrame:isValid(), "should be false ACK with a body" )
  ::oStompFrame:setCommand("NACK")
  ::assert:false( ::oStompFrame:isValid(), "should be false NACK with a body" )
  ::oStompFrame:setCommand("DISCONNECT")
  ::assert:false( ::oStompFrame:isValid(), "should be false DISCONNECT with a body" )

  RETURN ( NIL )

METHOD testParseConnectFrame() CLASS TTestStompFrame
  LOCAL cStompFrame := "", oParsedFrame, oError

  // EOL is optional CR + LF or obrigatory LF
  cStompFrame += "COMMAND"        + CHR_CRLF
  cStompFrame += "header1:value1" + CHR_LF
  cStompFrame += "header2:value2" + CHR_CRLF
  cStompFrame += CHR_CRLF
  cStompFrame += "Body"           + CHR_NULL
  cStompFrame += CHR_CRLF         // OPTIONAL

  oParsedFrame := TStompFrame():new()
  oParsedFrame := oParsedFrame:parse( @cStompFrame )

  ::assert:equals( "COMMAND", oParsedFrame:cCommand, "oParsedFrame:cCommand should be 'COMMAND'" )
  ::assert:equals( "header1", oParsedFrame:aHeaders[1]:getName(), "oParsedFrame:aHeaders[1]:getName() should be 'header1'" )
  ::assert:equals( "value1", oParsedFrame:aHeaders[1]:getValue(), "oParsedFrame:aHeaders[1]:getValue() should be 'value1'" )
  ::assert:equals( "header2", oParsedFrame:aHeaders[2]:getName(), "oParsedFrame:aHeaders[2]:getName() should be 'header2'" )
  ::assert:equals( "value2", oParsedFrame:aHeaders[2]:getValue(), "oParsedFrame:aHeaders[2]:getValue() should be 'value2'" )
  ::assert:equals( "Body", oParsedFrame:cBody, "oParsedFrame:cBody should be 'Body'" )

  RETURN ( NIL )

METHOD testParseTwoFrames() CLASS TTestStompFrame
  LOCAL cStompFrame    := "", ;
        cStompFrameTwo := "", ;
        cStompFrameOne := "", ;
        oParsedFrame        , ;
        oError

  // EOL is optional CR + LF or obrigatory LF
  cStompFrameOne += "COMMAND_ONE"    + CHR_CRLF
  cStompFrameOne += "header1:value1" + CHR_LF
  cStompFrameOne += "header2:value2" + CHR_CRLF
  cStompFrameOne += CHR_CRLF
  cStompFrameOne += "Body One"       + CHR_NULL
  cStompFrameOne += CHR_CRLF         // OPTIONAL

  // EOL is optional CR + LF or obrigatory LF
  cStompFrameTwo += "COMMAND_TWO"    + CHR_CRLF
  cStompFrameTwo += "header1:value1" + CHR_LF
  cStompFrameTwo += "header2:value2" + CHR_CRLF
  cStompFrameTwo += CHR_CRLF
  cStompFrameTwo += "Body Two"       + CHR_NULL
  cStompFrameTwo += CHR_CRLF         // OPTIONAL

  cStompFrame := cStompFrameOne + cStompFrameTwo

  oParsedFrame := TStompFrame():new()
  oParsedFrame := oParsedFrame:parse( @cStompFrame )

  ::assert:equals( "COMMAND_ONE", oParsedFrame:cCommand, "cCommand should be COMMAND_ONE")
  ::assert:equals( "Body One", oParsedFrame:cBody, "cBody shoud be 'Body One'")

  oParsedFrame := oParsedFrame:parse( @cStompFrame )

  ::assert:equals( "COMMAND_TWO", oParsedFrame:cCommand, "cCommand should be COMMAND_TWO")
  ::assert:equals( "Body Two", oParsedFrame:cBody, "cBody shoud be 'Body Two'")

  RETURN ( NIL )

METHOD testRemoveAllHeaders() CLASS TTestStompFrame
  ::clearFrame()
  ::oStompFrame:addHeader( TStompFrameHeader():new("header1", "value1"))
  ::oStompFrame:removeAllHeaders()
  ::assert:equals(0, ::oStompFrame:countHeaders(), "::oStompFrame:countHeaders() should be 0 after ::oStompFrame:removeAllHeaders()")
  RETURN ( nil )<file_sep>/lib/StompSocketADVPL.class.prg
#include "stomp.ch"

#ifdef __PROTHEUS__
// See : http://tdn.totvs.com/display/tec/TSocketClient

CLASS TStompSocketADVPL FROM TStompSocket

  METHOD connect( cHost, nPort )
  METHOD send( cStompFrame )
  METHOD receive()
  METHOD disconnect()

ENDCLASS

METHOD connect( cHost, nPort ) CLASS TStompSocketADVPL

  ::hSocket    := tSocketClient():new()
  ::hSocket:Connect( nPort, cHost, 10 )

  IIF (::hSocket:IsConnected(), ::nStatus := STOMP_SOCKET_STATUS_CONNECTED, ::nStatus := STOMP_SOCKET_STATUS_CONNECTION_FAILED)

  RETURN ( nil )

METHOD send( cStompFrame ) CLASS TStompSocketADVPL

  ::cReceivedData := ::hSocket:send( cStompFrame )

  IF ( ::cReceivedData == Len(cStompFrame) )
    ::nStatus := STOMP_SOCKET_STATUS_DATA_SENT
  ELSE
    ::nStatus := STOMP_SOCKET_STATUS_SEND_FAILED
  ENDIF

  RETURN ( nil )

METHOD receive() CLASS TStompSocketADVPL

  cBuffer := ""
  nResp := oObj:Receive( @cBuffer, 10000 )
  if( nResp >= 0 )
      conout( "--> Dados Recebidos " + StrZero(nResp,5) )
      conout( "--> ["+cBuffer+"]" )
  else
      conout( "--> Não recebi dados" )
  endif

  RETURN ( nil )

METHOD disconnect() CLASS TStompSocketADVPL

  oObj:CloseConnection()

  RETURN ( nil )

#endif<file_sep>/tests/fake/StompSocketFake.class.prg
#include "stomp.ch"

CLASS TStompSocketFake FROM TStompSocket

  DATA hSocket
  DATA nStatus
  DATA oError
  DATA cBuffer
  DATA cReceivedData
  DATA cHost
  DATA nPort

  METHOD new() CONSTRUCTOR

  METHOD connect( cHost, nPort )  VIRTUAL
  METHOD send( cStompFrame )      VIRTUAL
  METHOD receive()                VIRTUAL
  METHOD disconnect()             VIRTUAL

ENDCLASS

METHOD new()
	RETURN ( self )<file_sep>/README.md
# hbstomp [![Build Status](https://travis-ci.org/endersonmaia/hbstomp.svg)](https://travis-ci.org/endersonmaia/hbstomp)

Library for Harbour/ADVPL that implements STOMP messaging protocol (http://stomp.github.io).

## Goals

These are the initial goals of this library

- Build and validates a message;
- Send messages to STOMP Server;
- Parse STOMP server responses;
- Learn Harbour and ADVPL programming;
- Get rich :moneybag: ;

## How-to Use it

With this version, you can build and send basic STOMP Client Frames. Subscribing to STOMP queues isn't working at the moment.

````xbase
PROCEDURE MAIN()

  oStompClient := TStompClient():new("127.0.0.1", 61613)
  oStompClient:connect()

  IF ( oStompClient:isConnected() )

    oStompClient:publish( "/queue/hbstomp", "First message." )
    oStompClient:publish( "/queue/hbstomp", "Second message!" )

    oStompClient:disconnect()
  ELSE
    OutStd( "Failed to connect.", hb_EOL() )
    OutStd( "Message: ", oStompClient:getErrorMessage(), hb_EOL() )
    ErrorLevel(1)
  ENDIF

  RETURN ( NIL )
````

# License

The MIT License (MIT)

Copyright (c) 2014 <NAME> <endersonmaia (_at_) gmail (_dot_) com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
<file_sep>/include/stomp_frame_header.ch
#ifndef _STOMP_FRAME_HEADER_CH
#define _STOMP_FRAME_HEADER_CH

// GENERAL
#define STOMP_ACCEPTED_VERSIONS       	"1.0,1.1,1.2"

// DEFAULT HEADERS
#define STOMP_ACCEPT_VERSION_HEADER "accept-version"
#define STOMP_HOST_HEADER           "host"
#define STOMP_DESTINATION_HEADER    "destination"
#define STOMP_ID_HEADER             "id"
#define STOMP_TRANSACTION_HEADER    "transaction"
#define STOMP_CONTENT_LENGTH_HEADER "content-length"
#define STOMP_CONTENT_TYPE_HEADER   "content-type"
#define STOMP_RECEIPT_HEADER        "receipt"
#define STOMP_LOGIN_HEADER          "login"
#define STOMP_PASSCODE_HEADER       "passcode"
#define STOMP_HEART_BEAT_HEADER     "heart-beat"
#define STOMP_SESSION_HEADER        "session"
#define STOMP_SERVER_HEADER         "server"
#define STOMP_ACK_HEADER            "ack"
#define STOMP_MESSAGE_ID_HEADER     "message-id"
#define STOMP_SUBSCRIPTION_HEADER   "subscription"
#define STOMP_RECEIPT_ID_HEADER     "receipt-id"
#define STOMP_MESSAGE_HEADER        "message"
#define STOMP_VERSION_HEADER        "version"

#endif<file_sep>/include/stomp_socket.ch
#ifndef _STOMP_SOCKET_CH
#define _STOMP_SOCKET_CH

#define STOMP_SOCKET_BUFFER_SIZE 4098

// CONNECTION ERRORS

#define STOMP_SOCKET_OPEN_ERROR               2
#define STOMP_SOCKET_CONNECT_ERROR            3
#define STOMP_SOCKET_STATUS_SEND_FAILED       4

#endif<file_sep>/lib/StompFrame.class.prg
#include "stomp.ch"

CLASS TStompFrame

  DATA cCommand INIT "" READONLY
  DATA aHeaders INIT {} READONLY
  DATA cBody INIT "" READONLY
  DATA aErrors INIT {} READONLY

  CLASSDATA aStompFrameTypes INIT { "SEND", "SUBSCRIBE", "UNSUBSCRIBE", "BEGIN", "COMMIT", "ABORT", "ACK", "NACK", "DISCONNECT", "CONNECT", "STOMP", "MESSAGE", "CONNECTED" }

  HIDDEN:
  // Validations
  METHOD validateCommand()
  METHOD validateHeader()
  METHOD validateBody()

  #ifdef __PROTHEUS__
    #xtranslate parseExtractCommand( <x> ) => parseEC( <x> )
    #xtranslate parseExtractHeaders( <x> ) => parseEH( <x> )
    #xtranslate parseExtractBody( <x> ) => parseEB( <x> )
  #endif
  METHOD parseExtractCommand( cStompFrame )
  METHOD parseExtractHeaders( cStompFrame )
  METHOD parseExtractBody( cStompFrame )

  EXPORTED:
  METHOD new() CONSTRUCTOR
  METHOD build()
  METHOD parse( cStompFrame )

  // Content
  METHOD setCommand( cCommand )
  METHOD setBody( cBody )
  METHOD addHeader( oStompFrameHeader )
  METHOD removeAllHeaders()
  METHOD getHeaderValue( cHeaderName )

  METHOD isValid()
  METHOD headerExists( cHeaderName )
  METHOD countHeaders()

  METHOD addError()
  METHOD countErrors()

ENDCLASS

METHOD countHeaders() CLASS TStompFrame
  RETURN ( LEN( ::aHeaders ) )

METHOD countErrors() CLASS TStompFrame
  RETURN ( LEN( ::aErrors ) )

METHOD new() CLASS TStompFrame
  RETURN SELF

METHOD addHeader( oStompFrameHeader ) CLASS TStompFrame
  AADD( ::aHeaders, oStompFrameHeader )
  RETURN ( NIL )

METHOD addError( cError ) CLASS TStompFrame
  AADD( ::aErrors, cError )
  RETURN ( NIL )

METHOD setCommand( cCommand ) CLASS TStompFrame

  ::cCommand := UPPER(cCommand)

  RETURN ( NIL )

METHOD setBody( cBody ) CLASS TStompFrame

  ::cBody := cBody

  RETURN ( NIL )

METHOD removeAllHeaders() CLASS TStompFrame
  ::aHeaders := ARRAY(0)
  RETURN ( nil )

METHOD validateCommand() CLASS TStompFrame
  LOCAL lReturn := .F.

  IF( ASCAN( ::aStompFrameTypes, { |c| UPPER(c) == UPPER( ::cCommand ) } ) > 0 )
    lReturn := .T.
  ELSE
    ::addError( "Invalid command." )
  ENDIF

  RETURN ( lReturn )

METHOD headerExists( cHeaderName ) CLASS TStompFrame
  LOCAL lReturn := .F.

  IIF ( ASCAN( ::aHeaders, { |h| h:getName() == cHeaderName } ) > 0, lReturn := .T., )

  RETURN ( lReturn )

METHOD getHeaderValue( cHeaderName ) CLASS TStompFrame
  LOCAL uReturn := nil

  FOR i := 1 TO ::countHeaders()
    IIF ( (::aHeaders[i]:getName() == cHeaderName), uReturn := ::aHeaders[i]:getValue(),  )
  NEXT
  RETURN ( uReturn )

METHOD validateHeader() CLASS TStompFrame
  LOCAL lReturn := .F.

  DO CASE

  CASE ::cCommand == "CONNECT" .OR. ::cCommand == "STOMP"
    IIF ( ( ::headerExists(STOMP_ACCEPT_VERSION_HEADER) .AND. ::headerExists(STOMP_HOST_HEADER) ), lReturn := .T., )
  CASE ::cCommand == "SEND"
    IIF ( ::headerExists(STOMP_DESTINATION_HEADER), lReturn := .T., )
  CASE ::cCommand == "SUBSCRIBE"
    IIF ( ::headerExists(STOMP_DESTINATION_HEADER) .AND. ::headerExists(STOMP_ID_HEADER), lReturn := .T., )
    IIF ( lreturn == .T. .AND. ::headerExists(STOMP_ACK_HEADER) .AND. ASCAN( STOMP_ACK_MODES, ::getHeaderValue(STOMP_ACK_HEADER) ) = 0, lReturn := .F., )
  CASE ::cCommand == "UNSUBSCRIBE" .OR. ::cCommand == "ACK" .OR. ::cCommand == "NACK"
    IIF ( ::headerExists(STOMP_ID_HEADER), lReturn := .T., )
  CASE ::cCommand == "BEGIN" .OR. ::cCommand == "COMMIT" .OR. ::cCommand == "ABORT"
    IIF ( ::headerExists(STOMP_TRANSACTION_HEADER), lReturn := .T., )
  CASE ::cCOmmand == "MESSAGE"
    IIF ( ( ::headerExists( STOMP_DESTINATION_HEADER ) .AND. ::headerExists( STOMP_MESSAGE_ID_HEADER ) .AND. ::headerExists( STOMP_SUBSCRIPTION_HEADER ) ), lReturn := .T., )
  CASE ::cCommand == "DISCONNECT"
    lReturn := .T.
  ENDCASE

  IIF ( ( lReturn == .F. ), ::addError( "Missing required header for " + ::cCommand + " command." ), )

  RETURN ( lReturn )

METHOD validateBody() CLASS TStompFrame
  LOCAL lReturn := .F.

  DO CASE
  CASE  ::cCommand == "SEND" .OR. ::cCommand == "MESSAGE"
    lReturn := .T.
  CASE        ::cCommand == "SUBSCRIBE"   ;
        .OR.  ::cCommand == "UNSUBSCRIBE" ;
        .OR.  ::cCommand == "BEGIN"       ;
        .OR.  ::cCommand == "COMMIT"      ;
        .OR.  ::cCommand == "ABORT"       ;
        .OR.  ::cCommand == "ACK"         ;
        .OR.  ::cCommand == "NACK"        ;
        .OR.  ::cCommand == "DISCONNECT"  ;
        .OR.  ::cCommand == "CONNECT"     ;
        .OR.  ::cCommand == "STOMP"
    IIF( ( Empty(::cBody) ), lReturn := .T., )
  ENDCASE

  IIF ( ( lReturn == .F. ), ::addError( "Missing required body for this " + ::cCommand + " frame." ), )

  RETURN ( lReturn )

METHOD isValid() CLASS TStompFrame
  RETURN ( ::validateCommand() .AND. ::validateHeader() .AND. ::validateBody() )

METHOD build() CLASS TStompFrame
  LOCAL cStompFrame := "", i

  IF !::isValid()
    RETURN ( .F. )
  ENDIF

  // build COMMAND
  cStompFrame += ::cCommand + CHR_CRLF

  // build HEADERS
  IF (::countHeaders() > 0)
    FOR i := 1 TO ::countHeaders()
      cStompFrame += ::aHeaders[i]:toString()
      cStompFrame += CHR_CRLF
    NEXT
  ENDIF
  cStompFrame += CHR_CRLF

  // build BODY
  cStompFrame += ::cBody
  cStompFrame += CHR_NULL + CHR_CRLF

  RETURN ( cStompFrame )

METHOD parse( cStompFrame ) CLASS TStompFrame
  LOCAL nLen          := 0 ,  ;
        nLastPos      := 0 ,  ;
        cHeader       := "",  ;
        cHeaderName   := "",  ;
        cHeaderValue  := "",  ;
        oHeader            ,  ;
        oStompFrame

  // Cleaning cStompFrame from CRLF to LF only
  cStompFrame := STRTRAN( cStompFrame, CHR_CRLF, CHR_LF )

  oStompFrame := TStompFrame():new()

  oStompFrame:cCommand  := ::parseExtractCommand( @cStompFrame )
  IIF ( ( oStompFrame:cCommand != STOMP_SERVER_COMMAND_ERROR ), oStompFrame:aHeaders := ::parseExtractHeaders( @cStompFrame ), )
  oStompFrame:cBody     := ::parseExtractBody( @cStompFrame )

  RETURN ( oStompFrame )

METHOD parseExtractCommand( cStompFrame ) CLASS TStompFrame
  LOCAL nLen      := 0,   ;
        nLastPos  := 0,   ;
        cCommand  := ""

  nLen        := Len( cStompFrame )
  nLastPos    := At( CHR_LF, cStompFrame )
  cCommand    := SUBSTR( cStompFrame, 1, nLastPos - 1 )
  cStompFrame := SUBSTR( cStompFrame, nLastPos + 1, nLen )

  RETURN ( cCommand )

METHOD parseExtractHeaders( cStompFrame ) CLASS TStompFrame
  LOCAL nLen          := 0,   ;
        nLastPos      := 0,   ;
        cHeaders      := "",  ;
        cHeaderName   := "",  ;
        cHeaderValue  := "",  ;
        aHeaders      := {},  ;
        i             := 0,   ;
        oHeader

  nLen        := Len ( cStompFrame )
  nLastPos    := AT( CHR_LF+CHR_LF, cStompFrame )
  cHeaders    := SUBSTR( cStompFrame, 1, nLastPos)

  // extract header's name and value
  DO WHILE ( AT( ":", cHeaders ) > 0 )
    i++

    cHeaderName   := LEFT( cHeaders, AT( ":", cHeaders ) - 1 )
    cHeaderValue  := SUBSTR( cHeaders, AT( ":", cHeaders ) + 1, AT( CHR_LF, cHeaders) - AT( ":", cHeaders ) - 1)

    AADD( aHeaders, TStompFrameHeader():new( cHeaderName, cHeaderValue ) )

    cHeaders      := SUBSTR(  cHeaders, ;
                              Len( CHR_LF ) + Len( cHeaderName ) + Len( ":" ) + Len( cHeaderValue ) + Len( CHR_LF ), ;
                              nLen ;
                            )
  ENDDO

  cStompFrame := SUBSTR( cStompFrame, nLastPos + 2, nLen )

  RETURN ( aHeaders )

METHOD parseExtractBody( cStompFrame ) CLASS TStompFrame
  LOCAL nLen          := 0,   ;
        nLastPos      := 0

  nLen     := Len ( cStompFrame )
  nLastPos := AT( CHR_NULL+CHR_LF, cStompFrame )
  cBody    := LEFT( cStompFrame, nLastPos - 1)

  cStompFrame := SUBSTR( cStompFrame, nLastPos + 2 , nLen )

  RETURN ( cBody )<file_sep>/lib/StompSocketHarbour.class.prg
#include "stomp.ch"
#include "hbsocket.ch"

#ifdef __HARBOUR__

CLASS TStompSocketHarbour FROM TStompSocket

  METHOD new() CONSTRUCTOR
  METHOD connect( cHost, nPort )
  METHOD send( cStompFrame )
  METHOD receive()
  METHOD disconnect()

ENDCLASS

METHOD new()
  RETURN ( self )

METHOD connect( cHost, nPort ) CLASS TStompSocketHarbour

  IF EMPTY( ::hSocket := hb_socketOpen() )
    ::oError := ErrorNew( "ESocketOpen",,, ProcName(), "Socket create error " + hb_ntos( hb_socketGetError() ) )
    //Throw( ::oError )
  ENDIF

  IF !hb_socketConnect( ::hSocket, { HB_SOCKET_AF_INET, cHost, nPort } )
    ::oError := ErrorNew( "ESocketConnect",,, ProcName(), "Socket connect error " + hb_ntos( hb_socketGetError() ) )
    //Throw( ::oError )
  ENDIF

  RETURN( NIL )

METHOD receive() CLASS TStompSocketHarbour
  LOCAL cBuffer, nLen

  ::cReceivedData := ""
  cBuffer = Space( STOMP_SOCKET_BUFFER_SIZE )
  IF ( nLen := hb_socketRecv( ::hSocket, @cBuffer, STOMP_SOCKET_BUFFER_SIZE, 0 , 1000 ) ) > 0
    ::cReceivedData := ALLTRIM( cBuffer )
  ENDIF

  #ifdef DEBUG
  ? "<<<<", CHR_CRLF
  ? cBuffer, CHR_CRLF
  ? "^^^^", CHR_CRLF
  #endif

  RETURN ( nLen )

//TODO - handle errors
//TODO - handle reconnections
//TODO - handle responses from the server
METHOD send( cStompFrame ) CLASS TStompSocketHarbour

  hb_socketSend( ::hSocket, cStompFrame )

  #ifdef DEBUG
  ? ">>>>", CHR_CRLF
  ? cStompFrame, CHR_CRLF
  ? "^^^^", CHR_CRLF
  #endif

 RETURN ( NIL )

METHOD disconnect() CLASS TStompSocketHarbour

  hb_socketShutdown( ::hSocket )
  hb_socketClose( ::hSocket )

  ::hSocket := nil

  RETURN ( NIL )

#endif

branch_name: refs/heads/master

languages: Makefile Markdown xBase YAML

repo_language: Makefile

repo_name: talvane/hbstomp


text:
<file_sep>ion-view(view-title='Start Page')
	ion-content.padding
		| Start Page
<file_sep>div.welcome(view-title='Start Page')
	h1
		| Start Page
.panel
	p
		| sdfasdfsd
		span.caret<file_sep>#!/bin/bash

sudo jade www/index.jade
sudo jade www/templates/*/*.jade
sudo gulp sass

exit
<file_sep>Download IdealApp Files

1. Download repo or copy project folder

2. Renaming project

	Change the files below and rename "Ideal-App" with your new project name.

	- bower.json
	- config.xml
	- ionic.project
	- package.json

	Optional: Change the files below and rename "IdealApp" with your new project name.

	- app.js
	- index.jade
	- controller.js
	- services.js

3. Terminal into the new app's folder to update the Ionic files with the new project name

	AppName$ ionic lib update

------------------------------------------------------------------------------

Install Ionic inside project's folder

AppName$ sudo npm install -g ionic

------------------------------------------------------------------------------

Running app

AppName$ sudo ionic serve

<file_sep>#!/bin/bash

git rm -r --cached .
git add .
git commit -m "Fix .gitignore Cache <bash it/git-ignore-refre.sh>"

exit
<file_sep>div.global-header-wrapper
	header.global-header
		div.global-header_logo
			a(href="#")
				img(src="http://placehold.it/100x35")
		nav.global-header_nav
			ul.nav.global-header_nav-links-wrapper
				li
					a(href="#/")
						| Start
				li
					a(href="#/sample")
						| Sample
<file_sep>#!/bin/bash

sudo npm install gulp
sudo npm install gulp-util
sudo npm install gulp-concat
sudo npm install gulp-sass
sudo npm install gulp-minify-css
sudo npm install gulp-rename

exit
<file_sep>doctype html
html(ng-app='RASworkspaces' ng-controller='Base')
	head
		meta(charset='utf-8')
		meta(name='viewport', content='initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width')
		title
		link(href="css/hd.app.css" rel="stylesheet" ng-if="C_DesktopView")
		link(href="css/ionic.app.css" rel="stylesheet" ng-if="C_MobileView")

		// ionic/angularjs js
		script(src='lib/ionic/js/ionic.bundle.js')
		// cordova script (this will be a 404 during development)
		script(src='cordova.js')

		script(src='lib/angular-bootstrap/ui-bootstrap-tpls.js')

		// your app's js
		script(src='js/app.js')
		script(src='js/controllers.js')
		script(src='js/services.js')
	body(ng-class='{"desktop": C_DesktopView, "mobile": C_MobileView}')
		div(ui-view="header")

		ion-nav-bar.bar-stable
			ion-nav-back-button

		//
			### Views to render

		div(ng-if="C_DesktopView")
			div.main_hd(ui-view="content")

		div(ng-if="C_MobileView")
			ion-nav-view.main_mobile(name="content")
<file_sep>ion-tabs.tabs-icon-top.tabs-color-active-positive(ng-controller="ContentMobile")
	ion-tab(title='Start', icon-off='ion-ionic', icon-on='ion-ionic', href='#/')
		ion-nav-view(name='v-start')
	ion-tab(title='Sample', icon-off='ion-ionic', icon-on='ion-ionic', href='#/sample')
		ion-nav-view(name='v-sample')
<file_sep>//
	###
	ATTENTION!
	Do not use this template!  The "header" template is in index.jade at "ion-nav-bar"
	###<file_sep>ion-view(view-title='Sample Page')
	ion-content.padding
		| Sample Page
<file_sep>div.sample(view-title='Sample Page')
	h1
		| Sample Page
<file_sep>(function() {
    angular.module('RASworkspaces.services', [])
           .factory('S_defaultData', function() {
        var defaultData = {};

        return {
            get: function(whichKey, whichFurtherKeys) {
                if(whichFurtherKeys === undefined) {
                    whichFurtherKeys = [];
                }

                var resultingData = defaultData[whichKey];

                for(var i = 0; i < whichFurtherKeys.length; i++) {
                    resultingData = resultingData[whichFurtherKeys[i]];
                }

                return resultingData;
            },
            data: function() {
                return defaultData;
            }
        };
    })

           .factory('S_localStorage', function() {
        var appVersion = "v0.0.1";

        if(window.localStorage["appVersion"] !== appVersion) {
            // ### Do new things if new app version

            // Update localStorage appVersion to latest
            window.localStorage["appVersion"] = appVersion;
        }

        var userData = {
            appVersion: window.localStorage["appVersion"]
        };

        return {
            get: function(whichKey, whichFurtherKeys) {
                if(whichFurtherKeys === undefined) {
                    whichFurtherKeys = [];
                }

                var resultingData = userData[whichKey];

                for(var i = 0; i < whichFurtherKeys.length; i++) {
                    resultingData = resultingData[whichFurtherKeys[i]];
                }

                return resultingData;
            },
            getOne: function(whichKey, whichSubkey) {
                return userData[whichKey][whichSubkey];
            },
            set: function(whichKey, whichValue) {
                userData[whichKey] = whichValue;

                window.localStorage[whichKey] = JSON.stringify(whichValue);
            },
            setOne: function(whichKey, whichSubkey, whichValue) {
                userData[whichKey][whichSubkey] = whichValue;

                window.localStorage[whichKey] = JSON.stringify(userData[whichKey]);
            },
            delete: function(whichKey, baseValue) {
                delete userData[whichKey];

                userData[whichKey] = baseValue;

                window.localStorage[whichKey] = JSON.stringify(userData[whichKey]);
            },
            deleteOne: function(whichKey, whichSubkey) {
                delete userData[whichKey][whichSubkey];

                window.localStorage[whichKey] = JSON.stringify(userData[whichKey]);
            },
            data: function() {
                return userData;
            }
        };
    })

           .factory('S_globalFlags', function() {
        var currentGlobalFlag = {
            deviceIsReady: false
        };

        document.addEventListener("deviceready", function() {
            currentGlobalFlag["deviceIsReady"] = true;
        }, false);

        return {
            get: function(whichKey) {
                return currentGlobalFlag[whichKey];
            },
            set: function(whichKey, whichValue, whichCallback) {
                if(whichCallback === undefined) {
                    whichCallback = function(){};
                }

                currentGlobalFlag[whichKey] = whichValue;

                whichCallback();
            },
            delete: function(whichKey, baseValue) {
                delete currentGlobalFlag[whichKey];

                currentGlobalFlag[whichKey] = baseValue;
            },
            data: function() {
                return currentGlobalFlag;
            }
        };
    });
})();
<file_sep>(function() {
    var isMobile = false;

    angular.module('RASworkspaces', ['ionic', 'RASworkspaces.controllers', 'RASworkspaces.services', 'ui.bootstrap'])
           .controller('Base', function($scope, S_globalFlags) {
        console.log("### Controller - Base ###");

        S_globalFlags.set("MobileView", isMobile);

        var MobileView = S_globalFlags.get("MobileView");
        $scope.C_MobileView = MobileView;
        $scope.C_DesktopView = !MobileView;
    })
           .run(function($ionicPlatform) {
        $ionicPlatform.ready(function() {
            // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
            // for form inputs)
            if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
                cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
            }
            if (window.StatusBar) {
                // org.apache.cordova.statusbar required
                StatusBar.styleLightContent();
            }
        });
    })
           .config(function($stateProvider, $locationProvider, $urlRouterProvider) {
        var templateFolderName = 'hd';

        if(isMobile) {
            templateFolderName = 'mobile';
        }

        $stateProvider.state('content', {
            url: "",
            abstract: true,
            views: {
                "header": {
                    templateUrl: 'templates/' + templateFolderName + '/header-base.html'
                },
                "content": {
                    templateUrl: 'templates/' + templateFolderName + '/content-base.html'
                }
            }
        })

                      .state('content.start', {
            url: '/',
            views: {
                'v-start': {
                    templateUrl: 'templates/' + templateFolderName + '/start.html',
                    controller: 'Start'
                }
            }
        })
                      .state('content.sample', {
            url: '/sample',
            views: {
                'v-sample': {
                    templateUrl: 'templates/' + templateFolderName + '/sample.html',
                    controller: 'Sample'
                }
            }
        });

        $urlRouterProvider.otherwise('/');
    });
})();
<file_sep>div.content_start(ui-view='v-start')
div.content_sample(ui-view='v-sample')
<file_sep>#!/bin/bash

sudo npm install
bash it/npm-install-gulp.sh
bower install
bash it/compile.sh

exit

languages: Markdown Shell JavaScript Pug

repo_language: Markdown

repo_name: hoathai/ideal-ionic-hybrid-app


text:
<repo_name>edwinmoradian90/tic-tac-toe_js<file_sep>/README.md
# Tic tac toe with Js

Project for Microverse using Odin project.

It is built with vanilla Javascript, HTML, and CSS.

The main point of this project is to use modules, factory functions, and to understand how to closures work.

![tictactoe](./assets/images/screenshots/tictactoejs.png)

## Getting Started

Just clone the project, and run the HTML in your browser.

Or [view](https://raw.githack.com/edwinmoradian90/tic-tac-toe_js/game-features/index.html) it here.

## Built With

* JavaScipt - Vanilla.
* HTML - You know.
* CSS - Styling.

## Authors

**<NAME>**  | [Github](https://github.com/edwinmoradian90) | [LinkedIn](https://linkedin.com/in/edwin-moradian) | [Portfolio](https://edwin-moradian.firebaseapp.com)

## License

This project is licensed under the MIT License.

branch_name: refs/heads/development


text:
<repo_name>jsleung1/spring_boot_logging<file_sep>/logging-log4j2/src/main/resources/notes.txt
https://stackoverflow.com/questions/30882982/in-log4j-1-2-to-log4j-2-migration-what-to-do-with-the-dailyrollingfileappender
https://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender

repo_language: Text


text:
<file_sep>import MainLayout from '../layouts/MainLayout';
const Profile = () => {

    return (
        <MainLayout>

Profile

        </MainLayout>

    )
}

export default Profile;<file_sep>
import Link from 'next/link';
const MainLayout  = (props) => {
    return (

                    <Link href='/'>
                         STOCK
                    </Link>

                        <Link href='/products'>
                         Products
                        </Link>

                        <Link href='/manage'>
                         Manage
                        </Link>

                        <Link href='/profile'>
                            Profile
                        </Link>

                {props.children}

    )
}

export default MainLayout ;<file_sep>import Link from 'next/link';
import ProductsPage from './Products';
import MainLayout from '../layouts/MainLayout';

const HomePage = () => {
    return (
       <MainLayout>
           Home
           </MainLayout>
    )
}

export default HomePage;

repo_language: JavaScript