libuv is a multi-platform library that provides your
programs with asynchronous capabilities through the use of an event loop. node.js has been the most mainstream usage of this library.
Today’s post will talk about this library and show some working examples.
When you’re programming in an event-driven environment, you need a medium that can transfer control over to your program when an event occurs. The event loop’s job is to do exactly this, running forever.
If you were to think about it in c-pseudo code, it might look something like this.
Watchers
The list of handles that can send us events, and signal our application are here:
These are the handles that we can register interest in; so the system will raise interesting events to us.
Get started
Before we get started, the libuv library needs to be installed along with the development files. In order to do this on my Debian machine, I’ll install the development and the runtime files.
Now, when we build an executable we need to link to the uv library using -luv. For the CMake test application that I’m writing with this article, I used:
Where uvtest is the name of my application.
First program
The “hello, world” of event loops. We’ll allocate the event loop, run the loop, and then cleanup.
Idle
While our program is doing “nothing”, waiting for the next event we can register a function to execute. You’ll notice in this code that we’re using a uv_idle_t rather than a uv_loop_t (as above). Using uv_idle_t provides us access to register an “idler” function.
The idle function, count_to_10 counts up until we exceed 10 and then calls uv_idle_stop which is our exit.
Finishing up
This has just been an introduction to the absolute basics of libuv.
When you’re writing demos in 320x200 mode, you can quickly estimate X and Y coordinates from a screen offset with one simple multiply. That value that you use is 0xcccd, and it’s called the Rrrola Constant.
To start this, we need to adjust our video address. Remember, this is an estimate (it’s good enough); but it does need a bit more “help” in the setup.
Right now, es:[di] is pointing to the start of video memory (adjusted).
Now we perform the multiply
At this point the (x, y) pair is now available to us in (dh, dl). This is really handy for use in your rendering functions.
In this example, we just make a pixel that’s x xor y.
This works because the offset into the video buffer is worked out as (y * 320) + x. Multiplying this formula out by Oxcccd we end up with (y * 0x1000040) + (x * 0xcccd)
The top byte is y * 0x1000000. The next byte along is now (x * 0xcccd / 0x10000) which approximates to (x * 256/320), which is useful to us. The lower two bytes from the product are garbage.
Full example
The following is a .com demo-style example which uses the above technique:
Sometimes it can be of value to be able to isolate and analyse specific network
traffic that is flowing through your network interface. tcpdump
offers you this capability in a command line application.
There are many tutorials already that take you through tcpdump comprehensively,
so this article will just be constrained to usages that have benefited me.
Reading the output
In order for this tool to be of any use, it pays to know how to read the output. In
this example I’m capturing all of the port 80 traffic flowing through my network
interface.
The stream of output that you see after this (once you have some port 80 traffic going)
is the output that you’ll use for analysis. Here’s an excerpt after hitting
the first page on the internet.
There’s lots here.
We’re given the time of the packet being observed 21:49:54.056071.
We’re given the network layer protocol IP, source address (my machine) 192.168.20.35 and port 60584; along
with the destination 188.184.21.108 (on port 80).
The next field Flags [P.] is an encoded representation of the TCP flags. The following table gives a
breakdown of these flag values.
Value
Flag
Description
S
SYN
Connection start
F
FIN
Connection finish
P
PUSH
Data push
R
RST
Connection reset
.
ACK
Acknowledgement
The combination of values tells you the flags that are up. In this case P. tells us this is a PUSH-ACK packet.
The sequence number seq 3043086668:3043087150 tells us the run of bytes contained within this sample. The ack
value ack 3119373143 is the next byte expected. The win value tells us the number of bytes available in the
buffer followed by the TCP options.
The packet length is given at the end of the line.
The data frame is now split into a hexadecimal representation in the middle (given by -X); and the ASCII representation to the
right.
With the basic output view out of the way, we get move onto some useful invocations.
Invocations
Filter by Port
As per the above example, we can filter traffic by any port that we give to port switch. Here
we can see any SMTP traffic.
Everything
Sometimes it can be useful to just receive everything flowing through a network interface.
Filter by Host
You can use the host keyword to see traffic going to or coming from an IP address. You can constrain this
even further using src (coming from) or dest (going to).
Filter by Network
Using broader strokes, you can use net to specify a full network to filter packets on. This will allow you
to filter a whole network or subnet.
Filter by Protocol
Just seeing ping (ICMP) traffic can be filtered like so:
Conclusion
tcpdump is a very useful network analysis tool do perform discoveries on what’s actually happening. There’s
a lot more power that can be unlocked by combining some of these basic filters together using logical
concatenators.
ANTLR is a code generation tool for making language
parsers. Using a grammer file, you can get ANTLR to generate code to read,
interpret, and execute your very own code.
In today’s article I’ll walk through the basic setup to create a Calculator
language that can execute simple equations in a golang
project of our own.
Before we start, there are some software pre-requisites. You will need to
install ANTLR. This is a simple JAR File
that we can invoke locally.
Code generation
Now that we’ve got ANTLR installed, it’s time to generate some code. We do this
using a grammer file. A very comprehensive calculator can be found in the examples
of the antlr grammers repository here.
For today’s example, we’ll just focus on addition, subtraction, multiplication, and division
with the following grammer file:
Even without fully understanding the grammer language, you can see that there is
some basic token definitions, rules, and expression definitions.
MUL, DIV, ADD, SUB, NUMBER, and WHITESPACE all being significant to
the language that we’re definting.
The expression definition not only defines operations for us, but will also be
key in defining operator precedence, with the MulDiv rule occuring before the AddSub
rule, finally dealing with Number.
We can turn this grammer file into some go code with the following invocation:
This creates a parser folder for us now with a few different pieces of go code.
Parsers, Lexers, and Listener
If you look in the parser folder at the code that was created, you shoul see something
similar to this:
The Lexer’s job is to perform Lexical Analysis on
arbitrary pieces of text, and tokenizes that text into a set of symbols. For example, the input
of 1 + 2 might get tokenized to NUMBER 1, ADD, NUMBER 2. These tokens are now
fed into the parser.
The Parser’s job is to take these
tokens, and make sure they conform to the rules of the language. You can imagine that
a LISP style language would expect ADD, NUMBER 1, NUMBER 2 rather than a c-style
language that would expect the operator in between the number tokens.
After the string has passed through the lexer and the parser, it now runs through
the listener where we can write some code to respond to these symbols in order.
Implementation
The internal implementation of this calculator is a stack-based calculator. This gets
represented as struct:
The internal state of the calculator are int values on that stack. As operations
execute, the program will take the top of the stack as well that second-to-the-top
and perform arithmetic, leaving the result on the top of the stack.
The BaseCalcListner type that was generated for us has all of the hooks we need
to latch onto the complete the implementation. The NUMBER, ADDSUB, and MULDIV rules
all get their own listener for us to respond to.
Execution
Now we go from text input to execution. In the following snippet, the
input stream feeds the text into the lexer. The lexer then gets setup
as a stream ready to tokenize our input.
Finally, all of those tokens get parsed to make sure they represent
valid expressions for our language.
We can now walk the parser tree with a listener attached. The listener
will fire off our hooks that we defined earlier; and our stack-based calculator
should leave us with the result at the TOS.
We should be left with something like this on screen:
Conclusion
As you can see, ANTLR is a very powerful tool for writing all of the pieces
of a compiler (or in this case, an interpreter) to get you kick started very
quickly.
You’d almost be insane to ever do this stuff yourself!
Sometimes you can be just as productive using your shell as you are in any
programming environment, you just need to know a couple of tricks. In this
article, I’ll walk through some basic tips that I’ve come across.
Reading input
You can make your scripts immediately interactive by using the read
instruction.
String length
You can get the length of any string that you’ve stored in a variable by
prefixing it with #.
Quick arithmetic
You can perform some basic arithmetic within your scripts as well. The value
emitted with the # character is an integral value that we can perform tests
against.
Substrings
String enumeration will also allow you to take a substring directly. The
format takes the form of ${VAR:offset:length}.
Passing positive integers for offset and length will make substring
operate from the leftmost side of the string. Negative numbers provide a
reverse index, from the right.
Replacement
It’s common place to be able to use regular expressions to make substitutions
where needed, and they’re available to you at the shell as well.
Finishing up
There’s lots more that you can do just from the shell, without needing to
reach for other tools. This is only a few tips and tricks.