Skip to content

Commit

Permalink
Merge pull request #2 from ikonopistsev/v1.7.0
Browse files Browse the repository at this point in the history
V1.7.0
  • Loading branch information
ikonopistsev authored Apr 20, 2022
2 parents d79fa52 + 9c0bcb8 commit 10dc8cf
Show file tree
Hide file tree
Showing 17 changed files with 546 additions and 626 deletions.
7 changes: 3 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ project(stomptalk VERSION 1.7.0 LANGUAGES CXX)
option(STOMPTALK_LIBRARY_STATIC "Set library type to STATIC" ON)
option(STOMPTALK_LIBRARY_INSTALL "make install" OFF)

set (CMAKE_CXX_STANDARD 17)
set (CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_definitions("-DSTOMPTALK_VERSION=${PROJECT_VERSION}")

Expand All @@ -16,7 +16,7 @@ endif()

set(source
src/parser.cpp
src/parser_hook.cpp
src/stomptalk.cpp
)

set(pub_header
Expand All @@ -32,7 +32,6 @@ set(pub_header
include/stomptalk/stackbuf.hpp
include/stomptalk/hashval.hpp
include/stomptalk/parser.hpp
include/stomptalk/version.hpp
)

if (STOMPTALK_LIBRARY_STATIC)
Expand Down
11 changes: 8 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ You must implement the hook_base interface.
struct hook_base
{
virtual void on_frame(parser_hook&, const char *frame_start) noexcept = 0;
virtual void on_method(parser_hook&,
std::uint64_t method_id, std::string_view) noexcept = 0;
std::uint64_t method_id, const char*, std::size_t) noexcept = 0;
virtual void on_hdr_key(parser_hook&,
std::uint64_t hader_id, std::string_view) noexcept = 0;
virtual void on_hdr_val(parser_hook&, std::string_view) noexcept = 0;
std::uint64_t hader_id, const char*, std::size_t) noexcept = 0;
virtual void on_hdr_val(parser_hook&, const char*, std::size_t) noexcept = 0;
virtual void on_body(parser_hook&, const void*, std::size_t) noexcept = 0;
virtual void on_frame_end(parser_hook&, const char *frame_end) noexcept = 0;
};
```
Expand Down
24 changes: 7 additions & 17 deletions include/stomptalk/antoull.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
#include <limits>
#include <string>
#include <cstdint>
#include <cassert>
#include <type_traits>
#include <string_view>

namespace stomptalk {
namespace detail {
Expand Down Expand Up @@ -39,11 +39,16 @@ struct antout<T, 1>

}

} // namespace detail

// return UNSIGNED result as SIGNED value;
// if result < 0 then parse error;
static inline
std::int64_t antoull(const char *ptr, std::size_t n) noexcept
{
assert(ptr);

using namespace detail;
switch (n)
{
case 0x12: return antout<std::int64_t, 0x12>::conv(ptr);
Expand All @@ -67,23 +72,8 @@ std::int64_t antoull(const char *ptr, std::size_t n) noexcept
default:;
}

// parse error
return std::numeric_limits<std::int64_t>::min();
}

} // namespace detail

// return UNSIGNED result as SIGNED value;
// if result < 0 then parse error;
static inline
std::int64_t antoull(const char *ptr, std::size_t n) noexcept
{
return detail::antoull(ptr, n);
}

static inline
std::int64_t antoull(std::string_view text) noexcept
{
return detail::antoull(text.data(), text.size());
}

} // namespace stomptalk
6 changes: 4 additions & 2 deletions include/stomptalk/fnv1a.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ struct fnv1a
template<class T, fnv1a::type H>
struct static_hash
{
constexpr static auto value = fnv1a::calc_hash<decltype(T::text)>(T::text.begin(), T::text.end());
using enable_type = typename std::enable_if<value == H, std::nullptr_t>::type;
constexpr static auto value =
fnv1a::calc_hash<decltype(T::text)>(T::text.begin(), T::text.end());
using enable_type =
typename std::enable_if<value == H, std::nullptr_t>::type;
};

} // namespace stomptalk
2 changes: 1 addition & 1 deletion include/stomptalk/hashval.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ template<>
struct hashval<char>
{
using type = fnv1a::type;
type value_{ fnv1a::salt };
type value_{fnv1a::salt};

void reset(type salt = fnv1a::salt) noexcept
{
Expand Down
2 changes: 1 addition & 1 deletion include/stomptalk/header.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by stomptalkgen.js 2022-03-15T16:58:45.281Z
// generated by stomptalkgen.js 2022-03-19T14:16:57.888Z
#ifndef stomptalk_header_h
#define stomptalk_header_h

Expand Down
9 changes: 4 additions & 5 deletions include/stomptalk/hook_base.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#pragma once

#include <string_view>
#include <cassert>
#include <cstddef>
#include <cstdint>

namespace stomptalk {
Expand All @@ -13,12 +12,12 @@ struct hook_base
virtual void on_frame(parser_hook&, const char *frame_start) noexcept = 0;

virtual void on_method(parser_hook&,
std::uint64_t method_id, std::string_view) noexcept = 0;
std::uint64_t method_id, const char*, std::size_t) noexcept = 0;

virtual void on_hdr_key(parser_hook&,
std::uint64_t hader_id, std::string_view) noexcept = 0;
std::uint64_t hader_id, const char*, std::size_t) noexcept = 0;

virtual void on_hdr_val(parser_hook&, std::string_view) noexcept = 0;
virtual void on_hdr_val(parser_hook&, const char*, std::size_t) noexcept = 0;

virtual void on_body(parser_hook&, const void*, std::size_t) noexcept = 0;

Expand Down
2 changes: 1 addition & 1 deletion include/stomptalk/method.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by stomptalkgen.js 2022-03-15T16:58:45.253Z
// generated by stomptalkgen.js 2022-03-19T14:16:57.870Z
#ifndef stomptalk_method_h
#define stomptalk_method_h

Expand Down
15 changes: 15 additions & 0 deletions include/stomptalk/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,17 @@ typedef int (*stomptalk_cb) (stomptalk_parser*, const char* at);

struct stomptalk_parser;

enum stomptalk_error {
stomptalk_error_none = 0,
stomptalk_error_too_big,
stomptalk_error_inval_reqline,
stomptalk_error_inval_method,
stomptalk_error_inval_frame,
stomptalk_error_inval_content_size,
stomptalk_error_next_frame,
stomptalk_error_generic
};

struct stomptalk_parser_hook {
stomptalk_cb on_frame;
stomptalk_id_cb on_method;
Expand Down Expand Up @@ -52,6 +63,10 @@ uint64_t stomptalk_get_content_length(stomptalk_parser *parser);

size_t stomptalk_get_error(stomptalk_parser *parser);

const char* stomptalk_get_error_str(size_t error);

const char* stomptalk_version();

#ifdef __cplusplus
}
#endif
Expand Down
147 changes: 93 additions & 54 deletions include/stomptalk/parser_hook.hpp
Original file line number Diff line number Diff line change
@@ -1,102 +1,141 @@
#pragma once

#include "stomptalk/hook_base.hpp"
#include "stomptalk/header.h"
#include "stomptalk/antoull.hpp"
#include "stomptalk/parser.h"

namespace stomptalk {

class parser;
class parser_hook
{
public:
struct error
{
enum type
: std::size_t
{
none = 0,
too_big,
inval_reqline,
inval_method,
inval_frame,
inval_content_size,
next_frame,
generic
};
};

protected:
hook_base& hook_;
std::uint64_t content_left_{};
// header 'content-length' data
std::uint64_t total_length_{};
error::type error_{error::none};
std::uint64_t content_length_{};
std::uint64_t header_id_{};
stomptalk_error error_{stomptalk_error_none};

public:
parser_hook(hook_base& hook)
: hook_(hook)
parser_hook(hook_base& hook) noexcept
: hook_{hook}
{ }

void reset() noexcept;

bool ok() const noexcept
{
return error() == error::none;
}

error::type error() const noexcept
void reset() noexcept
{
return error_;
content_left_ = 0u;
content_length_ = 0u;
header_id_ = 0u;
error_ = stomptalk_error_none;
}

void set(error::type) = delete;

void set(std::uint64_t content_left) noexcept
{
content_left_ = content_left;
}

std::uint64_t content_length() const noexcept
{
return total_length_;
return content_length_;
}

void set(stomptalk_error error) noexcept
{
error_ = error;
}

std::uint64_t content_left() const noexcept
{
return content_left_;
}

void on_frame(const char *frame_start) noexcept;

void on_method(std::uint64_t method_id, std::string_view text) noexcept;

void on_hdr_key(std::uint64_t header_id, std::string_view text) noexcept;

void on_hdr_val(std::string_view text) noexcept;

void on_body(const void* ptr, std::size_t size) noexcept;
std::uint64_t header_id() const noexcept
{
return header_id_;
}

void on_frame_end(const char *frame_end) noexcept;
stomptalk_error error() const noexcept
{
return error_;
}

// errors
void no_error() noexcept;
bool ok() const noexcept
{
return error() == stomptalk_error_none;
}

void too_big() noexcept;
void on_frame(const char *frame_start) noexcept
{
hook_.on_frame(*this, frame_start);
}

void on_method(std::uint64_t method_id, const char *at, std::size_t len) noexcept
{
hook_.on_method(*this, method_id, at, len);
}

void inval_reqline() noexcept;
template<class P>
void on_method(std::uint64_t method_id, P p) noexcept
{
on_method(method_id, p.first, p.second);
}

void inval_method() noexcept;
void on_hdr_key(std::uint64_t header_id, const char *at, std::size_t len) noexcept
{
// нам важен только размер контента
// прверяем встречается ли хидер первый раз
// http://stomp.github.io/stomp-specification-1.2.html#Repeated_Header_Entries
// If a client or a server receives repeated frame header entries,
// only the first header entry SHOULD be used as the value of header entry.
if ((st_header_content_length == header_id) && !content_length_)
header_id_ = header_id;

hook_.on_hdr_key(*this, header_id, at, len);
}

void inval_frame() noexcept;
template<class P>
void on_hdr_key(std::uint64_t header_id, P p) noexcept
{
on_hdr_key(header_id, p.first, p.second);
}

void inval_content_size() noexcept;
void on_hdr_val(const char *at, std::size_t len) noexcept
{
// проверяем ожидали ли content_length
if (st_header_content_length == header_id_)
{
// парсим размер
auto content_len = stomptalk::antoull(at, len);
if (content_len > 0ll)
content_length_ = content_left_ = static_cast<std::uint64_t>(content_len);
else
{
set(stomptalk_error_inval_content_size);
return;
}

header_id_ = 0u;
}

hook_.on_hdr_val(*this, at, len);
}

void next_frame() noexcept;
template<class P>
void on_hdr_val(P p) noexcept
{
on_hdr_val(p.first, p.second);
}

void generic_error() noexcept;
void on_body(const void* ptr, std::size_t size) noexcept
{
hook_.on_body(*this, ptr, size);
}

std::string_view error_str() const noexcept;
void on_frame_end(const char *frame_end) noexcept
{
hook_.on_frame_end(*this, frame_end);
}
};

} // stomptalk
Loading

0 comments on commit 10dc8cf

Please sign in to comment.