Hypothetically speaking…

Hypothetically speaking…

… if you were working on a language which was in many ways similar to (and targets) C but added more expressive types, type inference, and polymorphism, how would you interpret the following line of code?

x = "foo";

The options are:

char x[] = "foo";

or

char * x = "foo";

Thoughts?

Posted in Uncategorized | 5 Comments

Do Yourself a Favor

Stick this in your .bashrc:

export HISTCONTROL=erasedups
export HISTSIZE=500
export HISTIGNORE=ls:'ls -l':fg

This changes what gets shoved into .bash_history.

  • Erase duplicate entires that have shown up previously.
  • Set the history size to 500
  • Ignore a few specified commands
Posted in Uncategorized | 1 Comment

Thought for Today

Just one thing:

MERGING IS HARD.

That is all.

Posted in Uncategorized | Leave a comment

More Arduino

I just ordered my own an Arduino Duemilanove! I’ve been borrowing Job’s Arduino up until now (thanks Job). I’ve got some plans for a few more interesting posts using Atom on the Arduino when this thing arrives.

SparkFun Electronics – Arduino USB Board

Posted in Uncategorized | 2 Comments

Moved!

Hi everyone.

I moved this blog from http://angryhosting.com/ to a VPS hosted with http://linode.com/. I know a bunch of links now target this site, so I’ve done my best to maintain all the old links and files, etc.

If any one notices problems with the old posts (broken links or otherwise), let me know.

Thanks.

Posted in Uncategorized | Tagged | Leave a comment

HsOpenSSL Update

The maintainer of HsOpenSSL accepted a patch Job Vranish and I put together that moves to a simple build type rather than the configure step. This has the nice side effect that, with the right libraries installed, we can get HsOpenSSL to install happily in windows without the need for Cygwin to build it.

Here’s how:

  1. First, we need to install the OpenSSL binaries and header files. The Windows build of OpenSSL depends on the Visual C++ 2008 Redistributables. Download and install them.
  2. Next we need the Win32 OpenSSL v0.9.8k package. Download and install this.
  3. Open cmd.exe to run a few commands.
  4. Now that OpenSSL is installed, lets perform a cabal update to make sure we have the most recent package.
  5. If you used the default installation options, you can call the following command to install HsOpenSSL:
    cabal install --reinstall HsOpenSSL --extra-include-dirs=C:OpenSSLinclude --extra-lib-dirs=C:OpenSSLlibMinGW

    Note that I included --reinstall just to make sure we don’t terminate prematurely because of an older version.

Everything should be installed now. Lets test it. Save this into a file somewhere:

module Main where

import OpenSSL.RSA

main :: IO ()
main = do
    key <- generateRSAKey' 2048 65537

    print key

And lets build it…

ghc --make test.hs

…and run it…

>test.exe
RSAKeyPair {rsaN = [ZOMG BIG NUMBER], rsaE = 65537, rsaD = [ZOMG ANOTHER ONE], rsaP = [THIS ONE WASN'T AS LARGE], rsaQ = [SAME HERE, BUT STILL PRETTY HUGE] }

If you got some output that wasn’t an error from test.exe, you’ve successfully installed HsOpenSSL in Windows.

Hope this helps someone!

Posted in Uncategorized | 1 Comment

Data.Binary and Byte Order

I seem to come across the (false) idea that Data.Binary isn’t able to handle encoding/decoding things of non-network byte order. So, for all those of you who are trying to get Data.Binary to use little endian instead of big endian, consider this a guide.

Lets build a small module that encodes and decodes a simple data.

Module and imports first!

module Main where

import Text.Printf

import Data.Binary
import Data.Binary.Get
import Data.Binary.Put
import Data.ByteString.Lazy hiding (concatMap, putStrLn)

Lets describe the type we’re going to encode/decode.

data Foo = Foo {
    w16 :: Word16,
    w32 :: Word32,
    w64 :: Word64
} deriving (Read,Show)

I’d like to be able to represent this as both big endian and little endian, so I’m making two newtype wrappers:

-- Foo, Little Endian
newtype FooLE = FooLE { unFooLE :: Foo }
  deriving (Read,Show)

-- Foo, Big Endian
newtype FooBE = FooBE { unFooBE :: Foo }
  deriving (Read,Show)

Now for the instances! Lets do little endian first (since it seems to be the most problematic):

instance Binary FooLE where
    get = do
        w16le <- getWord16le
        w32le <- getWord32le
        w64le <- getWord64le
        return $ FooLE $ Foo { w16 = w16le,
                               w32 = w32le,
                               w64 = w64le }
    put fle = do
        let f = unFooLE fle
        putWord16le $ w16 f
        putWord32le $ w32 f
        putWord64le $ w64 f

Note that putWordXXle and getWordXXle are found in Data.Binary.{Get,Put}–they aren’t exposed by Data.Binary (perhaps they should be?).

What’s going on here? In the get instance, we simple pull bytes off using the little endian functions, make a Foo, and wrap it in a FooLE!

The put instance unwraps Foo and uses the record selectors of Foo to hand stuff to the put* functions.

The big endian version is nearly identical:

instance Binary FooBE where
    get = do
        w16be <- getWord16be
        w32be <- getWord32be
        w64be <- getWord64be
        return $ FooBE $ Foo { w16 = w16be,
                               w32 = w32be,
                               w64 = w64be }
    put fbe = do
        let f = unFooBE fbe
        putWord16be $ w16 f
        putWord32be $ w32 f
        putWord64be $ w64 f

Again, we look for the put* and get* functions in Data.Binary.{Put,Get}.

Now we just need to create some test data, make a function to print the hex string (so that we know that we output the bytes in the right order), and encode/decode/print the test data to ensure things come back the right way.

td :: Foo
td = Foo { w16 = 0x0011,
           w32 = 0x00112233,
           w64 = 0x0011223344556677 }

tdBE :: FooBE
tdBE = FooBE td

tdLE :: FooLE
tdLE = FooLE td

printHex :: ByteString -> String
printHex b = concatMap (printf "%02x") $ unpack b

main :: IO ()
main = do
    let le  = encode $ tdLE
        be  = encode $ tdBE
        le' = decode $ le :: FooLE
        be' = decode $ be :: FooBE

    putStrLn $ "le:" ++ (printHex le)
    print le'

    putStrLn $ "be:" ++ (printHex be)
    print be'

What’s the output?

le:1100332211007766554433221100
FooLE {unFooLE = Foo {w16 = 17, w32 = 1122867, w64 = 4822678189205111}}
be:0011001122330011223344556677
FooBE {unFooBE = Foo {w16 = 17, w32 = 1122867, w64 = 4822678189205111}}

Now, lets try and get over the idea that you can’t easily use Data.Binary to play with byte order. It’s rather trivial. :)

Posted in haskell | Tagged , , | Leave a comment