Skip to content

Commit

Permalink
more pixels
Browse files Browse the repository at this point in the history
  • Loading branch information
Alcaro committed Nov 25, 2018
1 parent e16471a commit dc61cb4
Show file tree
Hide file tree
Showing 15 changed files with 117 additions and 915 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Enhanced remake of http://www.notdoppler.com/kingofbridges.php

![Screenshot](https://github.com/Alcaro/bridges/blob/master/pic.png)

## Compilation - Linux

```
Expand Down
3 changes: 2 additions & 1 deletion arlib/bytepipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,8 @@ class bytepipe {

return NULL;
}
//Returns 'line' minus a trailing \r\n or \n. The \n must exist. Usable together with the above.
//Returns 'line' minus a trailing \r\n or \n. The \n must exist.
//Usable together with the above, though you must acknowledge the \n too.
static arrayview<byte> trim_line(arrayview<byte> line)
{
if (line.size()==1) return NULL;
Expand Down
2 changes: 1 addition & 1 deletion arlib/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ class function<R (ARG_TYPES)>
//- it is not sensitive to false negatives - even if the address of EmptyHandler changes, obj==func does not
//- it is not sensitive to false positives - EmptyHandler is private, and can't be aliased by anything unexpected
// (okay, it is sensitive on a pure Harvard architecture, but they're extinct and Modified Harvard is safe.)
//- it is sensitive to hostile callers, but if you call bind_ptr(func, (void*)func), you're asking for bugs.
//- it is sensitive to hostile callers, but if you call bind_ptr(func, (void*)func), you're asking for trouble.
function() : func(EmptyHandler), obj((void*)EmptyHandler), ref(NULL) {}
function(const function& rhs) : func(rhs.func), obj(rhs.obj), ref(rhs.ref)
{ add_ref(); }
Expand Down
23 changes: 23 additions & 0 deletions arlib/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,29 @@ class autofree : nocopy {
~autofree() { free(ptr); }
};

template<typename T>
class refcount {
struct inner_t {
uint32_t refcount;
T item;
};
inner_t* inner;

public:
refcount() { inner = new inner_t(); inner->refcount = 1; }
refcount(const refcount<T>& other) { inner = other.inner; inner->refcount++; }
refcount(refcount<T>&& other) { inner = other.inner; other.inner = NULL; }
refcount<T>& operator=(T* ptr) = delete;
refcount<T>& operator=(autofree<T>&& other) = delete;
T* operator->() { return &inner->item; }
T& operator*() { return inner->item; }
const T* operator->() const { return &inner->item; }
const T& operator*() const { return inner->item; }
operator T*() { return &inner->item; }
operator const T*() const { return &inner->item; }
~refcount() { if (inner && 0 == --inner->refcount) delete inner; }
};

#if __cplusplus < 201103
class nullptr_t_impl {};
#define nullptr_t nullptr_t_impl* // random pointer type nobody will ever use
Expand Down
26 changes: 19 additions & 7 deletions arlib/http.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ void HTTP::try_compile_req()
if (next_send > 1) return; // only pipeline two requests at once
if (!sock) return;

const rsp& r = requests[next_send].r;
rsp_i& ri = requests[next_send];
const rsp& r = ri.r;
if (r.status == rsp::e_canceled)
{
requests.remove(next_send);
Expand Down Expand Up @@ -135,13 +136,9 @@ void HTTP::try_compile_req()
if (method!="GET" && !httpContentType)
{
if (q.body && (q.body[0] == '[' || q.body[0] == '{'))
{
tosend.push("Content-Type: application/json\r\n");
}
else
{
tosend.push("Content-Type: application/x-www-form-urlencoded\r\n");
}
}
if (!httpConnection) tosend.push("Connection: keep-alive\r\n");

Expand All @@ -150,10 +147,13 @@ void HTTP::try_compile_req()
tosend.push(q.body);

bool ok = true;
if (sock->send(tosend.pull_buf( )) < 0) ok = false;
if (sock->send(tosend.pull_next()) < 0) ok = false;
if (ok && (q.flags & req::f_no_retry) && ri.sent_once) ok = false;
if (ok && sock->send(tosend.pull_buf( )) < 0) ok = false;
if (ok && sock->send(tosend.pull_next()) < 0) ok = false;
if (!ok) sock = NULL;

ri.sent_once = true;

next_send++;
}

Expand Down Expand Up @@ -195,6 +195,7 @@ void HTTP::reset_limits()

void HTTP::activity()
{
//TODO: replace this state machine with bytepipe::pull_line
newsock:
if (requests.size() == 0)
{
Expand Down Expand Up @@ -408,7 +409,18 @@ test("URL parser", "", "http")
test_url("http://example.com/foo/bar.html?baz", "foo.html", "http", "example.com", 0, "/foo/foo.html");
test_url("http://example.com/foo/bar.html?baz", "?quux", "http", "example.com", 0, "/foo/bar.html?quux");
test_url("http://example.com:80/", "http", "example.com", 80, "/");
test_url("http://example.com:80/", "http://example.com:8080/", "http", "example.com", 8080, "/");
test_url_fail("http://example.com:80/", ""); // if changing this, also change assert in HTTP::try_compile_req()
test_url("http://a.com/foo/bar.html?baz", "#corge", "http", "a.com", 80, "/foo/bar.html?baz#corge");
test_url("http://a.com/foo/bar.html?baz#corge", "http://b.com/foo.html", "http", "b.com", 80, "/foo.html#corge");
test_url("http://a.com/foo/bar.html?baz#corge", "/bar/foo.html", "http", "a.com", 80, "/bar/foo.html#corge");
test_url("http://a.com/foo/bar.html?baz#corge", "foo.html", "http", "a.com", 80, "/foo/foo.html#corge");
test_url("http://a.com/foo/bar.html?baz#corge", "?quux", "http", "a.com", 80, "/foo/bar.html?quux#corge");
test_url("http://a.com/foo/bar.html?baz#corge", "http://b.com/#grault", "http", "b.com", 80, "/foo.html#grault");
test_url("http://a.com/foo/bar.html?baz#corge", "/bar/foo.html#grault", "http", "a.com", 80, "/bar/foo.html#grault");
test_url("http://a.com/foo/bar.html?baz#corge", "foo.html#grault", "http", "a.com", 80, "/foo/foo.html#grault");
test_url("http://a.com/foo/bar.html?baz#corge", "?quux#grault", "http", "a.com", 80, "/foo/bar.html?quux#grault");
test_url("http://a.com/foo/bar.html?baz#corge", "#grault", "http", "a.com", 80, "/foo/bar.html?baz#grault");
}

test("HTTP", "tcp,ssl", "http")
Expand Down
10 changes: 9 additions & 1 deletion arlib/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@ class HTTP : nocopy {
array<string> headers; // TODO: multimap
array<byte> body;

uintptr_t id; // Passed unchanged in the rsp object, and used for cancel(). Otherwise not used.
enum {
f_no_retry = 0x00000001,
};
uint32_t flags = 0;

// Passed unchanged in the rsp object, and used for cancel(). Otherwise not used.
// Duplicates are allowed if cancel() is not used.
uintptr_t id = 0;

//If the server sends this much data (including headers/etc), or hasn't finished in the given time, fail.
//They're approximate; a request may succeed if the server sends slightly more than this.
Expand Down Expand Up @@ -82,6 +89,7 @@ class HTTP : nocopy {
private:
struct rsp_i {
rsp r;
bool sent_once = false; // used for f_no_retry
function<void(rsp)> callback;
};
public:
Expand Down
11 changes: 11 additions & 0 deletions arlib/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,17 @@ class timer {
{
return us() / 1000;
}
uint64_t us_reset()
{
uint64_t new_us = time_us_ne();
uint64_t prev_us = start;
start = new_us;
return new_us - prev_us;
}
uint64_t ms_reset()
{
return us_reset() / 1000;
}
};

#ifdef _WIN32 // surprisingly, this is safe - gmtime() returns a thread local
Expand Down
9 changes: 5 additions & 4 deletions arlib/serialize-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,10 +563,11 @@ test("JSON deserialization", "json", "serialize")
assert_eq(item.b, 2);
}

//these pass if they do not give infinite loops or otherwise explode
//these pass if they do not give infinite loops or valgrind errors, or otherwise explode
{
jsonunserialize<ser1>("{ \"a\":1, \"b\":2, \"q\":*, \"a\":3, \"a\":4 }");
jsonunserialize<ser6>("{\"data\":[{\"a\":\"a\n[]\"}]}");
jsonunserialize<map<string,int>>("{\"aaaaaaaaaaaaaaaa\":1,\"bbbbbbbbbbbbbbbb\":2}");
}

//the system is allowed to loop, but only if there's bogus or extraneous nodes
Expand Down Expand Up @@ -642,9 +643,9 @@ test("JSON deserialization", "json", "serialize")
"{ \"data\": { \"foo\": \"bar\", "
"\"C:/Users/Administrator/My Documents/!TOP SECRET!.docx\": \"test\", "
"\"test\": \"C:/Users/Administrator/My Documents/!TOP SECRET!.docx\" } }");
assert_eq(item.data.get("foo"), "bar");
assert_eq(item.data.get("test"), "C:/Users/Administrator/My Documents/!TOP SECRET!.docx");
assert_eq(item.data.get("C:/Users/Administrator/My Documents/!TOP SECRET!.docx"), "test");
assert_eq(item.data.get_or("foo", "NONEXISTENT"), "bar");
assert_eq(item.data.get_or("test", "NONEXISTENT"), "C:/Users/Administrator/My Documents/!TOP SECRET!.docx");
assert_eq(item.data.get_or("C:/Users/Administrator/My Documents/!TOP SECRET!.docx", "NONEXISTENT"), "test");
}

{
Expand Down
36 changes: 29 additions & 7 deletions arlib/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,24 @@
// //The name can be any string.
// template<typename T> void item(cstring name, T& item);
//
// //Similar to item(), but uses hex rather than decimal if output is human readable (otherwise, identical to item).
// //Similar to item(), but uses hex rather than decimal, if applicable. If not, identical to item, except the type restrictions.
// //Valid types:
// //- Any unsigned integral type
// //- array<byte>
// //- arrayvieww<byte>
// template<typename T> void hex(cstring name, T& item);
// void hex(cstring name, arrayvieww<byte> item);
//
// //Makes serialized data look nicer. May be ignored.
// //Makes serialized data look nicer. May be ignored. Ignored while unserializing.
// void comment(cstring c);
//
// //Returns the next child name the structure expects to process. Valid only while unserializing.
// //These are valid only while unserializing. Check .serializing before calling.
// //Returns the next child name the structure expects to process.
// cstring next() const;
// //(BML unserializer only) Returns the value corresponding to next().
// //item_next(foo) is like item(next(), foo), but won't do weird things
// // due to next() being freed by item(), or due to two consecutive identical keys.
// template<typename T> void item_next(T& item);
// //(BML only) Returns the value corresponding to next().
// cstring nextval() const;
//};
//
Expand Down Expand Up @@ -113,7 +117,8 @@ class bmlserialize_impl {
w.node(bmlwriter::escape(name), tostringhex(item));
}

cstring next() const { abort(); } // illegal
template<typename T> void item_next(T& out) { abort(); } // only legal for deserializing
cstring next() const { abort(); }
};

template<typename T> string bmlserialize(T& item)
Expand Down Expand Up @@ -225,6 +230,13 @@ class bmlunserialize_impl {
}
}

template<typename T> void item_next(T& out)
{
read_item(out);
thisnode = "";
to_next();
}

bool enter(bool& first)
{
bmlparser::event ev(0);
Expand Down Expand Up @@ -411,7 +423,8 @@ class jsonserialize_impl {
add_node(inner, conv);
}

cstring next() const { abort(); } // illegal
template<typename T> void item_next(T& out) { abort(); } // illegal
cstring next() const { abort(); }
};

template<typename T> string jsonserialize(T& item)
Expand All @@ -438,7 +451,7 @@ class jsonunserialize_impl {
jsonunserialize_impl(cstring json) : p(json) {}
template<typename T> friend T jsonunserialize(cstring json);
template<typename T> friend void jsonunserialize(cstring json, T& out);
template<typename T> friend void jsonunserialize(cstring json, const T& out);
template<typename T> friend void jsonunserialize(cstring json, const T& out); // this is super dumb, but lambdas need it somehow

//input: ev points to any node
//output: if ev pointed to enter_map or enter_list, ev now points to corresponding exit; if not, no change
Expand Down Expand Up @@ -671,6 +684,15 @@ class jsonunserialize_impl {
}
}

template<typename T> void item_next(T& out)
{
if (ev.action != jsonparser::map_key)
abort();
ev = p.next();
read_item(out);
matchagain = true;
}

template<typename T>
typename std::enable_if<std::is_integral<T>::value>::type
hex(cstring name, T& out)
Expand Down
5 changes: 1 addition & 4 deletions arlib/set.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,10 +482,7 @@ class map : public linqbase<map<Tkey,Tvalue>> {
{
Tkey tmpk;
if (fromstring(s.next(), tmpk))
{
Tvalue& tmpv = items.get_create(tmpk).value;
s.item(s.next(), tmpv);
}
s.item_next(items.get_create(tmpk).value);
}
}
};
1 change: 1 addition & 0 deletions arlib/stringconv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ test("string conversion", "", "string")
testcall(testundec<int>("00123", 123));
testcall(testundec<int>("000123", 123));
testcall(testundec<int>("0", 0));
testcall(testundec<int>("09", 9)); // no octal alloweds
testcall(testundec<double>("123", 123));
testcall(testundec<double>("0123", 123));
testcall(testundec<double>("00123", 123));
Expand Down
17 changes: 14 additions & 3 deletions arlib/test.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,31 @@
#pragma once
#include "global.h"
#include "stringconv.h"
#include "linq.h"

#undef assert

#ifdef ARLIB_TEST

template<typename T>
string tostring_dbg(const T& item) { return tostring(item); }
template<typename T>
string tostring_dbg(const arrayview<T>& item)
{
return item.join((string)",", [](const T& i){ return tostring(i); });
return item.join((string)",", [](const T& i){ return tostring_dbg(i); });
}
template<typename T> string tostring_dbg(const arrayvieww<T>& item) { return tostring_dbg((arrayview<T>)item); }
template<typename T> string tostring_dbg(const array<T>& item) { return tostring_dbg((arrayview<T>)item); }
template<typename T>
string tostring_dbg(const T& item) { return tostring(item); }
template<typename Tkey, typename Tvalue>
string tostring_dbg(const map<Tkey,Tvalue>& item)
{
return "{"+
item
.select([](const typename map<Tkey,Tvalue>::node& n){ return tostring_dbg(n.key)+" => "+tostring_dbg(n.value); })
.as_array()
.join(", ")
+"}";
}

class _testdecl {
public:
Expand Down
Loading

0 comments on commit dc61cb4

Please sign in to comment.