Archive for January, 2009

Cyberduck 3.1 is Out

Friday, January 9th, 2009

Cyberduck.jpg

I noticed this morning that Cyberduck 3.1 was released with several nice additions: Cloud Files, Amazon CloudFront S3 support, better defaults for MobileMe (WebDAV), new icons in the site list, and lots of other stuff.

I don't use it a ton, but it's a nice, clean app that's a breeze to use. Great tool to have when you need it.

House, M.D. is a Fantastic Television Show

Thursday, January 8th, 2009

TV.jpg

I don't get to watch a lot of TV. Prior to a few months ago, the only show I watched regularly was The Deadliest Catch on the Discovery Channel - and that was a limited run series every year. So for me to take time out to watch a show means a lot.

That having been said, House, M.D. is one of the most entertaining shows I've seen in years. My daughter started watching it and then there were a few House marathons over the Holidays, and that was enough to make it a family activity for us. The actors are really quite impressive... the characters they play are exceptionally smart, witty, clever, and it's not always a happy ending.

It's become a must watch for the entire family, and a guaranteed spot on the DVR. Really amazing television. I'm glad to see it's not extinct.

Interesting Developments in Gimp on OS X

Thursday, January 8th, 2009

Gimp.jpg

I was looking at the latest from Gimp for OS X this morning and I realized that it requires an updated X11 install for OS X. While I might not mind that, I just ordered a new box, and with Snow Leopard on the way it's just not something I'm going to hassle with and put my box in an odd state over.

So I went back to the GIMP.app site which has the native port of Gimp for OS X. This is interesting to me because I think that the native port beats the X11 one because it fits in better with the rest of the applications on the box. Not that I have anything against X11 - it's just that if I had a choice, I'd go native.

Well... with the move by the Gimp on OS X folks to use the non-standard X11, the native port is getting my attention. While it's on 2.6.0 and the other is 2.6.4 (the most recent stable cut), there's a lot that can be done in 2.6.0, and it actually runs on my box without the new X11 libraries.

I'm wondering if the GIMP.app guys have given up, but if that's the case, then the only long-term way to get Gimp on OS X is to use the non-standard X11. Maybe they'll go back to the 'standard' one with Snow Leopard, but if they diverged once, they'll do it again. We'll just have to wait and see.

For now, the GIMP.app runs just fine on 10.5.6. I can do all the things I need to do and while that's not much (I use Acorn much more these days) it's nice to know it's there if I need it. Also... it's less than half the size of the X11 port. Wow! that's a big difference.

I Ordered It!

Thursday, January 8th, 2009

MacBookPro17.jpg

Well... I took about three times longer to order it than necessary - I had to triple-check that I had all the options picked out right, but I finally ordered a new 17-inch MacBook Pro from Apple. The aluminum unibody on the 15-inch I got for my Mom and played with for a while was just superb. Solid - just like I like things. Sleek. Smooth. Beautiful. Literally, a work of art.

I had to get the matte finish on the screen - it's just too important to me when I'm working on the train to have it glare at my with the glossy screen. Worth the $50 for that. I also got the faster 320GB HDD (7200 rpm) as I know that's a big factor in the compiles and loads, and I do a lot of that. Of course, I had to get the 8GB of RAM - that was something I've waited for for a long time.

It's due to arrive Feb 26th. That's seven weeks away. I can wait. By then, I'll have iLife '09 and iWork '09 which will be a lot of fun to get this month, yet.

Acorn 1.5.1 is Finally Available

Thursday, January 8th, 2009

acorn.png

The guys at Flying Meat pulled a little fast one on me a week ago - they released Acorn 1.5 and then realized right away there were a few issues, and the release notes indicated 1.5.1 was also out. I wrote about 1.5.1 assuming it was out that day (after upgrading to 1.5) but 1.5.1 never showed up. In fact, the release notes got modified and the 1.5.1 section was pulled.

Finally, today, they released 1.5.1 with a few bug fixes to 1.5. The misspelling in the preferences panel is fixed, and the docs are updated to include some of the new features in the Brush Tool, etc. Nice to see.

Nice Git Repo Tool for Mac OS X – GitX

Wednesday, January 7th, 2009

GitX.jpg

I started using Git for a simple project (the Xerces-C stuff I was playing with) just to get in the habit of using it and making sure I didn't forget what I read - which, of course, I had. But the purpose of this little project is to exercise Xerces-C and Git - and for that it's working perfectly. But I was still using just the command-line tools, which isn't bad, but I knew there were a few GUI tools for Git on OS X that I had seen. So I decided to track them down this afternoon.

I stopped as soon as I found GitX v0.5 - what a find! This is exactly what I was looking for - something that will make the harder Git repo work a little easier. It all seems to be in ObjC and a decent interface to boot:

GitX - xercesFun

I like that it's easy to understand, and when branches and merges get in the mix it'll be nice to have something to make sure it's clear what came from what. Still, it's a little rough still - no ability to configure the toolbar, which I noticed right away. Not horrible, and I can't imagine it'll replace the command line version for me, but it's great to see something that can help out if I need a little something.

I also like that once you start the app, you can have it place a link into /usr/local/bin/ for gitx so that you can start it easily from the command-line. Nice touch, guys! Very nice.

Interesting Confirmation on the Dual-GPU MacBook Pros

Wednesday, January 7th, 2009

MacBookPro17.jpg

I was talking to a friend today about the new 17-inch MacBook Pro and it's dual-GPU configuration, and why I thought that was Apple's design for more cores as opposed to putting a quad-core CPU into the laptop. He didn't think the two could be powered at the same time, and pointed to the need for a reboot in the current hardware to switch from one to the other. I didn't remember where I'd read the news from NVidia, but I found it today.

The article points out that the NVidia representative confirmed:

Besides confirming that you'll see it in other notebooks soon, they definitively answered some lingering questions about the chip's capabilities: It can support up to 8GB of RAM. It can do on-the-fly GPU switching. And it can work together with the MacBook Pro's discrete 9600M GT. But it doesn't do any of those things. Yet.

This makes perfect sense then.

Apple invests in OpenCL and gets some of the ObjC code in the OS to use it and then all of a sudden it's got a tremendous advantage over those machines that don't have the similar capability. I was a little surprised to see the dual-GPU in the 15-inch MacBook Pro, but wrote it off to the fact that the integrated GPU was "free", and removing it was more expensive than just using it. But it wasn't good enough, so they added the "good" one.

Not so, I think now.

This is going to be a CPU/GPU machine where the integrated GPU is connected directly to the system RAM, and that makes perfect sense for fast processing. Sure, it's going to require a lot of work to get OpenCL integrated into the OS, or core Frameworks, but when it does what a boost!

Yup, I've got to order one of these boxes. Gotta.

Good, Solid, Code Needs Maintenance – Even Mine

Wednesday, January 7th, 2009

bug.gif

Last night I got a call from the second-shift operators here at work about a problem with my fast-tick risk engine. Basically, a process that gets the information on all the options in the system was handing and timing out and therefore was failing. This code hasn't been changed in years (so I thought) so I had no idea what to make of the problem. Time to dig into it.

I got online and looked at the stack trace of the error. I tried to match that up to the code in CVS, and couldn't. Great! Someone changed the code and didn't check it in! ran through my head more than once. So I had to get the manager of the unknown coder that had to have changed this online as well. He looked at the diffs in ViewCVS and came to the conclusion that the changes were all cosmetic. I had said that I could track this down, but I'd need to be able to rebuild the code to add in some debugging/logging statements that were very much absent in the existing code. But to do that, I had to know that I had the right version of the source or we'd be in even bigger trouble than we already were.

He gave me the go-ahead and I updated a few libraries of mine to make sure that it wasn't a flaky problem I'd fixed in the last year or two, and then rebuilt and deployed it. I got the same errors, but this time, the line numbers lined up with the stack trace. Finally! I could get to the bottom of this.

What I found was that even though the server appeared to be working properly, it most likely had a locking problem that was causing this issue and while I could not be positive on this, it certainly appeared that this was the cause. So I let everyone know and restarted the server. When it came up, everything worked as it should. Good.

This morning, I then dug into the effected code and noticed that since it was very old I hadn't updated it to the more consistent locking scheme I'd put in place for the rest of the app. I didn't have the read-lock on the master list of instruments - and it needed to be there so I'd be safe from any additions/deletions, and there was a read-lock on the instrument which wasn't necessary because the data I was looking at is set at load time and there's no way to change it during the run-time. I replaced it with a safer retain()/release() pair, and this will also protect me from having the instrument deleted out from under me.

With these changes, the dev server worked perfectly and I've been able to get several large queries through it without any problem. Nice.

The lesson here is that all good code needs to be maintained regularly to make sure that changes in one part of the code make it to all other effected areas. This hasn't happened in this codebase simply because there isn't time to do so. When something breaks (like last night), there's time to fix it, but not before. I've said it many times before, and it's still true - the best time to fix a hole in the roof is not during a monsoon. Too bad we just don't have the time.

Upgraded My iTunes Library

Wednesday, January 7th, 2009

iTunes.jpg

With the MacWorld Keynote announcement that more record labels are putting their songs in the iTunes Plus category, I decided this morning to update my library to iTunes Plus. It turns out that there were 120 songs including 3 albums that I had that needed to be upgraded. Only cost about $25 to get it all updated to the DRM-free, high-bit rate versions. What's not to like about that?

I have to say that updates in the iTunes Store, like this, are one of the reasons I like Apple as a company. Sure, they are making $25 off me for a simple upgrade, but I upgrade the software I have when the old versions probably worked just fine. It's technology and it's my career. I like it. I don't check that often for updates to my music, but it's nice to see that it's not that much even when I do it so infrequently.

Working with Xerces-C – Examples are Hard to Find

Tuesday, January 6th, 2009

cplusplus.jpg

I was trying to get a decent handle on working with Xerces-C today as I know I'm going to need to know how it works when the specs come from the vendor that I have to interface with. I'm going to be putting together a large XML file of a lot of data for nightly shipping to this vendor. They, in turn, will massage the data and make the results available for us to pull down and view/process. It's essentially an outsourced compute facility that's got a great reputation for the numbers they create.

But to the point, I needed to have some way of reliably making an XML file and I didn't want to go back down the path of using a Java-based DOM libraries as I've been there, and it's a mess. Far too heavy in memory and CPU usage. So I looked around and picked Xerces-C as a decent alternative.

Today I was simply trying to create a DOM tree and output it to a file. Simple - right? Wrong. The documentation for doing this should be clear and easy to follow, but it's not. It's just not there. There are plenty of examples for the parsing of an XML file with Xerces-C, but nothing for the creation of a tree. It's just not there.

So I got bits and pieces of the code from here and there, and finally put this together:

  // System Includes
  #include <iostream>
  #include <ostream>
 
  // Third-Party Includes
  #include <xercesc/dom/DOM.hpp>
  #include <xercesc/util/XMLString.hpp>
  #include <xercesc/util/PlatformUtils.hpp>
  #include <xercesc/framework/LocalFileFormatTarget.hpp>
 
  XERCES_CPP_NAMESPACE_USE
 
  /*
   * This method writes out the DOM tree starting at the provided node to the
   * file specified. This is going to be a pretty optimistic way of writing
   * out this guy, but it should look nice.
   */
  void printTreeUnderNode(DOMNode *top, char *filename) {
    DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(NULL);
    DOMWriter *writer = ((DOMImplementationLS*)impl)->createDOMWriter();
    // set it so that it looks nice on the output
    if (writer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true)) {
      writer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
    }
    LocalFileFormatTarget myFormTarget(filename);
    writer->writeNode(&myFormTarget, *top);
    myFormTarget.flush();
    writer->release();
  }
 
 
  /*
   * Main entry point
   */
  int main(int argc, char *argv[]) {
    /*
     * Xerces-C doesn't play around. You need to set up the environment
     * so that all the xerces calls can actually work.
     */
    try {
      // Initialize Xerces infrastructure
      XMLPlatformUtils::Initialize();
    } catch (XMLException &e) {
      char *message = XMLString::transcode(e.getMessage());
      std::cerr << "XML toolkit initialization error: " << message << std::endl;
      XMLString::release(&message);
      return 1;
    }
 
    std::cout << "Transcoding the features..." << std::endl;
    XMLCh tempStr[100];
    XMLString::transcode((const char*)"XML 1.0", tempStr, 99);
    std::cout << "Creating the implementation..." << std::endl;
    DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr);
 
    std::cout << "Creating the document and root..." << std::endl;
    DOMDocument *doc = impl->createDocument(NULL, XMLString::transcode("root"), NULL);
    DOMElement *root = doc->getDocumentElement();
 
    std::cout << "Adding an IBM..." << std::endl;
    DOMElement *ibm = doc->createElement(XMLString::transcode("Instrument"));
    ibm->setAttribute(XMLString::transcode("symbol"),
                      XMLString::transcode("IBM"));
    ibm->setAttribute(XMLString::transcode("CUSIP"),
                      XMLString::transcode("123456789"));
    // now add in the position
    DOMElement *ibm_pos = doc->createElement(XMLString::transcode("Position"));
    DOMText *ibm_pos_val = doc->createTextNode(XMLString::transcode("1000"));
    ibm_pos->appendChild(ibm_pos_val);
    ibm->appendChild(ibm_pos);
    // now add in the price
    DOMElement *ibm_prc = doc->createElement(XMLString::transcode("Price"));
    DOMText *ibm_prc_val = doc->createTextNode(XMLString::transcode("95.88"));
    ibm_prc->appendChild(ibm_prc_val);
    ibm->appendChild(ibm_prc);
    // finally, add this tree to the root
    root->appendChild(ibm);
 
    std::cout << "Adding an AAPL..." << std::endl;
    DOMElement *aapl = doc->createElement(XMLString::transcode("Instrument"));
    aapl->setAttribute(XMLString::transcode("symbol"),
                       XMLString::transcode("AAPL"));
    aapl->setAttribute(XMLString::transcode("CUSIP"),
                       XMLString::transcode("333444555"));
    // now add in the position
    DOMElement *aapl_pos = doc->createElement(XMLString::transcode("Position"));
    DOMText *aapl_pos_val = doc->createTextNode(XMLString::transcode("-955"));
    aapl_pos->appendChild(aapl_pos_val);
    aapl->appendChild(aapl_pos);
    // now add in the price
    DOMElement *aapl_prc = doc->createElement(XMLString::transcode("Price"));
    DOMText *aapl_prc_val = doc->createTextNode(XMLString::transcode("112.80"));
    aapl_prc->appendChild(aapl_prc_val);
    aapl->appendChild(aapl_prc);
    // finally, add this tree to the root
    root->appendChild(aapl);
 
    // write this all out
    std::cout << "Writing out tree to 'output.xml'..." << std::endl;
    printTreeUnderNode(doc, "output.xml");
 
    /*
     * Done with the document, must call release() to release the entire document
     * resources
     */
    std::cout << "Cleaning everything up..." << std::endl;
    doc->release();
 
    /*
     * Now we need to shut down Xerces as we started it up.
     */
    try {
      XMLPlatformUtils::Terminate();
    } catch(XMLException &e) {
      char *message = XMLString::transcode(e.getMessage());
      std::cerr << "XML toolkit teardown error: " << message << std::endl;
      XMLString::release(&message);
    }
 
    std::cout << "Done" << std::endl;
    return 0;
  }

There's a lot of wasted effort here, and the code is far too optimistic to be used in production, but the ideas are clear, and that's what I needed. You have to get pretty low-level with Xerces-C to make up the XML tree. The attributes are tacked onto a node, and then you can make sub-nodes that might have attributes or values themselves. It's pretty easy when you realize the level you're dealing with, it's just going to take a lot of calls to build up the complete tree.

When I build the code for the project, it's clearly going to have to be based on the objects at hand, and not the XML representation. That will be set up once in the generation/output cycle and then all the attributes of the classes will be properly added to the tree, one by one, and then the tree itself will be serialized to the file.

In general, I think I can wrap up all the Xerces-C stuff so that it's hidden from the rest of the implementation and so could, in theory, be changed out. It's pretty low-level, so except for the writing it out, reproducing it shouldn't be that hard.