text:
Ok, this isn't actually all Erlang. In fact, by line-count, it's a Postscript project, but [all of those lines were already written](https://code.google.com/p/postscriptbarcode/) by someone else. Also, I'm not sure whether I'll get the same benefit here that I got out of [my Strifebarge write-up](/posts/strifebarge-turn-based-web-games-in-common-lisp), but it's the third such piece, so I've gone back and added labels to group them.

"Almost Literate Programming".

What I'm doing isn't quite the [LP that Knuth advocates](http://www.literateprogramming.com/) because it doesn't self-extract, share space with the executable source, or make use of variable labels to automatically update certain portions. However, it still gains me considerable reflective clarity about what the goal of the program is, and it hopefully conveys the essence to whoever happens to be reading. With that out of the way...

## Generating Barcodes

As you may have noticed from the above links, there already exists a [Postscript-based barcode generator](https://code.google.com/p/postscriptbarcode/) which I'm going to use pretty shamelessly in order to generate bitmap barcodes of various descriptions. Taking a look at the [actual code](https://code.google.com/p/postscriptbarcode/downloads/detail?name=barcode-2012-04-26.ps) for that generator should make it obvious that you probably *don't* want to just echo the entire system every time you need to generate something[^the-complete-file]. We'll get to that though, lets start from the system side first. This is what a `.app` declaration looks like in Erlang

[^the-complete-file]: The complete file is 17111 lines, and we really only need about 800-1200 at the outside to generate a single specific barcode.

```make
# Makefile
all: *.erl *.c
        make wand
        erlc -W *erl

run:
        erl -name ps_barcode@127.0.1.1 -eval 'application:load(ps_barcode).' -eval 'application:start(ps_barcode).'

wand: wand.c erl_comm.c driver.c
        gcc -o wand `pkg-config --cflags --libs MagickWand` wand.c erl_comm.c driver.c

clean:
        rm wand
        rm *beam
```

```erlang
%% ps_barcode.app
{application, ps_barcode,
 [{description, "barcode image generator based on ps-barcode"},
  {vsn, "1.0"},
  {modules, [ps_barcode_app, ps_barcode_supervisor, barcode_data, wand, ps_bc]},
  {registered, [ps_bc, wand, ps_barcode_supervisor]},
  {applications, [kernel, stdlib]},
  {mod, {ps_barcode_app, []}},
  {start_phases, []}]}.
```

```erlang
-module(ps_barcode_app).
-behaviour(application).
-export([start/2, stop/1]).

start(_Type, StartArgs) -> ps_barcode_supervisor:start_link(StartArgs).
stop(_State) -> ok.
```

```erlang
-module(ps_barcode_supervisor).
-behavior(supervisor).

-export([start/0, start_for_testing/0, start_link/1, init/1]).

start() ->
    spawn(fun() -> supervisor:start_link({local, ?MODULE}, ?MODULE, _Arg = []) end).

start_for_testing() ->
    {ok, Pid} = supervisor:start_link({local, ?MODULE}, ?MODULE, _Arg = []),
    unlink(Pid).

start_link(Args) ->
    supervisor:start_link({local, ?MODULE}, ?MODULE, Args).

init([]) ->
    {ok, {{one_for_one, 3, 10},
          [{tag1,
            {wand, start, []},
            permanent,
            brutal_kill,
            worker,
            [wand]},
           {tag2,
            {ps_bc, start, []},
            permanent,
            10000,
            worker,
            [ps_bc]}]}}.
```

The `Makefile` is not, strictly speaking, necessary, but a bunch of stuff needs to be done manually in its absence. The above code is approximately equivalent to [a Lisp `.asd` file](https://github.com/xach/quickproject/), in that it tells Erlang what needs to be compiled/called in order to run the system I'm about to define[^incidentally-didnt-do-this-first].

[^incidentally-didnt-do-this-first]: Incidentally, I didn't do this first. I sort of wish I had in retrospect, because it would have saved me some dicking around with `erl`, but I actually wrote the code first, then wrote the above based on it. Also incidentally, a lot of it doesn't seem like much of it will change on a project-by-project basis. That tells me that we're either working with the wrong abstractions, or there are tricky things you can do at this stage that I haven't yet grasped. It also tells me that I should probably write some generation scripts for it.

```erlang
  {modules, [ps_barcode_app, ps_barcode_supervisor, barcode_data, wand, ps_bc]},
```

That line specifies which other modules we'll be loading as part of the application, as well as their start order (which is relevant for a certain supervision strategy).

```erlang
  {registered, [ps_bc, wand, ps_barcode_supervisor]},
```

That one specifies registered processes we expect.

```erlang
  {mod, {ps_barcode_app, []}},
```

That one tells Erlang which module's `start` function to call in order to start the application, and what arguments to pass it as `StartArgs`.

```erlang
init([]) ->
    {ok, {{one_for_one, 3, 10},
          [{tag1,
            {wand, start, []},
            permanent,
            brutal_kill,
            worker,
            [wand]},
           {tag2,
            {ps_bc, start, []},
            permanent,
            10000,
            worker,
            [ps_bc]}]}}.
```

*That* does something interesting; it defines how the [supervisor](http://www.erlang.org/doc/man/supervisor.html) should act, and how it should treat its child processes. `{one_for_one, 3, 10}` means that if a supervised process errors, it should be restarted on its own up to 3 times in 10 seconds[^one-for-all-and-rest-for-one]. Both sub-processes are `permanent`[^which-means-they-get-restarted] `worker`s[^which-means-we-have-a-shallow-tree]. The last interesting bit is the `brutal_kill`/`10000` part; that's the `Shutdown` variable. It determines how the process should be terminated; `brutal_kill` means "kill the process right away", an integer means "send the process a stop command and wait up to this many milliseconds, then kill it".

[^one-for-all-and-rest-for-one]: `one_for_all` and `rest_for_one` are other [possible strategies](http://www.erlang.org/doc/design_principles/sup_princ.html#strategy), `_all` restarts all child processes rather than just the one that errored, and `rest_` just restarts processes later in the start order.

[^which-means-they-get-restarted]: Which means they get restarted when they error, *and* hang around after they've finished their work.

[^which-means-we-have-a-shallow-tree]: Which means that we have a pretty shallow supervision tree in this case, but we really don't need more.

Lets follow the applications' start order and move on to

```erlang
-module(barcode_data).
-export([read_default_file/0, read_file/1]).
-export([export_ets_file/1, import_ets_file/0]).

export_ets_file(Table) -> ets:tab2file(Table, "ps-barcode-blocks").
import_ets_file() -> {ok, Tab} = ets:file2tab(filename:absname("ps-barcode-blocks")), Tab.

read_default_file() -> read_file("barcode.ps").
read_file(Filename) ->
    {ok, File} = file:open(Filename, [read]),
    TableId = ets:new(ps_barcode_blocks, [ordered_set]),
    trim_flash(File),
    {ok, Tab} = read_all_blocks(File, TableId),
    file:close(File),
    Tab.

trim_flash(IoDevice) -> read_until(IoDevice, "% --BEGIN TEMPLATE").

read_all_blocks(IoDevice, TableId) ->
    case Res = read_block(IoDevice) of
        [] -> {ok, TableId};
        _ -> ets:insert(TableId, parse_block(Res)),
             read_all_blocks(IoDevice, TableId)
    end.

read_block(IoDevice) -> read_until(IoDevice, "% --END ").

parse_block([["%", "BEGIN", "PREAMBLE"] | Body]) ->
    {preamble, lists:append(Body)};
parse_block([["%", "BEGIN", "RENDERER", Name] | Body]) ->
    {list_to_atom(Name), renderer, lists:append(Body)};
parse_block([["%", "BEGIN", "ENCODER", Name] | Body]) ->
    parse_encoder_meta(Name, Body);
parse_block(_) -> {none}.

parse_encoder_meta (Name, Encoder) -> parse_encoder_meta(Name, Encoder, [], {[], [], []}).
parse_encoder_meta (Name, [["%", "RNDR:" | Renderers] | Rest], Acc, {_, R, S}) ->
    parse_encoder_meta(Name, Rest, Acc, {Renderers, R, S});
parse_encoder_meta (Name, [["%", "REQUIRES" | Reqs] | Rest], Acc, {A, _, S}) ->
    parse_encoder_meta(Name, Rest, Acc, {A, Reqs, S});
parse_encoder_meta (Name, [["%", "SUGGESTS" | Suggs] | Rest], Acc, {A, R, _}) ->
    parse_encoder_meta(Name, Rest, Acc, {A, R, Suggs});
parse_encoder_meta (Name, [["%", "EXOP:" | Exop] | Rest], Acc, Cmp) ->
    parse_encoder_meta(Name, Rest, [{def_arg, Exop} | Acc], Cmp);
parse_encoder_meta (Name, [["%", "EXAM:" | Exam] | Rest], Acc, Cmp) ->
    parse_encoder_meta(Name, Rest, [{example, string:join(Exam, " ")} | Acc], Cmp);
parse_encoder_meta (Name, [["%" | _] | Rest], Acc, Cmp) ->
    parse_encoder_meta(Name, Rest, Acc, Cmp);
parse_encoder_meta (Name, Body, [DefArgs, Example], {A, R, S}) ->
    Reqs = [list_to_atom(strip_nl(X)) || X <- lists:append([A, R, S])],
    {list_to_atom(Name), encoder, {requires, Reqs}, Example, DefArgs, lists:append(Body)}.

strip_nl(String) -> string:strip(String, right, $\n).

read_until(IoDevice, StartsWith) -> read_until(IoDevice, StartsWith, []).
read_until(IoDevice, StartsWith, Acc) ->
    case file:read_line(IoDevice) of
        {ok, "\n"} ->
            read_until(IoDevice, StartsWith, Acc);
        {ok, Line} ->
            case lists:prefix(StartsWith, Line) of
                true ->
                    lists:reverse(Acc);
                false ->
                    read_until(IoDevice, StartsWith,
                               [process_line(Line) | Acc])
            end;
        {error, _} -> error;
        eof -> lists:reverse(Acc)
    end.

process_line(Line) ->
    case lists:prefix("% --", Line) of
        true -> split_directive_line(Line);
        false -> Line
    end.

split_directive_line(Line) ->
    [X || X <- re:split(strip_nl(Line), "( |--)", [{return, list}]),
          X /= " ", X /= [], X /= "--", X /="\n"].
```

This is a reasonably simple reader program. The goal of it is to break [that 17111 line .ps file](https://code.google.com/p/postscriptbarcode/downloads/detail?name=barcode-2012-04-26.ps) into individual components. First, a `preamble` (basic definitions that need to go into each file), then a set of `renderer`s[^routines-that-do-general-stuff], and a rather large number of `encoder`s[^routines-that-specialize-on-barcodes]. These components are stored in an [ETS](http://www.erlang.org/doc/man/ets.html) table held in memory. The initial Postscript file only needs to be parsed once; the resulting ETS table is then exported to a file on disk so that it can just be loaded in the future.

[^routines-that-do-general-stuff]: Routines that do general operations for a particular class of barcode, such as linear or matrix.

[^routines-that-specialize-on-barcodes]: Routines that do the job of converting a specific piece of data into a particular type of barcode, such as qrcode, code93 or datamatrix.

Do note the nested `case` statements there. Really, I should have been able to write that as

```erlang
        ...
        {ok, Line} where lists:prefix(StartsWith, Line) -> lists:reverse(Acc);
        {ok, Line} -> read_until(IoDevice, StartsWith, [process_line(Line) | Acc]);
        ...
```

but even though `lists:prefix` is a perfectly functional predicate, it's not in [that blessed subset of Erlang](http://www.erlang.org/doc/reference_manual/expressions.html#id79432) that can be called from within a guard sequence. The consequence, in this case, is that I have to bust out a second `case` block, and waste six lines doing it. Moving onto sorting PS blocks...

```erlang
parse_block([["%", "BEGIN", "PREAMBLE"] | Body]) ->
    {preamble, lists:append(Body)};
parse_block([["%", "BEGIN", "RENDERER", Name] | Body]) ->
    {list_to_atom(Name), renderer, lists:append(Body)};
parse_block([["%", "BEGIN", "ENCODER", Name] | Body]) ->
    parse_encoder_meta(Name, Body);
parse_block(_) -> {none}.
```

The `preamble` and `renderer`s are really just named strings, but the `encoder`s have more metadata about them.

```erlang
parse_encoder_meta (Name, Encoder) -> parse_encoder_meta(Name, Encoder, [], {[], [], []}).
parse_encoder_meta (Name, [["%", "RNDR:" | Renderers] | Rest], Acc, {_, R, S}) ->
    parse_encoder_meta(Name, Rest, Acc, {Renderers, R, S});
parse_encoder_meta (Name, [["%", "REQUIRES" | Reqs] | Rest], Acc, {A, _, S}) ->
    parse_encoder_meta(Name, Rest, Acc, {A, Reqs, S});
parse_encoder_meta (Name, [["%", "SUGGESTS" | Suggs] | Rest], Acc, {A, R, _}) ->
    parse_encoder_meta(Name, Rest, Acc, {A, R, Suggs});
parse_encoder_meta (Name, [["%", "EXOP:" | Exop] | Rest], Acc, Cmp) ->
    parse_encoder_meta(Name, Rest, [{def_arg, Exop} | Acc], Cmp);
parse_encoder_meta (Name, [["%", "EXAM:" | Exam] | Rest], Acc, Cmp) ->
    parse_encoder_meta(Name, Rest, [{example, string:join(Exam, " ")} | Acc], Cmp);
parse_encoder_meta (Name, [["%" | _] | Rest], Acc, Cmp) ->
    parse_encoder_meta(Name, Rest, Acc, Cmp);
parse_encoder_meta (Name, Body, [DefArgs, Example], {A, R, S}) ->
    Reqs = [list_to_atom(strip_nl(X)) || X <- lists:append([A, R, S])],
    {list_to_atom(Name), encoder, {requires, Reqs}, Example, DefArgs, lists:append(Body)}.
```

This is not the most elegant function. In fact, now that I look at it, it seems like I could fairly easily replace that `{A, R, S}` tuple with a list accumulator.

> EDIT:
> Turns out there was a reason I did it this way; we need this data to be in the order of Renderers, Required, Suggested, but the order they're parsed in is actually Required, Suggested, Renderers (also, some components have no requirements, and some have no suggestions). The ordering is confusing enough that I just decided to keep it explicit.
>
> Wed, 16 May, 2012

What we're doing here is breaking apart an `encoder` block, and pulling out

- the list of other blocks we need to output before this one[^renderer-required-encoder]
- a piece of example data that this particular encoder can handle[^some-like-datamatrix-and-qrcode]
- the default arguments to passed to this `encoder`
- the body code of this `encoder`

[^renderer-required-encoder]: `renderer`s, required `encoder`s and suggested `encoders`.

[^some-like-datamatrix-and-qrcode]: Some, like `datamatrix` and `qrcode`, can handle almost arbitrary string information, while others are restricted to a subset of ascii, and others require a specific number of numeric characters.

The list of required blocks is exhaustive for each `encoder`, so we don't need to recursively check requirements later, it's enough to store and act on all requirements of a given barcode.

```erlang
-export([read_default_file/0, read_file/1]).
-export([export_ets_file/1, import_ets_file/0]).
```

Those exported functions are really all that a user of this module should ever need to call; you're either processing a new revision of the `ps` file, or you're importing the already exported ETS table derived from the `ps` file, or you're exporting a new ETS table for later loading. Now that we've seen how we store the relevant data, lets take a look at

```erlang
-module(wand).

-behaviour(gen_server).

-export([start/0, stop/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
         terminate/2, code_change/3]).

-export([process/1]).

process(Filename) -> gen_server:call(?MODULE, {process_barcode, Filename}).

handle_call({process_barcode, Filename}, _From, State) ->
    State ! {self(), {command, Filename}},
    receive
        {State, {data, Data}} ->
            {reply, decode(Data), State}
    end;
handle_call({'EXIT', _Port, Reason}, _From, _State) ->
    exit({port_terminated, Reason}).

decode([0]) -> {ok, 0};
decode([1]) -> {error, could_not_read};
decode([2]) -> {error, could_not_write}.

%%%%%%%%%%%%%%%%%%%% generic actions
start() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
stop() -> gen_server:call(?MODULE, stop).

%%%%%%%%%%%%%%%%%%%% gen_server handlers
init([]) -> {ok, open_port({spawn, filename:absname("wand")}, [{packet, 2}])}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, State) -> State ! {self(), close}, ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
```

This is actually pretty much the same C Port file I [used last time](http://langnostic.blogspot.ca/2012/04/notes-from-borders-of-erlang.html), except that this one has been re-written to use [`gen_server`](http://www.erlang.org/doc/man/gen_server.html), rather than being plain Erlang code. I still refuse to use that godawful file template they ship with their Emacs mode though[^as-a-massive-aside]. All it does is call out to a C program named `wand` to do the actual image processing involved in generating these barcodes. All you need to know is that we send it a barcodes' file name, and it quickly generates a high-res PNG version in the same folder.

[^as-a-massive-aside]: As an aside here, that's one of the things that really rustles my jimmies about Erlang. I've gotten extremely used to including a pretty extensive documentation string with each Common Lisp function and method, knowing that a potential user will be able to make full use of any `describe` calls they make. It's actually even better for methods, since you get the documentation for the `generic` you define, as well as a compilation of all doc-strings for the related `defmethod` calls. Erlang isn't having any of this shit. If you want to include doc-strings, you can damn well write Java-style precisely formatted comments and use a separate doc extractor to read them. I guess this is how most languages do it? It still seems stupid to have a system this dynamic that *doesn't* allow runtime documentation pokes. Sigh. Ok, let's get back to it.

Right, that's it for the periphery, lets finally dive into

```erlang
-module(ps_bc).

-behaviour(gen_server).

-export([start/0, stop/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

-export([help/0, help/1, write/3, write/5, generate/2, generate/3, change/1, make_tempname/0]).

help() -> gen_server:call(?MODULE, help).
help(BarcodeType) -> gen_server:call(?MODULE, {help, BarcodeType}).
write(DestFolder, BarcodeType, Data) ->
    write(DestFolder, BarcodeType, Data, 200, 200).
write(DestFolder, BarcodeType, Data, Width, Height) ->
    gen_server:call(?MODULE, {write, DestFolder, BarcodeType, Data, Width, Height}).
generate(BarcodeType, Data) -> generate("/tmp/", BarcodeType, Data).
generate(DestFolder, BarcodeType, Data) ->
    NameOfTempFile = write(DestFolder, BarcodeType, Data),
    wand:process(NameOfTempFile),
    NameOfTempFile.
change(TableId) -> gen_server:call(?MODULE, {change, TableId}).

handle_call(help, _From, State) ->
    {reply, ets:match(State, {'$1', encoder, '_', '_', '_', '_'}), State};
handle_call({help, BarcodeType}, _From, State) ->
    {reply, ets:match(State, {BarcodeType, encoder, '_', '$1', '_', '_'}), State};
handle_call({write, DestFolder, BarcodeType, Data, Width, Height}, _From, State) ->
    Fname = make_tempname(DestFolder),
    {ok, File} = file:open(Fname, [write, exclusive]),
    [[{requires, CompList}, {def_arg, ExArgs}]] = ets:match(State, {BarcodeType, encoder, '$1', '_', '$2', '_'}),
    file:write(File, io_lib:format("%!PS-Adobe-2.0\n%%BoundingBox: 0 0 ~w ~w\n%%LanguageLevel: 2\n", [Width, Height])),
    write_component(preamble, State, File),
    file:write(File, "\n/Helvetica findfont 10 scalefont setfont\n"),
    lists:map(fun (C) -> write_component(C, State, File) end, CompList),
    write_component(BarcodeType, State, File),
    write_barcode(File, BarcodeType, ExArgs, Data),
    file:close(File),
    {reply, Fname, State};
handle_call({change_table, Tab}, _From, _State) ->
    {reply, {watching_table, Tab}, Tab}.

make_tempname() ->
    {A, B, C} = now(),
    [D, E, F] = lists:map(fun integer_to_list/1, [A, B, C]),
    lists:append(["tmp.", D, ".", E, ".", F]).
make_tempname(TargetDir) ->
    filename:absname_join(TargetDir, make_tempname()).

write_component(preamble, Table, File) ->
    [[Pre]] = ets:match(Table, {preamble, '$1'}),
    file:write(File, Pre);
write_component(Name, Table, File) ->
    file:write(File, lookup_component(Name, Table)).

write_barcode(File, datamatrix, _, Data)        -> format_barcode_string(File, datamatrix, "", Data);
write_barcode(File, BarcodeType, ExArgs, Data)  -> format_barcode_string(File, BarcodeType, string:join(ExArgs, " "), Data).

format_barcode_string(File, BarcodeType, ExArgString, DataString) ->
    io:format(File, "10 10 moveto (~s) (~s) /~s /uk.co.terryburton.bwipp findresource exec showpage",
              [DataString, ExArgString, BarcodeType]).

lookup_component(Name, Table) ->
    Ren = ets:match(Table, {Name, renderer, '$1'}),
    Enc = ets:match(Table, {Name, encoder, '_', '_', '_', '$1'}),
    case {Ren, Enc} of
        {[], [[Res]]} -> Res;
        {[[Res]], []} -> Res
    end.

%%%%%%%%%%%%%%%%%%%% generic actions
start() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). %% {local/global, Name}, Mod, InitArgs, Opts
stop() -> gen_server:call(?MODULE, stop).

%%%%%%%%%%%%%%%%%%%% gen_server handlers
init([]) -> {ok, barcode_data:import_ets_file()}.
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
```

This is where the meat of the application resides, so I'll take my time with it.

First off, note that the `init` function loads that ETS file we generated in `barcode_data`.

```erlang
init([]) -> {ok, barcode_data:import_ets_file()}.
```

That's where our data is stored, and we'll be looking up components by referring to it.

```erlang
lookup_component(Name, Table) ->
    Ren = ets:match(Table, {Name, renderer, '$1'}),
    Enc = ets:match(Table, {Name, encoder, '_', '_', '_', '$1'}),
    case {Ren, Enc} of
        {[], [[Res]]} -> Res;
        {[[Res]], []} -> Res
    end.
```

This is (again) not the most elegant code. Really, what I'd want to do is look up `Ren` first, check if it returned something, *then* check whether an `Enc` exists. That would save me a look-up every once in a while[^inst-really-worth-saving]. Do take note that there's no clause to handle the event that a faulty index was passed; in that case, the process will fail with an unmatched pattern and promptly be restarted. This function is in turn used by `write_component` to actually output the given block to a file

[^inst-really-worth-saving]: Which, granted, isn't really worth saving given how blazingly fast ETS is, but still.

```erlang
write_component(preamble, Table, File) ->
    [[Pre]] = ets:match(Table, {preamble, '$1'}),
    file:write(File, Pre);
write_component(Name, Table, File) ->
    file:write(File, lookup_component(Name, Table)).
```

Before we tear into `handle`, just one more note about the remaining interesting helper function

```erlang
make_tempname() ->
    {A, B, C} = now(),
    [D, E, F] = lists:map(fun integer_to_list/1, [A, B, C]),
    lists:append(["tmp.", D, ".", E, ".", F]).
make_tempname(TargetDir) ->
    filename:absname_join(TargetDir, make_tempname()).
```

Actually, two functions (`make_tempname/0` and `make_tempname/1`). I thought about just using `os:cmd("mktemp")` instead, but decided against it. `make_tempname` uses `now()` to generate a unique temporary filename. It optionally takes a directory specification, in which case it creates an absolute filename in that directory.

By the way, that's how you handle optional arguments in Erlang. You create multiple functions with the same name, but with different arity and just write the matching expression for each. It's surprisingly elegant, and the only thing differentiating these from a single function declaration is that they're separated by `.` rather than by `;`. Obviously, if you plan on extending such a function to the users of your module, you need to export all the arities you've defined. I wasn't being *needlessly* pedantic earlier, Erlang treats `make_tempname/0` and `make_tempname/1` as completely separate functions.

Right, now then.

```erlang
handle_call(help, _From, State) ->
    {reply, ets:match(State, {'$1', encoder, '_', '_', '_', '_'}), State};
handle_call({help, BarcodeType}, _From, State) ->
    {reply, ets:match(State, {BarcodeType, encoder, '_', '$1', '_', '_'}), State};
handle_call({write, DestFolder, BarcodeType, Data, Width, Height}, _From, State) ->
    Fname = make_tempname(DestFolder),
    {ok, File} = file:open(Fname, [write, exclusive]),
    [[{requires, CompList}, {def_arg, ExArgs}]] = ets:match(State, {BarcodeType, encoder, '$1', '_', '$2', '_'}),
    file:write(File, io_lib:format("%!PS-Adobe-2.0\n%%BoundingBox: 0 0 ~w ~w\n%%LanguageLevel: 2\n", [Width, Height])),
    write_component(preamble, State, File),
    file:write(File, "\n/Helvetica findfont 10 scalefont setfont\n"),
    lists:map(fun (C) -> write_component(C, State, File) end, CompList),
    write_component(BarcodeType, State, File),
    write_barcode(File, BarcodeType, ExArgs, Data),
    file:close(File),
    {reply, Fname, State};
handle_call({change_table, Tab}, _From, _State) ->
    {reply, {watching_table, Tab}, Tab}.
```

The last directive there should probably be implemented as a `handle_cast` rather than `handle_call`[^difference-handle-cast]. The first two should probably return processed data rather than raw ETS results. Rest assured that mental notes have been made. The message `help` returns a list of available `encoder`s[^which-well-use-later], while asking for help with a specific `encoder` will return its example data. All the meat is in that extra large message handler in the middle.

[^difference-handle-cast]: The only difference being that `handle_cast` doesn't send a response message to its caller.

[^which-well-use-later]: Which we'll use later to give the user something to do about them.

Deep breath.

A message of `{write, DestFolder, BarcodeType, Data, Width, Height}` will output `Data` in a `BarcodeType` barcode in the `DestFolder` folder and format it to `Width`x`Height` dimensions. That's actually going to get trickier. Right now, the dimensions are just assumed to be 200x200 in the initial PS, and that C module is expected to output a properly formatted PS file. There are a few problems with that though[^note-the-imagemagick-api], so what I will ultimately want to do is have the C module return the appropriate dimensions and have `ps_bc` change this initial file later. That's another TODO.

[^note-the-imagemagick-api]: Specifically, since I'm using the Imagemagick API, the PS that it outputs is actually rasterised. That means it'll be much larger than the initial file and take that much longer to output. Literally the only advantage to it is that it properly sets the width and height of the document.

What the `write` message actually does, in order is

- generates a tempfile name for the directory it was passed
- opens that `File` for output
- looks up the required blocks in our ETS table
- writes the preamble to `File`
- writes the required blocks to `File`
- writes the barcode component to `File`
- writes a Postscript directive invoking that component with `Data` to `File`
- closes `File`
- replies with the absolute tempfile name that it generated

And there you have it, we now have a barcode PS file in the specified location.

The rest of the functions here are either `gen_server` pieces (which I won't go into), or interface functions (which I will)

```erlang
help() -> gen_server:call(?MODULE, help).
help(BarcodeType) -> gen_server:call(?MODULE, {help, BarcodeType}).
write(DestFolder, BarcodeType, Data) ->
    write(DestFolder, BarcodeType, Data, 200, 200).
write(DestFolder, BarcodeType, Data, Width, Height) ->
    gen_server:call(?MODULE, {write, DestFolder, BarcodeType, Data, Width, Height}).
generate(BarcodeType, Data) -> generate("/tmp/", BarcodeType, Data).
generate(DestFolder, BarcodeType, Data) ->
    NameOfTempFile = write(DestFolder, BarcodeType, Data),
    wand:process(NameOfTempFile),
    NameOfTempFile.
change(TableId) -> gen_server:call(?MODULE, {change, TableId}).
```

This is a set of exported functions to let outside modules easily interact with the internal `ps_bc` process. `change`, `help` and `write` map to the corresponding `handle_call` messages we looked at earlier[^i-do-export-help-and-write]. `generate` is something else. This is the principal function I expect to be called from outside the module, though AFAIK, there's no way to highlight that from within the code. To that end, it collects everything you need to create a barcode from start to finish; it accepts a `BarcodeType` and `Data` (and optionally a `DestFolder`) and calls `write/3` to create the directory, then `wand:process` to create the corresponding PNG and rasterized PS file, and finally returns the tempfile name that it generated. That should probably actually return a list of absolute file-names it created rather than just the base name. Mental note number 6.

[^i-do-export-help-and-write]: Note that I do export `help/0`, `help/1`, `write/3` and `write/5` separately.

Whew! At the risk of pulling a Yegge, this piece is turning out *a lot* longer than I though it was going to be. Lets get it wrapped up quickly.

## Nitrogen

[Nitrogen](http://nitrogenproject.com/) is an Erlang web framework I've been playing with. I won't explain it in depth, just use it to show you how you'd go about invoking the above program for realsies. In fact, here's a `nitrogen/rel/nitrogen/site/src/index.erl` that will call out to `ps_barcode` to generate a barcode based on user input and let them download the bitmap and Postscript file:

```erlang
%% -*- mode: nitrogen -*-
-module (index).
-compile(export_all).
-include_lib("nitrogen_core/include/wf.hrl").

main() -> #template { file="./site/templates/bare.html" }.

title() -> "Welcome to Nitrogen".

body() ->
    #container_12 { body=[
        #grid_8 { alpha=true, prefix=2, suffix=2, omega=true, body=inner_body() }
    ]}.

inner_body() ->
    [
        #h3 { text="PS Barcode Generator" },
        #h1 { text="In MOTHERFUCKING ERLANG"},
        #p{},
        #textbox { id=barcode_data, text=get_example(qrcode)},
        barcode_type_dropdown(qrcode),
        #button { id=button, text="Generate", postback=click },
        #p{ id=result, body=[
            #image { id=barcode_img },
            #p { id=barcode_link }
        ]}
    ].

barcode_type_dropdown(DefaultType) ->
    Types = rpc:call('ps_barcode@127.0.1.1', ps_bc, help, []),
    #dropdown { id=barcode_type, value=DefaultType, postback=select_type,
        options=lists:map(fun ([T]) -> #option {text=T, value=T} end, Types)
    }.

get_example(BarcodeType) ->
    [[{example,Example}]] = rpc:call('ps_barcode@127.0.1.1', ps_bc, help, [BarcodeType]),
    Example.

event(click) ->
    [_, Fname] = re:split(
        rpc:call('ps_barcode@127.0.1.1', ps_bc, generate,
            [filename:absname("site/static/images"), list_to_atom(wf:q(barcode_type)), wf:q(barcode_data)]),
        "site/static", [{return, list}]),
    wf:replace(barcode_img,
        #image {
            id=barcode_img,
            image=string:concat(Fname, ".png"),
            actions=#effect { effect=highlight }
    }),
    wf:replace(barcode_link,
        #link {
            id=barcode_link,
            text="Download PS file",
            url=string:concat(Fname, ".ps")
    });
event(select_type) ->
    wf:set(barcode_data, get_example(list_to_atom(wf:q(barcode_type)))).
```

The actual calls to our application happen

```erlang
get_example(BarcodeType) ->
    [[{example,Example}]] = rpc:call('ps_barcode@127.0.1.1', ps_bc, help, [BarcodeType]),
    Example.
```

here[^should-be-expecting-naked-string] and

[^should-be-expecting-naked-string]: Which, again, really should be expecting a naked string response rather than a raw ETS lookup record.

```erlang
        ...
        rpc:call('ps_barcode@127.0.1.1', ps_bc, generate,
            [filename:absname("site/static/images"), list_to_atom(wf:q(barcode_type)), wf:q(barcode_data)]),
        "site/static", [{return, list}]),
        ...
```

here. Recall that `make run` on the `Makefile` I defined earlier started a node named `'ps_barcode@127.0.1.1'` and started our application in it. So, if we want to use it from another Erlang node, all we have to do is start them both up using the same [`cookie`](http://erlang.org/pipermail/erlang-questions/2001-December/004153.html), and then use the built in `rpc:call` function, specifying the appropriate node, module, function and arguments. The return message is going to be a response from our application.

The code shown here won't actually run on its own[^complete-code-doesnt-work-yet], I left out the C file[^was-going-to-discuss-but-too-long], as well as the actual [barcode.ps](https://code.google.com/p/postscriptbarcode/downloads/detail?name=barcode-2012-04-26.ps) that the whole thing is based on. I'll act on the mental notes I've collected first, and then toss the whole thing up on [my github](https://github.com/Inaimathi) for you to play with. The nitrogen module is minimal enough that I won't feel bad for leaving it out, but the one above should work with your copy of nitrogen.

[^complete-code-doesnt-work-yet]: The complete code doesn't quite work yet either. Most of it does what it's supposed to, but I've already found [one odd case where things don't quite work](http://stackoverflow.com/questions/10604400/handling-timeouts-in-otp) the way they're supposed to. Tips and patches welcome.

[^was-going-to-discuss-but-too-long]: Which I was actually going to discuss, but this has gone on quite long enough already.

It's actually just a minimally modified version of the default `index.erl` file that comes with the framework, the only interesting pieces in it are the `rpc:call` lines which demonstrate the **hands-down most interesting thing** about Erlang. The thing that justifies putting up with all the warts and annoyances[^at-least-until]. I'll expand on that next time though, this was already more than enough stuff coming out of my mind.

[^at-least-until]: At least, until I learn enough about it to put together an analogous system in Common Lisp :P


text:
@implementation FBSDKDeviceUtilities

+ (UIImage *)buildQRCodeWithAuthorizationCode:(NSString *)authorizationCode
{
  NSString *authorizationUri = @"https://facebook.com/device";
  if ([authorizationUri length] > 0) {
    authorizationUri = [NSString stringWithFormat:@"https://facebook.com/device?user_code=%@&qr=1", authorizationCode];
  }
  NSData *qrCodeData = [authorizationUri dataUsingEncoding:NSISOLatin1StringEncoding];

  CIFilter *qrCodeFilter = [CIFilter filterWithName:@"CIQRCodeGenerator"];
  [qrCodeFilter setValue:qrCodeData forKey:@"inputMessage"];
  [qrCodeFilter setValue:@"M" forKey:@"inputCorrectionLevel"];

  CIImage *qrCodeImage = qrCodeFilter.outputImage;
  CGRect qrImageSize = CGRectIntegral(qrCodeImage.extent);
  CGSize qrOutputSize = CGSizeMake(200, 200);

  CIImage *resizedImage =
  [qrCodeImage imageByApplyingTransform: CGAffineTransformMakeScale(qrOutputSize.width / CGRectGetWidth(qrImageSize),
                                                                    qrOutputSize.height / CGRectGetHeight(qrImageSize))];

  return [UIImage imageWithCIImage:resizedImage];
}

@end

#endif

redpajama_set_name: RedPajamaGithub


text:
#if PAL_BUILD_GPU_DEBUG

#include "core/layers/gpuDebug/gpuDebugColorTargetView.h"
#include "core/layers/gpuDebug/gpuDebugDevice.h"
#include "core/layers/gpuDebug/gpuDebugImage.h"

namespace Pal
{
namespace GpuDebug
{

// =====================================================================================================================
ColorTargetView::ColorTargetView(
    IColorTargetView*                pNextView,
    const ColorTargetViewCreateInfo& createInfo,
    const Device*                    pDevice)
    :
    ColorTargetViewDecorator(pNextView, createInfo, pDevice),
    m_pDevice(pDevice),
    m_format(createInfo.swizzledFormat)
{
}

} // GpuDebug
} // Pal

#endif


text:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { SpikesTimelineDemoComponent } from './spikes-timeline-demo.component';

describe('SpikesTimelineDemoComponent', () => {
  let component: SpikesTimelineDemoComponent;
  let fixture: ComponentFixture<SpikesTimelineDemoComponent>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ SpikesTimelineDemoComponent ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(SpikesTimelineDemoComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should be created', () => {
    expect(component).toBeTruthy();
  });
});


text:
// Licensed to Cloudera, Inc. under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  Cloudera, Inc. licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

function magicLayout(vm) {
  loadLayout(vm, vm.initial.layout);
  $(document).trigger("magicLayout");
}

function loadLayout(viewModel, json_layout) {
  var _columns = [];

  $(json_layout).each(function (cnt, json_col) {
    var _rows = [];
    $(json_col.rows).each(function (rcnt, json_row) {
      var row = new Row([], viewModel);
      $(json_row.widgets).each(function (wcnt, widget) {
        row.addWidget(new Widget({
          size:widget.size,
          id: widget.id,
          name: widget.name,
          widgetType: widget.widgetType,
          properties: widget.properties,
          offset: widget.offset,
          loading: true,
          vm: viewModel
        }));
      });
      _rows.push(row);
    });
    var column = new Column(json_col.size, _rows);
    _columns = _columns.concat(column);
  });

  viewModel.columns(_columns);
}

// End dashboard lib

var Query = function (vm, query) {
  var self = this;

  self.qs = ko.mapping.fromJS([{'q': ''}]);
  self.fqs = ko.mapping.fromJS([]);

  self.toggleFacet = function (data) {
    var fq = self.getFacetFilter(data.widget.id());

    if (fq == null) {
      self.fqs.push(ko.mapping.fromJS({
        'id': data.widget.id(),
        'field': data.widget.field(),
        'filter': [data.facet.value()],
        'type': 'field'
      }));
    } else {
      $.each(self.fqs(), function (index, fq) {
        if (fq.id() == data.widget.id()) {
          if (fq.filter.indexOf(data.facet.value()) > -1) {
            fq.filter.remove(data.facet.value());
            if (fq.filter().length == 0) {
              self.fqs.remove(fq);
            }
          } else {
            fq.filter.push(data.facet.value());
          }
        }
      });
    }

    vm.search();
  }

  self.selectRangeFacet = function (data) {
    var fq = self.getFacetFilter(data.widget_id);

    if (fq == null) {
      self.fqs.push(ko.mapping.fromJS({
          'id': data.widget_id,
          'field': data.cat,
          'filter': [{'value': data.from, 'exclude': false}],
          'properties': [{'from': data.from, 'to': data.to}],
          'type': 'range'
      }));
    } else {
      var f = $.grep(fq.filter(), function(f) { return f.value() == data.from; });
      if (f.length > 0) { // Unselect
        fq.filter.remove(f[0]);
        $.each(fq.properties(), function (index, prop) {
          if (prop && prop.from() == data.from) {
            fq.properties.remove(prop);
          }
        });
        if (fq.filter().length == 0) {
          self.removeFilter(ko.mapping.fromJS({'id': data.widget_id}));
        }
      } else {
       fq.filter.push(ko.mapping.fromJS({'exclude': data.exclude ? true : false, 'value': data.from}));
       fq.properties.push(ko.mapping.fromJS({'from': data.from, 'to': data.to}));
      }
    }
  };

  self.getFacetFilter = function (facet_id) {
    var _facet = null;
    $.each(self.fqs(), function (index, facet) {
      if (facet.id() == facet_id) {
        _facet = facet;
        return false;
      }
    });
    return _facet;
  }
}

var Dashboard = function (vm, dashboard) {
  var self = this;

  self.id = ko.mapping.fromJS(dashboard.id);
  self.facets = ko.mapping.fromJS(dashboard.facets);
  self.properties = ko.mapping.fromJS(dashboard.properties);

  self.dropdownDbs = ko.observableArray([]);
  self.selectedDropdownDb = ko.observable("");
  self.selectedDropdownDb.subscribe(function(value) {
	self.properties()[0].database(self.selectedDropdownDb());
	if (self.selectedDropdownDb() && self.selectedDropdownTable()) {
	  self.updateFields();
	}
  });

  self.dropdownTables = ko.observableArray([]);
  self.selectedDropdownTable = ko.observable("");
  self.selectedDropdownTable.subscribe(function(value) {
	self.properties()[0].table(self.selectedDropdownTable());
	if (self.selectedDropdownDb() && self.selectedDropdownTable()) {
	  self.updateFields();
	}
  });

  self.updateDropdownDatabases = function(databases) {
    if (databases) {
      var i = databases.indexOf("_impala_builtins"); // Blacklist of system databases
      if (i != -1) {
        databases.splice(i, 1);
      }
      self.dropdownDbs(databases);
    }
  };

  self.fields = ko.computed(function () {
    if (self.properties() != null && self.properties().length > 0 && self.properties()[0].fields != null){
	  return self.properties()[0].fields();
    }
    return [];
  });
  self.fieldNames = ko.computed(function () {
	return $.map(self.fields(), function (field) { return field.name() });
  });

  self.resultsetShowFieldList = ko.observable(true);
  self.resultsetFieldsFilter = ko.observable(""); // For UI

  self.resultsetSelectedFields = ko.observableArray(self.fieldNames());
  /**self.resultsetSelectedFields.subscribe(function(value) {
    vm.search();
  });*/

  self.resultsetFilteredFields = ko.computed(function() {
    var _fields = [];
    $.each(self.fields(), function (index, field) {
      if (self.resultsetFieldsFilter() == "" || field.name().toLowerCase().indexOf(self.resultsetFieldsFilter().toLowerCase()) > -1){
        _fields.push(field);
      }
    });
    return _fields;
  });

  self.selectedNewFacetField = ko.observable();

  self.addFacet = function(facet_json) {
   $.post("/impala/dashboard/new_facet", {
       "dashboard": ko.mapping.toJSON(self),
       "facet_json": ko.mapping.toJSON(facet_json),
       "field": self.selectedNewFacetField(),
     }, function (data) {
       if (data.status == 0) {
         var facet = ko.mapping.fromJS(data.facet);
         facet.properties.limit.subscribe(function () {
           vm.search();
         });
         self.facets.push(facet);
         vm.search();
       } else {
         $(document).trigger("error", data.message);
       }
    }).fail(function (xhr, textStatus, errorThrown) {});
  }

  self.getFacetById = function (facet_id) {
    var _facet = null;
    $.each(self.facets(), function (index, facet) {
      if (facet.id() == facet_id) {
        _facet = facet;
        return false;
      }
    });
    return _facet;
  }

  self.updateFields = function(database, table) {
    $.post("/impala/dashboard/get_fields", {
    	"database": self.properties()[0].database(),
    	"table": self.properties()[0].table()
    }, function (data) {
      if (data.status == 0) {
        self.properties()[0].fields.removeAll();
        self.resultsetSelectedFields.removeAll();
    	$.each(data.fields, function (index, field) {
    	  self.properties()[0].fields.push(ko.mapping.fromJS(field));
    	  self.resultsetSelectedFields.push(field.name);
      	});
      }
    }).fail(function (xhr, textStatus, errorThrown) {});
  }
}

var ImpalaDashboardViewModel = function (query_json, dashboard_json, initial_json) {
    var self = this;

    self.isEditing = ko.observable(true);
    self.toggleEditing = function () {
      self.isEditing(! self.isEditing());
    };
    self.isRetrievingResults = ko.observable(false);
    self.previewColumns = ko.observable("");
    self.columns = ko.observable([]);

    loadLayout(self, dashboard_json.layout);

    self.query = new Query(self, query_json);
    self.dashboard = new Dashboard(self, dashboard_json.dashboard);
    self.initial = initial_json;

    self.results = ko.observableArray([]);
    self.results_facet = ko.observableArray([]);
    self.results_cols = ko.observableArray([]);

    self.inited = ko.observable(self.columns().length > 0);

    self.init = function(callback) {
      if (self.inited()){
        self.search();
      }
      callback();
    }

    self.search = function (callback) {
      self.isRetrievingResults(true);
      self.results.removeAll();

      var multiQs = $.map(self.dashboard.facets(), function(facet) {
        return $.post("/impala/dashboard/query", {
           "query": ko.mapping.toJSON(self.query),
           "dashboard": ko.mapping.toJSON(self.dashboard),
           "layout": ko.mapping.toJSON(self.columns),
           "facet": ko.mapping.toJSON(facet),
        }, function (data) {return data});
      });

      $.when.apply($, [
          $.post("/impala/dashboard/query", {
            "query": ko.mapping.toJSON(self.query),
            "dashboard": ko.mapping.toJSON(self.dashboard),
            "layout": ko.mapping.toJSON(self.columns),
            }, function (data) {
              self.isRetrievingResults(false);
              if (data.status == 0) {
            	self.results_cols(data.cols)
            	$.each(data.data, function (index, row) {
            	  self.results.push(row);
            	});
              } else {
                $(document).trigger("error", data.message);
              }
            })
          ].concat(multiQs)
      )
      .done(function() {
          if (multiQs.length > 0) {
            for (var i = 1; i < arguments.length; i++) {
              var facet = arguments[i][0];
              removeFrom(self.results_facet, facet.id);
              self.results_facet.push(ko.mapping.fromJS(facet));
            }
          }
        })
      .fail(function (xhr, textStatus, errorThrown) {
    	  $(document).trigger("error", errorThrown);
       });
    };

    function removeFrom(collection, item_id) {
      $.each(collection(), function (index, item) {
        if (item.id() == item_id) {
          collection.remove(item);
          return false;
        }
      });
    }

    self.getFacetFromResult = function (facet_id) {
      var _facet = null;
      $.each(self.results_facet(), function (index, facet) {
        if (facet.id() == facet_id) {
          _facet = facet;
          return false;
        }
      });
      return _facet;
    }

    self.getWidgetById = function (widget_id) {
      var _widget = null;
      $.each(self.columns(), function (i, col) {
        $.each(col.rows(), function (j, row) {
          $.each(row.widgets(), function (z, widget) {
            if (widget.id() == widget_id){
              _widget = widget;
            }
          });
        });
      });
      return _widget;
    }

    self.save = function () {
      $.post("/impala/dashboard/save", {
          "dashboard": ko.mapping.toJSON(self.dashboard),
          "layout": ko.mapping.toJSON(self.columns)
      }, function (data) {
        if (data.status == 0) {
          self.dashboard.id(data.id);
          $(document).trigger("info", data.message);
          if (window.location.search.indexOf("dashboard") == -1) {
            window.location.hash = '#dashboard=' + data.id;
          }
        }
        else {
          $(document).trigger("error", data.message);
        }
      }).fail(function (xhr, textStatus, errorThrown) {
        $(document).trigger("error", xhr.responseText);
      });
    };

    function bareWidgetBuilder(name, type){
      return new Widget({
        size: 12,
        id: UUID(),
        name: name,
        widgetType: type
      });
    }

    self.draggableFacet = ko.observable(bareWidgetBuilder("Facet", "facet-widget"));
    self.draggableResultset = ko.observable(bareWidgetBuilder("Grid Results", "resultset-widget"));
    self.draggableHistogram = ko.observable(bareWidgetBuilder("Histogram", "histogram-widget"));
    self.draggableBar = ko.observable(bareWidgetBuilder("Bar Chart", "bar-widget"));
    self.draggableMap = ko.observable(bareWidgetBuilder("Map", "map-widget"));
    self.draggableLine = ko.observable(bareWidgetBuilder("Line Chart", "line-widget"));
    self.draggablePie = ko.observable(bareWidgetBuilder("Pie Chart", "pie-widget"));
    self.draggableFilter = ko.observable(bareWidgetBuilder("Filter Bar", "filter-widget"));
};


text:
CREATE TABLE cs_test_table (
	test_id serial NOT NULL UNIQUE PRIMARY KEY,
	description text,
	the_number integer NOT NULL DEFAULT 0,
	is_active boolean NOT NULL DEFAULT TRUE,
	date_created timestamptz DEFAULT NOW()
);

INSERT INTO cs_test_table (description, the_number, is_active, date_created) VALUES ('first', 1, true, (NOW() - interval '2 minutes'));
INSERT INTO cs_test_table (description, the_number, is_active, date_created) VALUES ('second', 2, true, NOW());
INSERT INTO cs_test_table (description, the_number, is_active, date_created) VALUES ('third', 3, true, NOW());
INSERT INTO cs_test_table (description, the_number, is_active, date_created) VALUES ('fourth', 4 , false, NOW());
INSERT INTO cs_test_table (description, the_number, is_active, date_created) VALUES ('another', 999, true, (NOW() - interval '3 months'));


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
null

#### Original name
Cladosporium herbarum var. cellulosae Sartory, R. Sartory & J. Mey.

### Remarks
null


text:
package org.jenkinsci.plugins.mesos.api;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

import akka.NotUsed;
import akka.actor.ActorSystem;
import akka.stream.ActorMaterializer;
import akka.stream.QueueOfferResult;
import akka.stream.javadsl.Flow;
import akka.stream.javadsl.SourceQueueWithComplete;
import com.mesosphere.usi.core.models.PodId;
import com.mesosphere.usi.core.models.StateEvent;
import com.mesosphere.usi.core.models.commands.KillPod;
import com.mesosphere.usi.core.models.commands.SchedulerCommand;
import java.net.URL;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import org.jenkinsci.plugins.mesos.TestUtils;
import org.jenkinsci.plugins.mesos.TestUtils.JenkinsParameterResolver;
import org.jenkinsci.plugins.mesos.fixture.AgentSpecMother;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@ExtendWith(JenkinsParameterResolver.class)
public class SessionTest {

  private static final Logger logger = LoggerFactory.getLogger(SessionTest.class);

  static ActorSystem system = ActorSystem.create("mesos-scheduler-test");
  static ActorMaterializer materializer = ActorMaterializer.create(system);

  @Test
  public void testLaunchOverflow(TestUtils.JenkinsRule j) throws Exception {
    // Given a scheduler flow that never processes commands.
    final URL jenkinsUrl = new URL("https://jenkins.com");
    Settings settings = Settings.load().withCommandQueueBufferSize(1);
    final CompletableFuture<StateEvent> ignore = new CompletableFuture<>();
    final Flow<SchedulerCommand, StateEvent, NotUsed> schedulerFlow =
        Flow.of(SchedulerCommand.class).mapAsync(1, command -> ignore);

    // And a running session.
    SourceQueueWithComplete<SchedulerCommand> sourceQueue =
        Session.runScheduler(
                settings,
                schedulerFlow,
                event -> logger.debug("Received event {}", event),
                materializer)
            .first();
    Session session = new Session(sourceQueue);

    // And one agent is processed and one is queued.
    session
        .getCommands()
        .offer(AgentSpecMother.simple.buildLaunchCommand(jenkinsUrl, "agent1", "*"));
    session
        .getCommands()
        .offer(AgentSpecMother.simple.buildLaunchCommand(jenkinsUrl, "agent2", "*"));

    // When we enqueue a third agent
    CompletionStage<QueueOfferResult> result =
        session
            .getCommands()
            .offer(AgentSpecMother.simple.buildLaunchCommand(jenkinsUrl, "agent3", "*"));

    // Then backpressure hits us.
    QueueOfferResult offerFeedback = result.toCompletableFuture().get();
    assertThat(offerFeedback, is(QueueOfferResult.dropped()));
  }

  @Test
  void testKillOverflow(TestUtils.JenkinsRule j) throws Exception {
    // Given a scheduler flow that never processes commands.
    Settings settings = Settings.load().withCommandQueueBufferSize(1);
    final CompletableFuture<StateEvent> ignore = new CompletableFuture<>();
    final Flow<SchedulerCommand, StateEvent, NotUsed> schedulerFlow =
        Flow.of(SchedulerCommand.class).mapAsync(1, command -> ignore);

    // And a running session.
    SourceQueueWithComplete<SchedulerCommand> sourceQueue =
        Session.runScheduler(
                settings,
                schedulerFlow,
                event -> logger.debug("Received event {}", event),
                materializer)
            .first();
    Session session = new Session(sourceQueue);

    // And one agent is processed and one is queued.
    session.getCommands().offer(new KillPod(new PodId("agent1")));
    session.getCommands().offer(new KillPod(new PodId("agent2")));

    // When we kill a third agent
    CompletionStage<QueueOfferResult> result =
        session.getCommands().offer(new KillPod(new PodId("agent3")));

    // Then backpressure hits us.
    QueueOfferResult offerFeedback = result.toCompletableFuture().get();
    assertThat(offerFeedback, is(QueueOfferResult.dropped()));
  }
}


text:
package edu.gemini.spModel.io.impl.migration

import java.io.InputStreamReader

import edu.gemini.pot.sp.ISPProgram
import edu.gemini.pot.spdb.{DBLocalDatabase, IDBDatabaseService}
import edu.gemini.spModel.io.impl.PioSpXmlParser
import org.junit.Assert._

/**
 * Base trait for all migration tests
 */
trait MigrationTest {

  protected def withTestOdb(block: IDBDatabaseService => Unit): Unit = {
    val odb = DBLocalDatabase.createTransient()
    try {
      block(odb)
    } finally {
      odb.getDBAdmin.shutdown()
    }
  }

  protected def withTestProgram(programName: String, block: (IDBDatabaseService, ISPProgram) => Unit): Unit = withTestOdb { odb =>
    val parser = new PioSpXmlParser(odb.getFactory)
    parser.parseDocument(new InputStreamReader(getClass.getResourceAsStream(programName))) match {
      case p: ISPProgram => block(odb, p)
      case _             => fail("Expecting a science program")
    }
  }

}


text:
TEST_CASE("constructor: simple", "[constructor]") {
  int argc           = 1;
  const char *argv[] = {
    "/usr/bin/name",
    NULL,
  };

  CheckArg ca("name");

  auto ret = ca.parse(argc, (char **)argv);
  REQUIRE(ret == CA_ALLOK);

  SECTION("call name") {
    auto ret2 = ca.argv0();

    REQUIRE(ret2 == "/usr/bin/name");
  }

  SECTION("appname") {
    auto usage = ca.usage();

    REQUIRE(usage == "Usage: name [options]");
  }
}

TEST_CASE("constructor: simple (vector)", "[constructor]") {
  const vector<string> argv = {
    "/usr/bin/name",
  };

  CheckArg ca("name");

  auto ret = ca.parse(argv);
  REQUIRE(ret == CA_ALLOK);

  SECTION("call name") {
    auto ret2 = ca.argv0();
    REQUIRE(ret2 == "/usr/bin/name");
  }

  SECTION("appname") {
    auto usage = ca.usage();

    REQUIRE(usage == "Usage: name [options]");
  }
}

#ifdef HAS_STD_FILESYSTEM
TEST_CASE("constructor: app name autodetect", "[constructor]") {
  const vector<string> argv = {
    "/usr/bin/name",
  };

  CheckArg ca;

  auto ret = ca.parse(argv);
  REQUIRE(ret == CA_ALLOK);

  SECTION("call name") {
    auto ret2 = ca.argv0();
    REQUIRE(ret2 == "/usr/bin/name");
  }

  SECTION("appname") {
    auto usage = ca.usage();

    REQUIRE(usage == "Usage: name [options]");
  }
}
#endif


text:
require 'spec_helper_acceptance'

describe 'telegraf class' do

  context 'default parameters' do
    # Using puppet_apply as a helper
    it 'work without errors' do
      pp = <<-EOC
      class { 'telegraf': }
      EOC

      # Run it twice and test for idempotency
      apply_manifest(pp, :catch_failures => true)
      apply_manifest(pp, :catch_changes  => true)
    end

    describe package('telegraf') do
      it { is_expected.to be_installed }
    end

    describe service('telegraf') do
      it { is_expected.to be_enabled }
      it { is_expected.to be_running }
    end
  end
end


text:
<?php

use yii\helpers\Html;

/* @var $this yii\web\View */
/* @var $model app\models\ItemProgramacaoHasPacote */

$this->title = 'Update Item Programacao Has Pacote: ' . ' ' . $model->itemProgramacao_iditemProgramacao;
$this->params['breadcrumbs'][] = ['label' => 'Item Programacao Has Pacotes', 'url' => ['index']];
$this->params['breadcrumbs'][] = ['label' => $model->itemProgramacao_iditemProgramacao, 'url' => ['view', 'itemProgramacao_iditemProgramacao' => $model->itemProgramacao_iditemProgramacao, 'pacote_idpacote' => $model->pacote_idpacote]];
$this->params['breadcrumbs'][] = 'Update';
?>

<?= Html::encode($this->title) ?>

    <?= $this->render('_form', [
        'model' => $model,
    ]) ?>


text:
package org.apache.camel.component.couchbase;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.apache.camel.test.junit5.CamelTestSupport;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

public class ProduceMessagesSimpleTest extends CamelTestSupport {

    // Ignore test since build environment does not have any couchbase instance
    @Disabled
    @Test
    public void testInsert() throws Exception {
        MockEndpoint mock = getMockEndpoint("mock:result");
        mock.expectedMessageCount(1);

        template.sendBody("direct:start", "couchbase persist");
        assertMockEndpointsSatisfied();
        mock.message(0).body().equals("couchbase persist");

    }

    @Override
    protected RouteBuilder createRouteBuilder() {
        return new RouteBuilder() {
            @Override
            public void configure() throws Exception {

                // need couchbase installed on localhost
                from("direct:start").setHeader(CouchbaseConstants.HEADER_ID, constant("blabla:120771"))
                        .to("couchbase:http://192.168.1.102/test?additionalHosts=localhost&username=root&password=123456")
                        .to("mock:result");

            }
        };
    }
}


text:
package director_test

import (
	"bytes"
	"net/http"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/ghttp"

	. "github.com/cloudfoundry/bosh-cli/director"
)

var _ = Describe("Director", func() {
	var (
		director Director
		server   *ghttp.Server
	)

	BeforeEach(func() {
		director, server = BuildServer()
	})

	AfterEach(func() {
		server.Close()
	})

	Describe("EnableResurrection", func() {
		It("enables resurrection for all instances and returns without an error", func() {
			server.AppendHandlers(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("PUT", "/resurrection"),
					ghttp.VerifyBasicAuth("username", "password"),
					ghttp.VerifyHeader(http.Header{
						"Content-Type": []string{"application/json"},
					}),
					ghttp.VerifyBody([]byte(`{"resurrection_paused":false}`)),
				),
			)

			err := director.EnableResurrection(true)
			Expect(err).ToNot(HaveOccurred())
		})

		It("disables resurrection for all instances and returns without an error", func() {
			server.AppendHandlers(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("PUT", "/resurrection"),
					ghttp.VerifyBasicAuth("username", "password"),
					ghttp.VerifyHeader(http.Header{
						"Content-Type": []string{"application/json"},
					}),
					ghttp.VerifyBody([]byte(`{"resurrection_paused":true}`)),
				),
			)

			err := director.EnableResurrection(false)
			Expect(err).ToNot(HaveOccurred())
		})

		It("returns error if response is non-200", func() {
			AppendBadRequest(ghttp.VerifyRequest("PUT", "/resurrection"), server)

			err := director.EnableResurrection(true)
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(ContainSubstring("Changing VM resurrection state"))
		})
	})

	Describe("CleanUp", func() {
		It("cleans up all resources and returns without an error", func() {
			ConfigureTaskResult(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("POST", "/cleanup"),
					ghttp.VerifyBasicAuth("username", "password"),
					ghttp.VerifyHeader(http.Header{
						"Content-Type": []string{"application/json"},
					}),
					ghttp.VerifyBody([]byte(`{"config":{"remove_all":true}}`)),
				),
				"",
				server,
			)

			err := director.CleanUp(true)
			Expect(err).ToNot(HaveOccurred())
		})

		It("cleans up some resources and returns without an error", func() {
			ConfigureTaskResult(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("POST", "/cleanup"),
					ghttp.VerifyBasicAuth("username", "password"),
					ghttp.VerifyHeader(http.Header{
						"Content-Type": []string{"application/json"},
					}),
					ghttp.VerifyBody([]byte(`{"config":{"remove_all":false}}`)),
				),
				"",
				server,
			)

			err := director.CleanUp(false)
			Expect(err).ToNot(HaveOccurred())
		})

		It("returns error if response is non-200", func() {
			AppendBadRequest(ghttp.VerifyRequest("POST", "/cleanup"), server)

			err := director.CleanUp(true)
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(ContainSubstring("Cleaning up resources"))
		})
	})

	Describe("DownloadResourceUnchecked", func() {
		var (
			buf *bytes.Buffer
		)

		BeforeEach(func() {
			buf = bytes.NewBufferString("")
		})

		It("writes to the writer downloaded contents and returns without an error", func() {
			server.AppendHandlers(
				ghttp.CombineHandlers(
					ghttp.VerifyRequest("GET", "/resources/blob-id"),
					ghttp.VerifyBasicAuth("username", "password"),
					ghttp.RespondWith(http.StatusOK, "result"),
				),
			)

			err := director.DownloadResourceUnchecked("blob-id", buf)
			Expect(err).ToNot(HaveOccurred())

			Expect(buf.String()).To(Equal("result"))
		})

		It("returns error if response is non-200", func() {
			AppendBadRequest(ghttp.VerifyRequest("GET", "/resources/blob-id"), server)

			err := director.DownloadResourceUnchecked("blob-id", buf)
			Expect(err).To(HaveOccurred())
			Expect(err.Error()).To(ContainSubstring("Downloading resource 'blob-id'"))
		})
	})
})


text:
xdescribe("Game", () =>{
    var tgame;
    beforeEach(() =>{
       tgame = new cuteCrow.game();
    });
  it("exists", () =>{

    expect(typeof tgame).toEqual("object");
  });

  it("have method init", () =>{

   expect(typeof tgame.init).toEqual("function");
  });

  it("can add players", () =>{
    var tplayer =  new cuteCrow.player(0);
    tgame.addPlayer(tplayer);
    expect(tgame.players.length).toBe(1);
  });
  it("can remove players", ()=>{
    var tplayer =  new cuteCrow.player("player");
    tgame.addPlayer(tplayer);
    tgame.removePlayer("player");
    expect(tgame.players.length).toBe(0);
  });

  it("can move to another question", () =>{
    var questions = [
      {
        "id": 0,
        "question": "Co trzyma w rękach warszawska syrenka?\n",
        "anser1": "a.  miecz i tarczę\n",
        "anser2": "b. pochodnię\n"
      },
      {
        "id": 1,
        "question": "Jak brzmi hasło reklamowe Warszawy?\n",
        "anser1": "a. Warszawa Przygód!\n",
        "anser2": "b. Zakochaj się w Warszawie!\n"
      }
    ];
    var ntgame = new cuteCrow.game([],questions);
    expect(ntgame.currentQuestion).toBe(null);
    ntgame.init();
    expect(ntgame.currentQuestion.id).toBe(0);
    ntgame.nextQuestion();
    expect(ntgame.currentQuestion.id).toBe(1);
  });
});


text:
package v1

import "testing"

func TestSubscriptionGetStatus(t *testing.T) {
	r := &Subscription{
		Status: SubscriptionStatus{},
	}
	if got, want := r.GetStatus(), &r.Status.Status; got != want {
		t.Errorf("GetStatus=%v, want=%v", got, want)
	}
}

func TestSubscription_GetGroupVersionKind(t *testing.T) {
	c := Subscription{}
	gvk := c.GetGroupVersionKind()
	if gvk.Kind != "Subscription" {
		t.Errorf("Should be Subscription.")
	}
}


text:
package com.glatthar.authorizer.model.dto;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

public class MongoClient extends Client {

  private String clientId;

  private String clientSecret;

  private Integer refreshTokenValiditySeconds;
  private Integer accessTokenValiditySeconds;

  private Set<AuthorizationGrantType> authorizationGrantTypes;

  private Set<String> scope;

  private Set<String> registeredRedirectUri;

  private Collection<Role> roles;

  private Map<String, String> information;

  public String getClientId() {
    return clientId;
  }

  public void setClientId(String clientId) {
    this.clientId = clientId;
  }

  public String getClientSecret() {
    return clientSecret;
  }

  public void setClientSecret(String clientSecret) {
    this.clientSecret = clientSecret;
  }

  public Set<AuthorizationGrantType> getAuthorizationGrandTypes() {
    return authorizationGrantTypes;
  }

  public void setAuthorizationGrandTypes(Set<AuthorizationGrantType> authorizedGrantTypes) {
    this.authorizationGrantTypes = authorizedGrantTypes;
  }

  public Set<String> getScope() {
    return scope;
  }

  public void setScope(Set<String> scope) {
    this.scope = scope;
  }

  public Set<String> getRegisteredRedirectUri() {
    return registeredRedirectUri;
  }

  public void setRegisteredRedirectUri(Set<String> registeredRedirectUri) {
    this.registeredRedirectUri = registeredRedirectUri;
  }

  public Collection<Role> getRoles() {
    return roles;
  }

  public void setRoles(Collection<Role> roles) {
    this.roles = roles;
  }

  public Map<String, String> getInformation() {
    return information;
  }

  public void setInformation(Map<String, String> information) {
    this.information = information;
  }

  public Integer getRefreshTokenValiditySeconds() {
    return refreshTokenValiditySeconds;
  }

  public void setRefreshTokenValiditySeconds(Integer refreshTokenValiditySeconds) {
    this.refreshTokenValiditySeconds = refreshTokenValiditySeconds;
  }

  public Integer getAccessTokenValiditySeconds() {
    return accessTokenValiditySeconds;
  }

  public void setAccessTokenValiditySeconds(Integer accessTokenValiditySeconds) {
    this.accessTokenValiditySeconds = accessTokenValiditySeconds;
  }

  //CHECKSTYLE:OFF
  @Override
  public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    MongoClient client = (MongoClient) o;

    if (getClientId() != null ? !getClientId().equals(client.getClientId()) : client.getClientId() != null) return false;
    if (getClientSecret() != null ? !getClientSecret().equals(client.getClientSecret()) : client.getClientSecret() != null) return false;
    if (getAuthorizationGrandTypes() != null ? !getAuthorizationGrandTypes().equals(client.getAuthorizationGrandTypes()) : client.getAuthorizationGrandTypes() != null)
      return false;
    if (getScope() != null ? !getScope().equals(client.getScope()) : client.getScope() != null) return false;
    if (getRegisteredRedirectUri() != null ? !getRegisteredRedirectUri().equals(client.getRegisteredRedirectUri()) : client.getRegisteredRedirectUri() != null)
      return false;
    if (getRoles() != null ? !getRoles().equals(client.getRoles()) : client.getRoles() != null) return false;
    return getInformation() != null ? getInformation().equals(client.getInformation()) : client.getInformation() == null;
  }

  @Override
  public int hashCode() {
    int result = getClientId() != null ? getClientId().hashCode() : 0;
    result = 31 * result + (getClientSecret() != null ? getClientSecret().hashCode() : 0);
    result = 31 * result + (getAuthorizationGrandTypes() != null ? getAuthorizationGrandTypes().hashCode() : 0);
    result = 31 * result + (getScope() != null ? getScope().hashCode() : 0);
    result = 31 * result + (getRegisteredRedirectUri() != null ? getRegisteredRedirectUri().hashCode() : 0);
    result = 31 * result + (getRoles() != null ? getRoles().hashCode() : 0);
    result = 31 * result + (getInformation() != null ? getInformation().hashCode() : 0);
    return result;
  }
  //CHECKSTYLE:ON

}


text:
#ifndef OMG_DDS_PUB_DATA_WRITER_IMPL_HPP_
#define OMG_DDS_PUB_DATA_WRITER_IMPL_HPP_

/***************************************************************************
 *
 * dds/pub/DataWriter<> WRAPPER implementation.
 * Declaration can be found in dds/pub/DataWriter.hpp
 *
 ***************************************************************************/

#include <dds/topic/Topic.hpp>

namespace dds
{
namespace pub
{

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>::DataWriter(
    const dds::pub::Publisher& pub,
    const dds::topic::Topic<T>& topic) :
        dds::core::Reference< DELEGATE<T> >(
            new DELEGATE<T>(pub,
                            topic,
                            pub.is_nil() ? dds::pub::qos::DataWriterQos() : pub.default_datawriter_qos(),
                            NULL,
                            dds::core::status::StatusMask::none()))
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(pub);
    this->delegate()->init(this->impl_);
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>::DataWriter(const dds::pub::Publisher& pub,
     const ::dds::topic::Topic<T>& topic,
     const dds::pub::qos::DataWriterQos& qos,
     dds::pub::DataWriterListener<T>* listener,
     const dds::core::status::StatusMask& mask) :
         dds::core::Reference< DELEGATE<T> >(
            new DELEGATE<T>(pub, topic, qos, listener, mask))
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(pub);
    this->delegate()->init(this->impl_);
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>::~DataWriter()
{
}

template <typename T, template <typename Q> class DELEGATE>
void
DataWriter<T, DELEGATE>::write(const T& sample)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->write(sample);
}

template <typename T, template <typename Q> class DELEGATE>
void
DataWriter<T, DELEGATE>::write(const T& sample, const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->write(sample, timestamp);
}

template <typename T, template <typename Q> class DELEGATE>
void
DataWriter<T, DELEGATE>::write(const T& sample, const ::dds::core::InstanceHandle& instance)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->write(sample, instance);
}

template <typename T, template <typename Q> class DELEGATE>
void
DataWriter<T, DELEGATE>::write(const T& sample,
        const ::dds::core::InstanceHandle& instance,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->write(sample, instance, timestamp);
}

template <typename T, template <typename Q> class DELEGATE>
void
DataWriter<T, DELEGATE>::write(const dds::topic::TopicInstance<T>& i)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->write(i);
}

template <typename T, template <typename Q> class DELEGATE>
void
DataWriter<T, DELEGATE>::write(const dds::topic::TopicInstance<T>& i,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->write(i, timestamp);
}

template <typename T, template <typename Q> class DELEGATE>
template <typename FWIterator>
void
DataWriter<T, DELEGATE>::write(const FWIterator& begin, const FWIterator& end)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    FWIterator b = begin;
    while(b != end)
    {
        this->delegate()->write(*b);
        ++b;
    }
}

template <typename T, template <typename Q> class DELEGATE>
template <typename FWIterator>
void
DataWriter<T, DELEGATE>::write(const FWIterator& begin, const FWIterator& end,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    FWIterator b = begin;
    while(b != end)
    {
        this->delegate()->write(*b, timestamp);
        ++b;
    }
}

template <typename T, template <typename Q> class DELEGATE>
template <typename SamplesFWIterator, typename HandlesFWIterator>
void
DataWriter<T, DELEGATE>::write(const SamplesFWIterator& data_begin,
        const SamplesFWIterator& data_end,
        const HandlesFWIterator& handle_begin,
        const HandlesFWIterator& handle_end)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    SamplesFWIterator data = data_begin;
    HandlesFWIterator handle = handle_begin;

    while(data != data_end && handle != handle_end)
    {
        this->delegate()->write(*data, *handle);
        ++data;
        ++handle;
    }
}

template <typename T, template <typename Q> class DELEGATE>
template <typename SamplesFWIterator, typename HandlesFWIterator>
void
DataWriter<T, DELEGATE>::write(const SamplesFWIterator& data_begin,
        const SamplesFWIterator& data_end,
        const HandlesFWIterator& handle_begin,
        const HandlesFWIterator& handle_end,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    SamplesFWIterator data = data_begin;
    HandlesFWIterator handle = handle_begin;

    while(data != data_end && handle != handle_end)
    {
        this->delegate()->write(*data, *handle, timestamp);
        ++data;
        ++handle;
    }
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::operator <<(const ::dds::pub::qos::DataWriterQos& qos)
{
    this->delegate()->qos(qos);
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::operator << (const T& data)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    this->write(data);
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::operator << (const std::pair<T, dds::core::Time>& data)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    this->write(data.first, data.second);
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::operator << (const std::pair<T, ::dds::core::InstanceHandle>& data)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    this->write(data.first, data.second);
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::operator <<(DataWriter & (*manipulator)(DataWriter&))
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    return manipulator(*this);
}

template <typename T, template <typename Q> class DELEGATE>
const dds::core::InstanceHandle
DataWriter<T, DELEGATE>::register_instance(const T& key)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    /* Invalid time will be used as current time. */
    return this->delegate()->register_instance(key, dds::core::Time::invalid());
}

template <typename T, template <typename Q> class DELEGATE>
const dds::core::InstanceHandle
DataWriter<T, DELEGATE>::register_instance(const T& key,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    return this->delegate()->register_instance(key, timestamp);
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::unregister_instance(const ::dds::core::InstanceHandle& i)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    /* Invalid time will be used as current time. */
    this->delegate()->unregister_instance(i, dds::core::Time::invalid());
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::unregister_instance(const ::dds::core::InstanceHandle& i,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->unregister_instance(i, timestamp);
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::unregister_instance(const T& key)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    /* Invalid time will be used as current time. */
    this->delegate()->unregister_instance(key, dds::core::Time::invalid());
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::unregister_instance(const T& key,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->unregister_instance(key, timestamp);
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::dispose_instance(const ::dds::core::InstanceHandle& i)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    /* Invalid time will be used as current time. */
    this->delegate()->dispose_instance(i, dds::core::Time::invalid());
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::dispose_instance(const ::dds::core::InstanceHandle& i,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->dispose_instance(i, timestamp);
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::dispose_instance(const T& key)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    /* Invalid time will be used as current time. */
    this->delegate()->dispose_instance(key, dds::core::Time::invalid());
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
DataWriter<T, DELEGATE>&
DataWriter<T, DELEGATE>::dispose_instance(const T& key,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);
    this->delegate()->dispose_instance(key, timestamp);
    return *this;
}

template <typename T, template <typename Q> class DELEGATE>
dds::topic::TopicInstance<T>&
DataWriter<T, DELEGATE>::key_value(dds::topic::TopicInstance<T>& i,
        const ::dds::core::InstanceHandle& h)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    return this->delegate()->key_value(i, h);
}

template <typename T, template <typename Q> class DELEGATE>
T&
DataWriter<T, DELEGATE>::key_value(T& sample, const ::dds::core::InstanceHandle& h)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    return this->delegate()->key_value(sample, h);
}

template <typename T, template <typename Q> class DELEGATE>
dds::core::InstanceHandle
DataWriter<T, DELEGATE>::lookup_instance(const T& key)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    return this->delegate()->lookup_instance(key);
}

template <typename T, template <typename Q> class DELEGATE>
const dds::topic::Topic<T>&
DataWriter<T, DELEGATE>::topic() const
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    return this->delegate()->topic();
}

template <typename T, template <typename Q> class DELEGATE>
void
DataWriter<T, DELEGATE>::listener(DataWriterListener<T>* listener,
    const ::dds::core::status::StatusMask& mask)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    this->delegate()->listener(listener, mask);
}

template <typename T, template <typename Q> class DELEGATE>
DataWriterListener<T>*
DataWriter<T, DELEGATE>::listener() const
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(*this);

    return this->delegate()->listener();
}

}
}

/***************************************************************************
 *
 * dds/pub/detail/DataWriter<> DELEGATE implementation.
 * Declaration can be found in dds/pub/detail/DataWriter.hpp
 *
 * Implementation and declaration have been separated because some circular
 * dependencies, like with DataWriterListener and AnyDataWriter.
 *
 ***************************************************************************/

/**
 * @cond
 * Do not add the delegate to the API documentation.
 */

#include <dds/pub/AnyDataWriter.hpp>
#include <dds/pub/DataWriterListener.hpp>
#include <org/opensplice/pub/AnyDataWriterDelegate.hpp>

template <typename T>
dds::pub::detail::DataWriter<T>::DataWriter(
    const dds::pub::Publisher& pub,
    const ::dds::topic::Topic<T>& topic,
    const dds::pub::qos::DataWriterQos& qos,
    dds::pub::DataWriterListener<T>* listener,
    const dds::core::status::StatusMask& mask)
    : ::org::opensplice::pub::AnyDataWriterDelegate(qos, topic), pub_(pub), topic_(topic)
{
    ISOCPP_REPORT_STACK_DDS_BEGIN(pub);

    if (dds::topic::is_topic_type<T>::value == 0) {
        ISOCPP_THROW_EXCEPTION(ISOCPP_PRECONDITION_NOT_MET_ERROR, "DataWriter cannot be created, topic information not found");
    }

    /* Create a implicit publisher with the topic participant when needed. */
    if (pub_.is_nil()) {
        pub_ = dds::pub::Publisher(topic->domain_participant());
    }

    /* Merge the topic QoS implicitly when needed. */
    if (topic.qos()->force_merge()) {
        qos_ = topic.qos();
    }

    org::opensplice::pub::qos::DataWriterQosDelegate dwQos = qos_.delegate();

    // get and validate the kernel qos
    dwQos.check();
    u_writerQos uQos = dwQos.u_qos();

    u_publisher uPublisher = (u_publisher)(pub_.delegate()->get_user_handle());
    u_topic uTopic = (u_topic)(topic.delegate()->get_user_handle());

    std::string name = "writer <" + topic.name() + ">";

    u_writer uWriter = u_writerNew(uPublisher, name.c_str(), uTopic, uQos);
    u_writerQosFree(uQos);

    if (!uWriter) {
        ISOCPP_THROW_EXCEPTION(ISOCPP_ERROR, "Failed to create DataWriter");
    } else {
        topic_.delegate()->incrNrDependents();
    }

    this->setCopyIn(org::opensplice::topic::TopicTraits<T>::getCopyIn());
    this->setCopyOut(org::opensplice::topic::TopicTraits<T>::getCopyOut());

    this->userHandle = (u_object)uWriter;
    this->listener_set((void*)listener, mask);
    this->set_domain_id(this->pub_.delegate()->get_domain_id());
}

template <typename T>
dds::pub::detail::DataWriter<T>::~DataWriter()
{
    if (!this->closed) {
        try {
            this->close();
        } catch (...) {
            /* Empty: the exception throw should have already traced an error. */
        }
    }
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::init(ObjectDelegate::weak_ref_type weak_ref)
{
    /* Set weak_ref before passing ourselves to other isocpp objects. */
    this->set_weak_ref(weak_ref);
    /* Register writer at publisher. */
    this->pub_.delegate()->add_datawriter(*this);
    /* Use listener dispatcher from the publisher. */
    this->listener_dispatcher_set(this->pub_.delegate()->listener_dispatcher_get());
    /* This only starts listening when the status mask shows interest. */
    this->listener_enable();
    /* Enable when needed. */
    if (this->pub_.delegate()->is_enabled() && this->pub_.delegate()->is_auto_enable()) {
        this->enable();
    }
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::write(const T& sample)
{
    this->check();
    AnyDataWriterDelegate::write((u_writer)(this->userHandle),
                                  &sample,
                                  dds::core::InstanceHandle(dds::core::null),
                                  dds::core::Time::invalid());
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::write(const T& sample, const dds::core::Time& timestamp)
{
    this->check();
    AnyDataWriterDelegate::write((u_writer)(this->userHandle),
                                  &sample,
                                  dds::core::InstanceHandle(dds::core::null),
                                  timestamp);
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::write(const T& sample, const ::dds::core::InstanceHandle& instance)
{
    this->check();
    AnyDataWriterDelegate::write((u_writer)(this->userHandle),
                                  &sample,
                                  instance,
                                  dds::core::Time::invalid());
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::write(const T& sample,
           const ::dds::core::InstanceHandle& instance,
           const dds::core::Time& timestamp)
{
    this->check();
    AnyDataWriterDelegate::write((u_writer)(this->userHandle),
                                  &sample,
                                  instance,
                                  timestamp);
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::write(const dds::topic::TopicInstance<T>& i)
{
    this->check();
    AnyDataWriterDelegate::write((u_writer)(this->userHandle),
                                  &i.sample(),
                                  i.handle(),
                                  dds::core::Time::invalid());
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::write(const dds::topic::TopicInstance<T>& i,
           const dds::core::Time& timestamp)
{
    this->check();
    AnyDataWriterDelegate::write((u_writer)(this->userHandle),
                                  &i.sample(),
                                  i.handle(),
                                  timestamp);
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::writedispose(const T& sample)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);
    this->check();
    AnyDataWriterDelegate::writedispose(
                                  (u_writer)(this->userHandle),
                                  &sample,
                                  dds::core::InstanceHandle(dds::core::null),
                                  dds::core::Time::invalid());
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::writedispose(const T& sample, const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);
    this->check();
    AnyDataWriterDelegate::writedispose(
                                  (u_writer)(this->userHandle),
                                  &sample,
                                  dds::core::InstanceHandle(dds::core::null),
                                  timestamp);
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::writedispose(const T& sample, const ::dds::core::InstanceHandle& instance)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);
    this->check();
    AnyDataWriterDelegate::writedispose(
                                  (u_writer)(this->userHandle),
                                  &sample,
                                  instance,
                                  dds::core::Time::invalid());
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::writedispose(
           const T& sample,
           const ::dds::core::InstanceHandle& instance,
           const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);
    this->check();
    AnyDataWriterDelegate::writedispose(
                                  (u_writer)(this->userHandle),
                                  &sample,
                                  instance,
                                  timestamp);
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::writedispose(const dds::topic::TopicInstance<T>& i)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);
    this->check();
    AnyDataWriterDelegate::writedispose(
                                  (u_writer)(this->userHandle),
                                  &i.sample(),
                                  i.handle(),
                                  dds::core::Time::invalid());
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::writedispose(
           const dds::topic::TopicInstance<T>& i,
           const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);
    this->check();
    AnyDataWriterDelegate::writedispose(
                                  (u_writer)(this->userHandle),
                                  &i.sample(),
                                  i.handle(),
                                  timestamp);
}

template <typename T>
template <typename FWIterator>
void
dds::pub::detail::DataWriter<T>::writedispose(const FWIterator& begin, const FWIterator& end)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);

    FWIterator b = begin;
    while(b != end)
    {
        this->writedispose(*b);
        ++b;
    }
}

template <typename T>
template <typename FWIterator>
void
dds::pub::detail::DataWriter<T>::writedispose(const FWIterator& begin, const FWIterator& end,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);

    FWIterator b = begin;
    while(b != end)
    {
        this->writedispose(*b, timestamp);
        ++b;
    }
}

template <typename T>
template <typename SamplesFWIterator, typename HandlesFWIterator>
void
dds::pub::detail::DataWriter<T>::writedispose(
        const SamplesFWIterator& data_begin,
        const SamplesFWIterator& data_end,
        const HandlesFWIterator& handle_begin,
        const HandlesFWIterator& handle_end)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);

    SamplesFWIterator data = data_begin;
    HandlesFWIterator handle = handle_begin;

    while(data != data_end && handle != handle_end)
    {
        this->writedispose(*data, *handle);
        ++data;
        ++handle;
    }
}

template <typename T>
template <typename SamplesFWIterator, typename HandlesFWIterator>
void
dds::pub::detail::DataWriter<T>::writedispose(
        const SamplesFWIterator& data_begin,
        const SamplesFWIterator& data_end,
        const HandlesFWIterator& handle_begin,
        const HandlesFWIterator& handle_end,
        const dds::core::Time& timestamp)
{
    ISOCPP_REPORT_STACK_DELEGATE_BEGIN(this);

    SamplesFWIterator data = data_begin;
    HandlesFWIterator handle = handle_begin;

    while(data != data_end && handle != handle_end)
    {
        this->writedispose(*data, *handle, timestamp);
        ++data;
        ++handle;
    }
}

template <typename T>
const ::dds::core::InstanceHandle
dds::pub::detail::DataWriter<T>::register_instance(const T& key,
                                                   const dds::core::Time& timestamp)
{
    this->check();
    dds::core::InstanceHandle handle(AnyDataWriterDelegate::register_instance((u_writer)(this->userHandle), &key, timestamp));
    return handle;
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::unregister_instance(const ::dds::core::InstanceHandle& handle,
                                                     const dds::core::Time& timestamp)
{
    this->check();
    AnyDataWriterDelegate::unregister_instance((u_writer)(this->userHandle), handle, timestamp);
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::unregister_instance(const T& sample,
                                                     const dds::core::Time& timestamp)
{
    this->check();
    AnyDataWriterDelegate::unregister_instance((u_writer)(this->userHandle), &sample, timestamp);
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::dispose_instance(const ::dds::core::InstanceHandle& handle,
                                                  const dds::core::Time& timestamp)
{
    this->check();
    AnyDataWriterDelegate::dispose_instance((u_writer)(this->userHandle), handle, timestamp);
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::dispose_instance(const T& sample,
                                                  const dds::core::Time& timestamp)
{
    this->check();
    AnyDataWriterDelegate::dispose_instance((u_writer)(this->userHandle), &sample, timestamp);
}

template <typename T>
dds::topic::TopicInstance<T>&
dds::pub::detail::DataWriter<T>::key_value(dds::topic::TopicInstance<T>& i,
                                           const ::dds::core::InstanceHandle& h)
{
    this->check();

    T sample;
    AnyDataWriterDelegate::get_key_value((u_writer)(this->userHandle), &sample, h);
    i.handle(h);
    i.sample(sample);

    return i;
}

template <typename T>
T&
dds::pub::detail::DataWriter<T>::key_value(T& sample, const ::dds::core::InstanceHandle& h)
{
    this->check();

    AnyDataWriterDelegate::get_key_value((u_writer)(this->userHandle), &sample, h);

    return sample;
}

template <typename T>
dds::core::InstanceHandle
dds::pub::detail::DataWriter<T>::lookup_instance(const T& key)
{
    this->check();

    dds::core::InstanceHandle handle(AnyDataWriterDelegate::lookup_instance((u_writer)(this->userHandle), &key));

    return handle;
}

template <typename T>
const dds::topic::Topic<T>&
dds::pub::detail::DataWriter<T>::topic() const
{
    return this->topic_;
}

template <typename T>
const dds::pub::Publisher&
dds::pub::detail::DataWriter<T>::publisher() const
{
    return this->pub_;
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::listener(DataWriterListener<T>* listener,
                                          const ::dds::core::status::StatusMask& mask)
{
    /* EntityDelegate takes care of thread safety. */
    this->listener_set((void*)listener, mask);
    this->listener_enable();
}

template <typename T>
dds::pub::DataWriterListener<T>*
dds::pub::detail::DataWriter<T>::listener() const
{
    return reinterpret_cast<dds::pub::DataWriterListener<T>*>(this->listener_get());
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::close()
{
    this->listener(NULL, dds::core::status::StatusMask::none());
    this->listener_dispatcher_reset();

    org::opensplice::core::ScopedObjectLock scopedLock(*this);

    topic_.delegate()->decrNrDependents();

    this->pub_.delegate()->remove_datawriter(*this);

    org::opensplice::pub::AnyDataWriterDelegate::close();

    scopedLock.unlock();
}

template <typename T>
dds::pub::DataWriter<T, dds::pub::detail::DataWriter>
dds::pub::detail::DataWriter<T>::wrapper()
{
    typename DataWriter::ref_type ref =
            OSPL_CXX11_STD_MODULE::dynamic_pointer_cast<DataWriter<T> >(this->get_strong_ref());
    dds::pub::DataWriter<T, dds::pub::detail::DataWriter> writer(ref);

    return writer;
}

template <typename T>
void
dds::pub::detail::DataWriter<T>::listener_notify(
        ObjectDelegate::ref_type source,
        uint32_t                 triggerMask,
        void                    *eventData,
        void                    *l)
{
    /* The EntityDelegate takes care of the thread safety and always
     * provides a listener and source. */
    dds::pub::DataWriterListener<T>* listener =
            reinterpret_cast<dds::pub::DataWriterListener<T>*>(l);
    assert(listener);

    /* Get DataWriter wrapper from given source EntityDelegate. */
    typename DataWriter::ref_type ref =
            OSPL_CXX11_STD_MODULE::dynamic_pointer_cast<DataWriter<T> >(source);
    dds::pub::DataWriter<T, dds::pub::detail::DataWriter> writer(ref->wrapper());

    if (triggerMask & V_EVENT_LIVELINESS_LOST) {
        dds::core::status::LivelinessLostStatus status;
        status.delegate().v_status(v_writerStatus(eventData)->livelinessLost);
        listener->on_liveliness_lost(writer, status);
    }

    if (triggerMask & V_EVENT_OFFERED_DEADLINE_MISSED) {
        dds::core::status::OfferedDeadlineMissedStatus status;
        status.delegate().v_status(v_writerStatus(eventData)->deadlineMissed);
        listener->on_offered_deadline_missed(writer, status);
    }

    if (triggerMask & V_EVENT_OFFERED_INCOMPATIBLE_QOS) {
        dds::core::status::OfferedIncompatibleQosStatus status;
        status.delegate().v_status(v_writerStatus(eventData)->incompatibleQos);
        listener->on_offered_incompatible_qos(writer, status);
    }

    if (triggerMask & V_EVENT_PUBLICATION_MATCHED) {
        dds::core::status::PublicationMatchedStatus status;
        status.delegate().v_status(v_writerStatus(eventData)->publicationMatch);
        listener->on_publication_matched(writer, status);
    }
}

/** @endcond */

#endif /* OMG_DDS_PUB_DATA_WRITER_IMPL_HPP_ */