Paul Shinn

  works in semicolons

  likes sweets

  has adventures with friends

Posts

February 08, 11:05 PM

Madeleines

Not too long after my vacation, I bought myself some Madeleine molds. I had decent success, but my first two attempts bombed and I was greatly dissatisfied with my results.

I haven’t taken pictures through the entire preparation process, as it is somewhat time sensitive. Most of the time is spent in setup- then in just a few minutes the batter takes sifted flour, and then straight to the oven. Not much time to take pictures, and not enough time to pickup a camera as the batter may break (before adding flour, anyhow).

These three Madeleines were from the first successful batch. Note that they are glossy, probably due to too much flour dusted into the molds to keep them from sticking. Also a little bit distant from the heating element in the oven.

After three batches, the first two of them unsuccessful, I finally baked a batch to some amount of satisfaction. Some people may argue that these are not browned enough on the bottom. The edges are quite well defined and firm out of the oven, though.

The fourth batch was excellent. I didn’t bother creating a glamour snapshot. Here’s a pretentious shot of one of the molds. One has to be careful to deposit the batter very carefully, as the slightest drop outside the reservoirs may cook into a crusty edge, or even burn.

One strange quirk about all of the batches, was that the Madeleines were even better the second day over the first. This is somewhat puzzling to me because a majority of online sources speak of them being best about 30 minutes out of the oven.

Here’s a link to the recipe I used. I added the zest of one orange, as well, and skipped the powdered sugar. I might try icing a batch with an orange sugar icing sometime.

http://www.101cookbooks.com/archives/madeleines-recipe.html

Permalink | Leave a comment  »

December 01, 12:09 AM

 

Day 5, part 2: St. Lucia

 

During my departure from the beach, we approached and then passed through the edge of a rain shower over the island. The combination of water mist, position of the sun, and location of the boat made for some amazing pictures of rainbows. But first, off in the distance, were the regionally famous Twin Pitons, two small mountains with striking outlines.

 

Here is the first, of the two.

 

 

Here are both of the Pitons, together. I’m not sure if this is the most common viewing angle, though. I think most people see these from the opposite side, by the town of Soufriere.

 

 

Not too far from the beach, hints of a rainbow became visible in the cloud cover.

 

 

There have been few times I can recall in my life, where I happened to see rainbows as vivid as these. To my surprise, it only got better as we traveled north back to the port.

 

 

The left portion of the rainbow is really surprising here. There is little visible cloud cover for the rain or mist to support it.

 

 

Here is an attempt at a close-up of one of the segments. Again, little did I know at that time, that it was still going to get better.

 

 

I glanced momentarily behind us. Plenty of beauty here, but perhaps tougher to appreciate relative to the ongoing rainbow.

 

 

The other tourists and I marveled at the developing rainbow, as the segments began to merge and connect together.

 

 

I found it amusing that two catamarans were eating our wake. We weren’t really traveling fast, though.

 

 

Here, the rainbow finally stretched across the sky in one sweeping arc.

 

 

As we traveled below the edge of the falling rain, the south end of the rainbow intensified. I think at this point, the focal point was much closer, as the foot of the rainbow colored the view of everything behind it.

 

 

Here is a foot (or a leg?) of the rainbow, over the Sandals resort on St. Lucia.

 

 

As we entered the heaviest portion of the rain, a second arc began to appear on the outside of the rainbow. Unfortunately, I think it was too faint for the camera to pick up. The main arc continued to shimmer brightly in the sky, though.

 

 

The skies were clear by the time we reentered the harbor. Here is a glamour shot of the Ruby Princess, the cruise ship I traveled upon.

 

 

There was a traffic jam at the only small-boat dock adjacent to the cruise ship. We had to wait for 7 other small craft to drop off their passengers. Some of the boats were impatient and unloaded their passengers onto the currently docked boat. How peculiar. Off in the distance there is still a faint hint of a different rainbow over the island. Perhaps this was the second arc I had seen earlier.

 

 

The oncoming nightfall brought some spectacular color to the clouds and reflections in the water. I think the ship in the distance is a Norwegian Cruise Line ship. The fore of the ship in the bottom left was a Royal Caribbean ship, exiting from the harbor.

 

 

Here is a slightly different view, to show off the clouds present.

 

 

The Ruby Princess deftly turned about, and wasted no time in accelerating to top speed. The motion of the boat made it tough to take stable pictures, as I only have a small pocket-sized camera, but I did manage one decent shot at the twilight before I stopped taking pictures for the day.

 

 

Although I didn’t get to travel inland on the island, I must say that I loved every bit of my time on St. Lucia. In my opinion, even after completing the trip, St. Lucia is the best Caribbean island ever. Also, the island, as one can plainly see, is densely populated with trees. I suspect, perhaps in the spirit of Jared Diamond’s writings, that this island is also one of the most prosperous relative to the number of inhabitants.

 

The other members of my group went on a Zip Line excursion through the rainforests of the southeast corner of the island. We had a long discussion about who got the best of the island, and it seems that I did get the best of it all. However, they brought back something for me. They were allowed to bring aboard the ship a sample of a local variety of banana that their tour guide plucked from the trees during the Zip Line return.

 

It was hauntingly delicious. I’ll be sure to look out for it again if I return to St. Lucia.

 

My next post will be about Antigua.

Permalink | Leave a comment  »

November 30, 11:30 PM

Day 5: St. Lucia

This day opened with absolutely gorgeous weather. I elected to spend this day away from the group, and I think I got the best of the island as a result.

Today’s excursion was another beach day away from the ship. Here is a snapshot of the open sea as my tour boat left the harbor.

Here is a parting glance of the cruise ship and port.

Here is a glance at the shoreline about a mile away from the port. After taking this picture, I dozed off in the sun.

About 15 minutes later, we arrived offshore from the beach. Our tour was composed of divers and snorkelers. I had initially signed up to snorkel, but it didn’t work out.

Here’s a glimpse up the shore as we jockeyed about to meet up with a smaller boat that would take us ashore.

The morning sun applying its magic upon the beach.

The divers depart for their dive site, about a quarter mile away.

Looking down into a glass-like sea.

I apologize for the pretentious snapshot. I couldn’t resist.

Looking down the shore, shortly after landing.

Some of the other tour attendees wasted no time getting acquainted with the locale.

I left my loot on this handy pedestal of stones, the footer for the palm tree providing shade over my chair.

Another pretentious picture. This felt like something one might find as a desktop background. Almost directly overhead of my beach chair.

Here is the shadow of the same palm branch.

I explored the north end of the beach, which was not groomed.

I caught a glimpse of this sand crab looking back at me. One of the other tourists warned me that there was a snake among the rocks, but I didn’t see it around.

This side of the beach had a lively surf.

Looking back over the main portion of the beach.

This intrepid seedling was well anchored into the sand. The beach sand was very fine; while standing at the edge of the waves, each wave ate away a lot of sand beneath my feet. I marveled at how well this seedling was able to hold its place.

An obligatory sit-and-watch-the-waves picture. A number of visitors came and went via the small water taxi boats during the course of the day.

The sign says it all.

Perhaps, if I ever return, I will bring some objects with me to make sandcastles. Footprints will have to do, this time around.

At mid-afternoon, it was time to depart. The afternoon sun provided a rather vivid view of the beach.

Goodbye, Anse Mamin beach!

Well, with the number of pictures I took of St. Lucia, even after selecting the best set, there are way too many to fit comfortably into one post. The next post contains the return trip and evening, with some surprising developments.

Permalink | Leave a comment  »

November 29, 09:57 PM

Day 4: St. Kitts & Nevis

Our ship arrived somewhat early in the morning. The forecast for today predicted rain, but it only rained part of the day. I spent this day on a train tour of the island.

This is a glance towards the aft of the ship.

The island is populated by many Egrets. This was the best picture I was able to take of any of them. Our guide on the train tour mentioned that there are only four nesting sites on the island.

Here is a snapshot of our train before departure. I forget the name of the island in the distance. I looked up the name later, and it appears to be called ‘Oranjestad’, part of the Netherlands Antilles.

One thing that struck me about the island was the absence of any expansive wooded areas. Most of the island was farmland and brush.

The rain and the shaking of the train (I was on the top floor of the two-floored cars) made it tough to take stable pictures. This gem was shot with a portion of my body hanging out the window, just after we emerged from beneath a raincloud.

On the east side of the island, there are many untouched beaches. I found this one particularly pretty.

Towards the south end of the island, there was a rock quarry. Our tour guide had some veiled remarks about the state of politics and public affairs on the island. Nonetheless, the quarry machines cut very cleanly into this mountain, revealing an interesting rock face.

There wasn’t much time after the train tour to do anything else on the island. I browsed some of the tourist shops at port but didn’t find anything of note.

Day 5: Barbados

We had an early departure from St. Kitts, presumably so that we would make it over to Barbados on time. Unfortunately, I forgot to charge my camera battery overnight, so I only have a few pictures. I split off from the group this day, on my own adventures.

I started the day at Malibu beach, which is somehow associated with the Malibu Rum Company. I had assumed that the beach was owned or operated by the company, but there were conflicting signs. In any case, it was a beautiful beach. I don’t know if the sand on this beach is natural, though. It was very well groomed.

An obligatory picture of the beach chairs and space I had to myself.

This beach faced the Caribbean Sea. The day started out clear and beautiful.

About two hours later, some dense clouds came in overhead, but no rain fell.

After the beach in the morning, I walked around downtown Basseterre. My camera was very low on battery so I didn’t take any pictures. To be honest I didn’t like the city that much, as it was a little bit dirty compared to St. Thomas. Also, the cab drivers around town were very pushy and hustled everyone within earshot.

I did snap a few pictures of the port, though, after I returned from downtown. From the ship, we could see updrafts of air into the cloud cover. A few minutes later, it began to rain, although the front stayed a few miles away.

The next port of call was St. Lucia, which I absolutely adored. Fortunately, I remembered to charge my camera batter, and I took plenty of pictures. A post will follow this one for St. Lucia.

Permalink | Leave a comment  »

November 17, 09:45 PM

Some of you already know that I’ve been away on vacation nearly two weeks. I’ve been posting some pictures here and there, but here is a collection from the first part of the trip.

Day 1: Princess Cays, Eleuthera, Bahamas

This was the 1st full day of the trip. I didn’t do much on this day, except hang out at the private beach owned by the princess cruise line. A striking feature of this beach is that the sand is completely white. My guess is that it is composed of crushed coral, although seashells are also another possibility. Individual grains of the stuff were quite prickly, in any case.

Day 2: At Sea (somewhere north of the Turks/Caicos)

My friend had her wedding this day at sea. Rather than disrupt her privacy, I’ll skip pictures of the wedding. I took some silly pictures this day, but most notable was a self-portrait outside my stateroom, and a picture of the sunset in the west.

This was a rather brilliant sunset, too. Vivid. Technically this was about 15 minutes before the actual sunset.

Day 3: St. Thomas (U.S. Virgin Islands)

I took lots of silly pictures this day. Our tour took us to the Caribbean Amber Museum. After the museum, we walked around Haagensen House, a British Colonial building whose name I forget, and eventually made our way up to Blackbeard’s Lookout (or was it Castle?). Nice views of the harbor, but I wasn’t a big fan of the town. I tried a sample of some Conch when we had lunch. Tasted like really intense scallops. I can’t say that it was bad, or that I liked it. We’ll see.

Arrival in St. Thomas.

Traveler’s Palm. Festive!

Hibiscus, many of these were growing around the tour area.

I know now that this sinister looking kitchen gadget is called a Trivet, to protect tables from hot cookware.

The Three Queens. There’s an interesting legend/account of their deeds. Local heroes.

Blackbeard’s lookout tower. I suppose that this is not as impressive as it once was, now, with a swimming pool in front and hotel accommodations surrounding it. No lack of vertigo here, as I climbed up the center wrought iron stairwell inside. I’m not a fan of heights and shaky staircases.

Anne Bonney, Pirate. Of all the pirate statues here, this one had the most character. Also, supposedly she was Irish. Upon reflection, I really should have cropped this picture or maybe took a less accidentally suggestive picture.

After our lunch, we went for a little walk around and about. In one of the public parks, there were roosters and hens roaming about. Here’s a rather lucky snapshot (on my part) of one native.

That’s it for now. Next post, St. Kitts-Nevis and Barbados.

Permalink | Leave a comment  »

November 02, 12:15 AM

Intro

It has been some time since my last post- I was out shopping this weekend and I came across a mixer on sale at the Williams-Sonoma store. Well, as it was 33% off an already discounted price, I decided to buy it. A few people have been pressuring me to get a mixer, under the assumption that I would make more treats. Ha, we’ll see!

I already had a promise made with a friend that if I ever bought a mixer, the first recipe I would make (and share!) would be marshmallows. Hence, here we are.

The recipe I used is based upon Alton Brown’s recipe from Good Eats. I used a little bit more water and more vanilla. Here’s a link if you’re interested in the original recipe.

http://www.foodnetwork.com/recipes/alton-brown/homemade-marshmallows-recipe/index.html

Marshmallows

Ingredients

3 packages unflavored gelatin

3/4 cups water

1/2 cup water

1 cup light corn syrup

1 1/2 cups sugar (1 lb.)

1/4 teaspoon kosher salt

2 teaspoons vanilla extract

Other

1/3 cup powdered sugar

Nonstick spray

Pour the gelatin into the mixing bowl, and then pour the 3/4 cups of water into the bowl. Swirl the water around a little if necessary, to ensure that there aren’t any dry spots in the gelatin.

In a saucepan, pour the remaining half cup of water, corn syrup, sugar, and salt. Heat the mix covered for a few minutes until it starts to simmer, then remove the lid. Affix a candy thermometer and allow the syrup to come to a boil.

It is worth nothing, here, that the temperature will eventually rise quickly to 212F as the water begins to boil. Then, it will taper off as the water is expelled from the syrup. Thus- don’t be alarmed if the temperature rises quickly- you have a few minutes before it starts to ascend past the boiling point.

While the syrup is heading toward a boil, grease a pan with nonstick spray and powdered sugar.

Once the syrup has reached soft-ball stage (240F, around 6 minutes), remove the saucepan from the heat. Immediately turn on the mixer on its lowest setting, and carefully pour in the syrup.

Bring the mixer up to its highest mixing speed, and immediately pour in the vanilla. Leave the mixer on for about 14 minutes. During this time the mixture will begin to whip up and become fluffy.

Here’s another thing to note. Bring the mixture up to speed as fast as you can. This is to avoid the whisk holding the marshmallow, as opposed to the marshmallow being whipped by the whisk. Expect lots of steam to be expelled, too, as the gelatin is incorporated into the syrup.

After a few minutes, you can observe that the mixture will lighten, take on air, and puff up. Also- expect your mixer to be working very hard during this process. The table where the mixer was standing shook continuously during this ordeal.

After the mixture has fluffed up, pour it out into your pan. Immediately spread it evenly in the pan as briskly as you can, as it will become very sticky.

Allow the new marshmallow to set for at least 4 hours.

Conclusion

At this time, I did four batches and I am still waiting for everything to set. I dusted the tops with powdered sugar and covered them with foil. I will follow up later once I have eaten them. I mean- once I have shared them with friends.

Permalink | Leave a comment  »

September 18, 08:47 PM

Intro

When I buy kohlrabi, I used to feel like I was giving up on part of my purchase, as I had never tried to do anything with the leaves and would just throw them away.

Well, looking closely at the leaves, they look pretty tough and the stems are quite firm as well. Digging around on the web, I did find instances of other people cooking them and a few claims that they were delicious. I decided to give them a shot, by sautéing them.

Well, what’s the worst that could happen?

Recipe

Kohlrabi Green Sauté

1/3 lb of kohlrabi greens

2+ tsp of garlic, as desired

1+ tbsp of olive oil, as desired

Salt
Pepper

Prep the kohlrabi greens by removing the lower leafless portions of the stems. You may also cut a thin V into the leaves if you wish and remove the upper portion of the stems. Cut roughly into 1½ inch squares or strips.

Heat a frypan or sauté pan to medium-high heat. Once the pan has reached a relatively hot temperature, where a few droplets of water may sizzle a little when placed into a pan, pour in the olive oil and the garlic.

Yes, I used pre-diced garlic. Fresh is always better, though.

Saute the garlic just to the point where it is about to brown at the corners, and place the kohlrabi greens in.

Fold the greens over itself, lifting the bottom wilted leaves over the top of the uncooked leaves. Repeat until the leaves have diminished in size and become a bit limp.

Note that at this stage, there is still about half cooked and half uncooked. Keep folding!

We are just about there! A significant amount of moisture will have cooked out and the apparent volume will be reduced.

Season the greens with salt and pepper, to taste, and immediately plate.

Finished!

Conclusion

Well, ultimately, I think this is not for everyone. The cooked stems were a bit bitter, and the leaves were a little bit flavorless. I think it might be better to make a soup out of the greens instead, perhaps as a substitute for Kale. The leaves were also a bit rubbery after being subjected to moderately high heat. Slow and steady is probably the way to go. Oh well. :)

Permalink | Leave a comment  »

September 17, 09:35 PM

Ok so this is from about a year ago- I made some mistakes with this recipe but it came out ok. If I make this again, I'll repost with fixes and with final presentation.

Clafoutis

1 Pound of Fruit (Cherries)

1/2 Cup Sugar + 1 tbsp Sugar (Reserve)

1 tsp Cornstarch

1/3 Cup Flour

1 Cup Milk

4 Large Eggs

1 tsp Salt

1/4 Cup Butter + Butter to coat baking pans

1 tsp Vanilla

1 tsp Almond Extract

Makes enough to fit into 2x 9” Cake Pans

Instructions

Preheat the oven to 350 degrees.

Wash the cherries or prep the fruit, and set aside. If you are using Cherries, remove the stems, but you don’t have to remove the pits. Traditionally, the pits stay in the cherries for this recipe.

To start, butter the pans, and melt a 1/4 Cup Butter over low heat.

Don’t forget to butter the sides of the pans!

Note: Low heat! This means your saucepan should not be so hot that you can’t touch the bottom.

Prep the dry ingredients, sifting together the flour, cornstarch, and salt. Set aside.

In the main bowl, beat the eggs until they are foamy.

Next, add the sugar, then whisk or stir until mostly dissolved. A few sugar crystals floating around is ok.

Once the sugar has been well incorporated into the eggs, add the milk, vanilla, and almond extract to the eggs.

Toss the cherries with the 1 tbsp of sugar that was set aside (Note: I forgot this part!). Divide the cherries between the two pans.

Add the dry mix into the wet mix, whisk together until incorporated, and then pour over each pan of cherries.

Bake at 350 for about 30-35 minutes, or until the clafoutis is very puffy and browned, and has started to climb up the sides of the pan. Don’t open the oven door while it is baking, or it will collapse prematurely and the texture will be bad.

Serve warm. Sprinkle powdered sugar over the top if you’d like.

Serves 16 people one tiny slice each, 8 people a large slice each, or … you get the idea. :)

Permalink | Leave a comment  »

September 15, 09:30 AM

:) looks like everything imported from blogger just fine! Only the food posts and gaming posts are here. Everything else is at http://evilwombat.posterous.com/ . Keeping up two alter egos is a lot of work!

Permalink | Leave a comment  »

June 01, 05:00 PM

Awww yeah. This recipe has truly served me well. If I may say, it makes a very dense and chewy brownie.

I overhear a lot of people talking about cake brownies. Why would you want to mess around? After practicing this recipe a few times I am quite convinced that cake brownies are not the way to go. Note that this recipe doesn't use any leavening of any sort. Just stir until your arm is sore and you're good to go.

chocolate brownies

ganache
8oz Chocolate
1 Cup of butter (2 sticks)

wet ingredients
5 eggs
2 1/2 cups of brown sugar
1 tbsp of vanilla

dry ingredients
1 cup cocoa powder
1 1/2 cups flour
1 tsp salt

Preheat your oven to 375 degrees.

Start by mixing your dry ingredients together in one bowl.

In another bowl mix your wet ingredients together. Mix well and make sure there are no lumps.

Now, to make the ganache. Is this really a ganache? I don't know. I suppose it is really cream and chocolate.

Melt your chocolate and butter together. Use a double boiler, or a sauce pan at very very low heat.

Right as the butter has become liquid, is when I like to add the chocolate.

Add the chocolate.

Stir carefully, and keep an eye on the ganache to ensure it doesn't burn.

Remove it from the heat once it has completely melted together. You should be able to touch the bottom of the pan with the flat of your palm if the heat is just low enough. If it is too hot to touch or to do this, set the mixture aside to cool for a while.

Once cool enough (if necessary), pour it into the wet mixture.

Stir it together.

Add the dry mixture.

Stir well, until there are no more dry spots.

In a parchment lined or well buttered 9"x13" pan, pour the brownie batter.

It will be really thick, so you may want to use something to spread it about so that you get all the corners.

Place it into the oven and bake for about 30-40 minutes. Usually this takes about 35 minutes for me. You may use the typical toothpick test in the center to test for doneness.

Unfortunately I don't have any further action shots, as this batch was earmarked for overnight delivery to a friend. Maybe another day I will fill in a final picture.

Anyways, make sure you cut the brownies after they have cooled to room temperature. If you cut them any earlier, you'll find it tough to cut because it will stick to your knife blade and make a messy cut. If you are going to cart your brownies around, I like to wrap mine in plastic wrap. Brownies tend to bruise each other if you cut them and carry them around in contact w/each other.

Permalink | Leave a comment  »

June 01, 04:35 PM

I'll be the first to admit; I was never a big fan of rhubarb growing up. To the unfortunate credit of anyone who has ever served me rhubarb; you all have it wrong!

Ok so that is a little bit mean spirited, but rhubarb is no joke. I tried making this pie at the advice of a coworker who insisted, "best pie ever!!". After pacing up and down the grocery aisle, sigh, it was still quite early in the season to be looking for peaches and plums. Strawberries were just in season, and there were those stalks of rhubarb looking lonely in the baskets in the produce aisle.

Alright... I guess we'll see how this turns out; I said to myself. The grocery clerk attempted to ring it up as celery. Oops. The bagger corrected him and I groaned inwardly. I hope this turns out alright.

strawberry rhubarb pie, filling

3 cups of rhubarb
4 cups of strawberries

1 lemon

1/2 cup of granulated sugar
1/4 cup of instant tapioca powder

1 whole pie crust (double the previous recipe so that you can have a top and bottom).

Wash your berries and rhubarb, and prepare to cut up your rhubarb.

Note that you do not want any leaves remaining on your rhubarb. If there are any little bits, cut them off.

Take your rhubarb and cut them roughly into 1/2 inch chunks. If they're extra wide you may wish to halve them lengthwise.

Set the rhubarb aside, and now to prep the strawberries.

I removed the leaves by twisting them off, and then cut off the tops. Then I cut the strawberries into about half inch chunks, and some into quarter inch chunks.

I set the strawberries aside in a separate bowl.

Take your lemon and zest it into the rhubarb. I have two lemons here because I'm making two pies.

For some reason, I get a kick out of denuded lemons. I'm weird like that.

Measure out your sugar, and pour it into your rhubarb and lemon zest mixture.

Squeeze the lemon juice out of the lemon (or lemons), and mix it up!

Measure out the tapioca powder.

I'd never seen tapioca powder or instant tapioca before; so I was curious about the texture... was this really going to be ok?

Almost time to fill the pies. Note again, each pie crust recipe only makes one layer. You need two portions to make a pie, four to make two pies.

Pour the tapioca into the rhubarb mixture and stir well.

Mix the rhubarb into the strawberry mixture. Be gentle with the strawberries.

Fill your pie shells. It's ok to leave it heaping a little bit in the center.

Seal your pies well (lesson learned, here) and make some incisions so that steam may escape.

Bake in a 400 degree oven for 30 minutes. Then, rotate your pies around, and bake at 350 for another 25-30 minutes.

All done!


I tried these pies... and they were simply amazing. Perhaps there is some truth to the idea that these are the best pies ever.

Permalink | Leave a comment  »

June 01, 04:17 PM

All pies start with pie dough, so let's make some basic pie dough so we can go on and make pies.

sweet pie dough

1 1/4 cups of flour
2 teaspoons of sugar
1/2 teaspoon of salt

1/2 cup of chilled or frozen butter (1 stick)

2-4 tablespoons of ice water

Combine the flour, sugar, salt together in a bowl. Sift them together, if you like. if not, then make sure you mix really well.

Cut the butter up into 1/3 inch chunks if it is in stick form and drop them into the flour.

From here, you'll want to use a pastry cutter or a really sturdy fork (yes, really!) and cut the butter into the flour.

This looks like it won't do anything, but the goal is to get little pea sized chunks of butter with a lot of finer chunks of butter coated in flour.

Once you have cut the butter into the flour and can't really cut the butter into smaller chunks, you'll want to start forming the dough. I like to squeeze it through my fingers.

Once the dough starts to form a little, add ice water a little bit at a time. Depending on how humid it is or how dry your flour and butter are, you may not need much water. You just want to add enough to make the dough come together.

Here is 1 tablespoon.

Work the dough a little bit in between each bit of water.

After another tablespoon and a half, the dough has started to just barely come together.

From here you may keep squeezing it about in the bowl, or transfer it to a lightly floured work surface.

Work it just a little so that it mostly stays together, and then ball it up and flatten it into a disc about 3/4ths of an inch in height.

Wrap the disc with some plastic wrap, and place it in the fridge for at least 45 minutes, or freeze for later.

Now wasn't that easy? Make sure you work briskly through this process. The colder the butter and dough stays, the more flaky and crisp your dough will be. Try to work it just the slightest amount possible and add only enough water to make it form. These things go a long way towards making an awesome crust.

Permalink | Leave a comment  »

May 11, 03:46 PM

These are some of my favorite cookies. Granted, most cookies are among my favorite things to eat, but these are especially good just a short while after being baked, and they really make a house smell awesome.

snickerdoodles

Preheat your oven to 400 degrees.

dry ingredients

2 & 3/4 Cups Flour
1 Tsp Baking Soda
2 Tsp Cream of Tartar
1/2 Tsp Salt

wet ingredients

1 Cup Shortening
1 & 1/2 Cups of Brown Sugar
2 Large Eggs
2 Tsp Vanilla

coating

1/4 Cup Sugar
3 Tsp Cinnamon Powder

Before we begin, I'd like to point out that before I started making these, I had long been wary of Crisco. When I checked to see what brand of Shortening I should buy at the supermarket, I was surprised to find out that Crisco was 100% vegetable based shortening. Needless to say, it still looks a bit strange, a very pure and transcendent white. However, it makes a very soft cookie, in spite of the relatively high ratio of flour to fat in this ratio.

Sift or thoroughly mix your dry ingredients in a bowl, and set aside.

Combine the sugar and shortening in another bowl, and cream until thoroughly mixed. Add the two eggs and continue mixing. You'll find that at this stage, the wet ingredients start to take on a thin batter-like consistency. Add the vanilla and keep mixing until incorporated.

Although this cookie is very soft once baked, the cookie dough is relatively dry. It helps to add the dry mixture in halves to the wet mixture.

After the dry mixture has been added, the dough will appear to be slightly crumbly. Don't overwork the dough once the dry mix has been incorporated and no dry spots remain.


Mix up the coating in yet another bowl (or reuse the dry mix bowl). Scoop the dough into small balls, and roll them or form them carefully and roll them around in the coating.

Myself, I like to do this 6 at a time for that size of bowl.

Make sure you space the cookie dough at least an inch and a half apart on the sheet.

Bake in the oven for 8 minutes.

When they come out of the oven, they will be very soft. Gently transfer to a wire rack or plate to cool.

This recipe makes about 3 1/2 dozen cookies. If you form them into smaller balls you can probably exceed 4 dozen cookies, but you may wish to cut the baking time to 7 minutes.

Permalink | Leave a comment  »

May 11, 01:37 PM

Today we have a shortbread recipe, which has served me well over the past few months. For this version, we'll be adding pecans.

pecan shortbread

Preheat your oven to 325 degrees, with the rack set in the center of the oven.

dry ingredients
2 Cups Flour
1/4 Tsp Baking Powder
1/4 Salt

wet ingredients
1 Cup of Butter (2 sticks), Cold
1/2 Cup of Powdered Sugar
1 Tsp of Vanilla

other ingredients
8oz of Pecans (about 1.5 cups)

First, take the dry ingredients and either sift or mix them together. If you don't sift, make sure you really mix them together and take a few extra minutes and be thorough about it. Set the dry mix aside.

Second, in a separate bowl, take the butter and the sugar and cream them together. If you are new to making shortbread, you may notice that there isn't nearly as much sugar as in most other cookie recipes. Hence you will see that there are some lumps in your butter mix.

This is normal. Keep creaming through until no streaks of butter remain. Add the vanilla and keep creaming the butter until thoroughly incorporated. Add your dry mixture.

Mix together, and then get in there with your hands and mash/squeeze through the mixture until it starts to get really creamy. You'll end up with a pale dough and very buttery hands.

At this point, you should let the dough rest a little bit in the fridge. Working the dough with your hands will raise the temperature of the dough, so giving it about 5 minutes of rest will go a long way towards preserving the soft yet crisp texture at the end. You want to try and keep the dough as cool as possible while still being workable.

After the rest, or if you are speedy and going to hand-shape the cookies, mix in the pecans. This is also going to raise the temperature, so work quickly from here. Myself, I divided the dough in half and rolled it out to be cut.

Since you aren't supposed to use sharp objects on a ROUL'PAT or SIL'PAT, I used a flat pastry/vegetable scoop to cut it.

Immediately after I cut the first set, I put it in the oven. I quickly cut out the 2nd half of the dough and stashed it in the fridge. The first batch baked in the oven for about 13 minutes. If you see the edges starting to brown, take them out of the oven! They're done.

Be careful when transferring the cookies to a wire rack or another plate to cool. If you drop them they may shatter. Once they have cooled they will firm up a little bit.

Makes about 32 cookies, if shaped to 1.5 inches square.

Permalink | Leave a comment  »

May 06, 03:04 AM

So... let's try a post without the <p> marks, cause they're pretty tedious to type.

coconut macaroons

This is the picture that started it all. I sent this to a friend, along with a snide remark about how I could become a pretentious food blogger. I'd say this is a pretty hot picture (yes, I said hot) of a coconut macaroon, made by yours truly. Her reply? "Well, why don't you start one?". I was aptly unprepared for a retort... and also very unprepared to actually start writing again. I've been quite lazy and been letting stuff just... accumulate in my head, for eventual garbage collection.

So a while back, I discussed the problems inherent in looking up recipes on the net. People will post some crazy shit and pass it off (proudly, in many cases) as their own bona-fide recipe. This doesn't really settle well with me.

For one, I believe one should be honest. Granted, people have enough good judgement to be wary of trying homemade pate or sushi, and people don't post risky recipes in that sort of affair; but what do you do when it comes to that ... gray area. I'm talking hollandaise sauce, poached eggs, 2 day tenderloin roasts... the sort of area where life is borderline unsanitary and people could get hurt, for not having the good sense to keep their work clean and buy fresh/clean ingredients. Note that fresh isn't necessariliy the greatest when cooking some meats. I digress.

To give you an example, in my previous posts, I came across a few crazy recipes for the blueberry filling. One recipe called for a cup of water, a few called for a cup of lemon juice (wow), and some of them had some incredible amounts of sugar: cup for cup against the blueberries.

The most incredulous recipe I have encountered, called for 3 cups of flour where most recipes call for about 2 to 2.25 cups of flour, in a cookie recipe. I suppose if you want cookies that can really grind teeth, you might consider upping your flour input. Good luck stirring the contents of your mixing bowl, by the way.

One thing I wonder is how to present food. I don't have a macro-ready camera, despite the setting on my camera that boldly says: Macro Setting. Some things, I realized pretty quickly, even before inception of these posts, are really tough to photograph.

Ok, so this close-up of chocolate sauce isn't so bad.

With a little bit of distance, not so great.

A shade closer, with a natural crop of the surroundings, and things are slightly better. I don't know if it is my camera or the lighting (probably the lighting) but everything has a slightly yellow overcast to it. Or conversely, an underexposure in green. Actually, is that even correct? Since this is view-by-reflection, I suppose that it is more correct to evaluate in CMYK and not RGB, which is view-by-radiance. I guess that would be an overexposure in yellow, then. I am a little bit confused, now.

Anyways, let's see how long this streak can go. I'll post the recipe for these coconut macaroons in the near future. I need to go to sleep, my house smells like butter and flour, and my hands smell like lemons. My camera has a slight dusting of flour. Surely this is the way to go, if I am going to start writing again in a most obvious way. :)

Permalink | Leave a comment  »

May 05, 07:57 PM

Ok, so now the pies are out of the oven.

Unfortunately, there is some serious seepage out of the sides of the pie. I wonder, would it be more correct to say the pie leaked out of its flutes? Does that even make any sense?

Here is a snazzy view in more of a landscape angle. Note that my ad-hoc slits look pretty nice, if I may . Too bad there were not enough to prevent the leaks.

Here is an overexposed closeup.

Here is a slightly normalized view, sans flash. The upper crust seems to look pretty good here.

I have covered the pies with a sheet of parchment paper to keep the dust out as the cool overnight. I don't know how I will transport the pies to work tomorrow, but I will have to figure something out.

This little adventure brings back some serious deja vu for me. I swear that I had a dream, about a year ago, that I brought pies in to work. I ended up wrapping them in plastic wrap, which I think I will do, but I will leave the parchment paper on for extra splatter insurance. I am concerned about them being jostled about on the commute in.

Permalink | Leave a comment  »

May 05, 07:06 PM

I don't know how to start a food blog... so let's just take one step into the water, to start. I'll try writing this in the most obvious way I can.

blueberry pie

I don't have any pictures of pie crust prep, but to be honest there isn't much to it. I used a basic butter pie crust, which is just flour, ice cold butter, salt, a touch of sugar, and some ice water to make it stick together. Let's fast forward to the pie assembly.

Here we have the 4 pieces of pie dough, enough for two pies with lids, and blueberry filling. I used frozen blueberries, as fresh blueberries would have cost me 2.5x as much. I am a little bit divided on this, but as the blueberries are going to be subject to some pretty high heat, I suppose fresh blueberries would be a waste of effort.

Here we have a slightly different angle. I have a pretty small camera, which is pretty good at quick shots but not that good at Macro photography. Note that the blueberries each have a tiny bit of shine in all the pictures.

Now that we have moved the stuff aside, I have unrolled the Roul'pat and brought out my handy rolling pin.

I neglected to get a shot of the rolled dough on the initial rollout, but I remembered to get one for the second, er, roll?

The table is clean but I have this thing about.. leaving stuff in contact with it. Hence I inverted the clean bowl and rested the 3rd sheet on it.

Here is another shot, varied again by angle.

Now that the dough has been rolled out, it is time to fill the pies. I waited till I rolled everything out as the filling has a lot of water and is going to soak into the dough if I don't work quick.

A few cuts into the pies, and trimming the excess.

About 40 minutes later, I started hearing some sizzling sounds. The pies are bubbling out of... the sides of the pie. To quote my best friend, "I couldn't imagine a pie leaking in that way...". I guess that's why pie-makers are so aggressive at crimping the edges of pies.

Oh, so I forgot to mention what is in the filling. I looked around online and I saw a lot of strange recipes for blueberry pie filling. I settled upon a recipe that only had lemon juice as the liquid, in a small amount, and not too much sugar. I feel like the berries should speak for themselves. The other ingredients are lemon zest, and some cornstarch. I won't be posting the full recipe just yet, but I will post it once I have received some feedback that the taste is spot on. At this very moment the pies are cooling and I need to go clean my kitchen. I will finish up with another post in short.

Permalink | Leave a comment  »

November 16, 01:16 AM

You could figure out where your opponent was by the color of their units on the ally screen. Rather than let my opponent know what was going on, I decided to toy with them.

Ah, now if only I took a followup screenshot.

Permalink | Leave a comment  »

November 16, 01:11 AM

What do you do when you are an observer in war2 and you want to mess with the other players anyways?

Sow salt into the earth :D

Permalink | Leave a comment  »

Posts

fiddleheads

my first time having them. they taste a little bit like escarole, asparagus, and romaine lettuce cores all together at once. if green had a quintessential taste, i think this would be it.

i used olive oil, but i think butter is a better match.

never put off until tomorrow...

… a sandwich that should be eaten today

Rory Sutherland on Shreddies (at TED)

Time Me

December, 1977

I usually skip the bandwagon, but looking into the National Women’s Conference (November, 1977) featured in the cover story on my birthday week was rather interesting.

Here is an excerpt that could still headline today.

Although the National Women’s Conference was not a lawmaking body and could only propose nonbinding recommendations, it was directed to arrive at a national plan of action to help remove sex barriers and better utilize women’s contributions. This plan, which grew from issues discussed at the state conferences, was to be submitted to the president and Congress within 120 days of the conference. Twenty-six major topics were considered by the delegates, including the ERA, abortion, lesbian rights, child care, minority women, homemakers, battered women, education, rape, health, and a cabinet-level women’s department. As expected, the most heated debates arose over the issues of abortion and lesbian rights. …

I wasn’t sure what the ERA was, so I went to look it up.

Equal Rights Amendment

Section 1. Equality of rights under the law shall not be denied or abridged by the United States or by any State on account of sex.

Section 2. The Congress shall have the power to enforce, by appropriate legislation, the provisions of this article.

Section 3. This amendment shall take effect two years after the date of ratification

A shame it didn’t pass.

i break horses

I Break Horses - Hearts

this is a great sign

madom aka magdom (tumblr) is impressed with you all. thank you.

happy blurry cinco de Madom

[Flash 10 is required to watch video.]

a communiqué from our beloved eyeseeyouarein, who has scouted a beach where one may sunbathe and watch planes land.

rodrigo y gabriela

fatchance:

I love this song. It makes me feel so close to nature.

“Feeling Good” by Leslie Bricusse and Anthony Newley, performed by Nina Simone. From the 1965 album I Put a Spell on You

Audio

  • fatchance: I love this song. It makes me feel so close to nature. “Feeling Good” by Leslie Bricusse and Anthony Newley, performed by Nina Simone. From the 1965 album I Put a Spell on You.
    57 plays
  • Bombay Bicycle Club - Shuffle
    110 plays
  • Film School - Sunny Day
    30 plays
  • The Centurions - Bullwinkle Part II ~ “Zed’s dead, baby. Zed’s dead”
    21 plays
  • The Lively Ones - Surf Rider
    20 plays
  • The Tornadoes - Bustin’ Surfboards
    31 plays
  • Ricky Nelson - Lonesome Town ~ no correlation to any mood; just listening to the pulp fiction soundtrack
    30 plays
  • Daft Punk - Aerodynamic
    20 plays
  • Ennio Morricone - Quella Estate ~ From the Pane e libertà Film Score (Bread & Liberty); artist referred by planproject / madmeals
    40 plays
  • Ravel - Bolero
    761 plays
  • Michael Nyman - A Borrowed Ladder (GATTACA soundtrack)
    30 plays
  • Mates of State - Get Better
    3280 plays
  • Wild Nothing - Golden Haze
    10 plays
  • Michael Nyman - The Departure ~ remember the movie GATTACA? (artist referred to me by planproject/madmeals)
    21 plays
  • Cults - Abducted
    20 plays
  • Corelli - Concerto #1 in D major - 3. Largo
    40 plays
  • Neko Case - Maybe Sparrow
    51 plays
  • wwemd: Stephen Fry reading The Nightingale and the Rose by Oscar Wilde ♥
    2556 plays
  • The Black Keys - Little Black Submarines (via thanksforthebread, melodyofyourlife)
    122 plays
  • Beirut - East Harlem
    90 plays

Posts

April 23, 06:03 AM
Canal House (2010), Flexibound
April 23, 04:37 AM
Canal House (2010), Flexibound
April 23, 04:37 AM
Canal House Cooking (2010), Paperback, 123 pages
April 23, 04:37 AM
Canal House (2009), Perfect Paperback
April 23, 04:36 AM
Apress (2009), Edition: 1, Paperback, 632 pages
April 23, 04:36 AM
Apress (2008), Edition: 1st ed. 2008. Corr. 2nd printing, Paperback, 488 pages
November 07, 04:59 PM
Portfolio Hardcover (2010), Hardcover, 256 pages
November 01, 08:03 AM
Harper Paperbacks (2000), Edition: 1st Pbk. Ed, Paperback, 224 pages
October 18, 12:35 AM
Bloomsbury USA (2009), Paperback, 272 pages
October 17, 04:54 AM
Chronicle Books (2010), Hardcover, 320 pages
October 17, 04:53 AM
Manning Publications (2009), Edition: 1, Paperback, 500 pages
October 17, 04:52 AM
Harvard Business Press (2009), Hardcover, 208 pages
October 17, 04:51 AM
O&#039;Reilly Media (2010), Edition: 1, Paperback, 272 pages
September 06, 03:04 AM
Chelsea Green Publishing (2010), Paperback, 208 pages
August 04, 12:52 PM
The MIT Press (2008), Paperback, 432 pages
August 02, 02:01 PM
Crown Business (2007), Edition: First Edition, Hardcover, 288 pages
July 08, 06:12 AM
HarperBusiness (2001), Edition: 1, Hardcover, 300 pages
July 08, 06:12 AM
Manning Publications (2010), Edition: 1, Paperback, 352 pages
June 15, 06:50 PM
Vintage (2010), Edition: 1, Paperback, 336 pages

Posts

May 16, 01:31 PM
meklarian started watching mislav/rfc May 16, 2012
rfc's description:
Pretty RFC indexes and reformats RFC documents for easier discovery and viewing.
May 15, 02:50 AM
meklarian started watching scottjehl/Respond May 15, 2012
Respond's description:
A fast & lightweight polyfill for min/max-width CSS3 Media Queries (for IE 6-8, and more)
May 14, 03:53 PM
meklarian forked gist: 2696175 May 14, 2012
C# Comb Guid generation
May 11, 01:28 PM
meklarian started watching farbrausch/fr_public May 11, 2012
fr_public's description:
Farbrausch demo tools 2001-2011
May 09, 06:01 PM
meklarian started watching caolan/async May 09, 2012
async's description:
Async utilities for node and the browser
May 09, 05:58 PM
meklarian started watching timrwood/moment May 09, 2012
moment's description:
Moment.js is a lightweight javascript date library for parsing, manipulating, and formatting dates.
May 09, 04:51 PM
meklarian started watching andrewplummer/Sugar May 09, 2012
Sugar's description:
A Javascript library for working with native objects.
May 08, 09:02 PM
meklarian started watching broofa/node-uuid May 09, 2012
node-uuid's description:
Generate RFC4122(v4) UUIDs, and also non-RFC compact ids
May 08, 06:47 PM
meklarian started watching mkoloberdin/waze May 08, 2012
waze's description:
Waze source code mirror (see http://www.waze.com/wiki/index.php/Source_code )
May 08, 03:40 PM
meklarian started watching bittorrent/apps-sdk May 08, 2012
apps-sdk's description:
Apps for BitTorrent SDK
May 08, 03:33 PM
meklarian started watching facebook/facebook-js-sdk May 08, 2012
facebook-js-sdk's description:
Facebook Javascript SDK
May 07, 07:29 PM
meklarian started watching glennjones/UfXtract May 07, 2012
UfXtract's description:
UfXtract is a .Net microformats parser
May 07, 06:17 PM
meklarian started watching twitter/twitter-text-conformance May 07, 2012
twitter-text-conformance's description:
Conformance testing data for the twitter-text-* repositories
May 07, 05:52 PM
meklarian started watching twitter/twitter-text-js May 07, 2012
twitter-text-js's description:
A JavaScript implementation of Twitter's text processing library
May 07, 05:52 PM
meklarian started watching twitter/twitter-text-objc May 07, 2012
twitter-text-objc's description:
An Objective-C implementation of Twitter's text processing library
May 04, 01:38 PM
meklarian started watching jquery/sizzle May 04, 2012
sizzle's description:
A sizzlin' hot selector engine.
May 02, 09:36 PM
meklarian started watching jeromeetienne/imageprocessing.js May 03, 2012
imageprocessing.js's description:
Simple Image Processing in javascript
May 02, 09:36 PM
meklarian started watching jeromeetienne/imageprocessing.js May 03, 2012
imageprocessing.js's description:
Simple Image Processing in javascript
May 02, 08:18 PM
meklarian started watching wycats/handlebars.js May 03, 2012
handlebars.js was created July 31, 2010
April 28, 11:39 PM
meklarian started watching xpaulbettsx/SassAndCoffee April 29, 2012
SassAndCoffee's description:
SassAndCoffee adds support in ASP.NET MVC to (you guessed it!) Sass/SCSS and CoffeeScript
April 28, 11:38 PM
meklarian started following xpaulbettsx April 29, 2012
xpaulbettsx has 54 public repos and 125 followers
April 28, 11:26 PM
meklarian started watching github/Akavache April 29, 2012
Akavache's description:
An asynchronous, persistent key-value store
April 27, 05:17 PM
meklarian started watching imakewebthings/jquery-waypoints April 27, 2012
jquery-waypoints's description:
Waypoints is a small jQuery plugin that makes it easy to execute a function whenever you scroll to an element.
April 24, 04:59 PM
meklarian started watching documentcloud/backbone April 24, 2012
backbone's description:
Give your JS App some Backbone with Models, Views, Collections, and Events
April 24, 04:56 PM
meklarian started watching documentcloud/underscore April 24, 2012
underscore's description:
JavaScript's utility _ belt
April 24, 03:31 PM
meklarian started watching janl/mustache.js April 24, 2012
mustache.js's description:
Minimal templating with {{mustaches}} in JavaScript
April 23, 05:18 PM
meklarian started watching FortAwesome/Font-Awesome April 23, 2012
Font-Awesome's description:
The iconic font designed for use with Twitter Bootstrap
April 23, 05:15 PM
meklarian started watching twitter/bootstrap April 23, 2012
bootstrap's description:
HTML, CSS, and JS toolkit from Twitter
April 23, 05:14 PM
meklarian started watching malarkey/320andup April 23, 2012
320andup's description:
This is the new 320 and Up
April 23, 03:18 PM
meklarian started watching nshah/rell April 23, 2012
rell's description:
An interactive environment to explore the Facebook JavaScript SDK.

Posts

May 15, 02:57 PM

Your sample works if you populate a DataSet instead of a DataTable.

Here is a copy of your source with the minimum changes required. Note that when you're using a DataSet you should add code to check whether any tables were returned, and whether there are rows in the first table available, etc.

Caller:

SqlParameter[] Parameters = new SqlParameter[1];
Parameters[0] = new SqlParameter();
Parameters[0].ParameterName = "@TestId";
Parameters[0].Value = TestId;
Parameters[0].SqlDbType = SqlDbType.Int;
Parameters[0].Size = 50;

DataSet data = ExecuteDataSet("ExportTestAsXML", Parameters);

// Read First table (Tables[0]), First Row (Rows[0]), First Column of that Row (Rows[0][0])
System.Diagnostics.Debug.Write(data.Tables[0].Rows[0][0]);

Method:

private DataSet ExecuteDataSet(string storedProcName, SqlParameter[] parameters)
{
    SqlCommand command = new SqlCommand();
    command.CommandText = storedProcName;
    command.Parameters.AddRange(parameters);
    command.CommandType = CommandType.StoredProcedure;
    command.Connection = (SqlConnection)dcMUPView.Connection;

    command.Connection.Open();
    command.Prepare();

    SqlDataAdapter adapter = new SqlDataAdapter(command);
    DataSet ds = new DataSet ();
    adapter.Fill(ds);

    command.Connection.Close();
    return ds;
}
April 13, 08:09 PM

The default packing is along 8-byte boundaries, according to the MIDL command line switch reference here:

/Zp switch @ MSDN (MIDL Language Reference)

Other parts of your code are more likely to break first if the pack value is changed, as the IDL file is usually pre-compiled ahead of time, and it is rare that someone will deliberately alter the command line switches given to MIDL (but not so rare that someone could fiddle with the C-scope #pragma pack and forget to restore the default state).

If you have a good reason to alter the setting, you can explicitly set the packing with a pragma pack statement.

pragma Attribute @ MSDN (MIDL Language Reference)

It is pretty good fortune that no party has changed any setting that would interfere with the default packing. Can it go wrong? Yes, if someone goes out of their way to change the defaults.

When using an IDL file, the details are typically compiled into a typelib (.tlb), and it is assumed that the platform are the same for both servers and clients when using the same typelib. This is suggested in the footnotes for the /Zp switch, as certain values will fail against certain non-x86 or 16-bit targets. There can also be 32bit <-> 64bit conversion cases that could cause expectations to break. Unfortunately I don't know if there are even more cases out there, but the defaults do work with minimal fuss.

C# and VB do not have any intrinsic behavior to handle information in a .tlb; instead, a tool like tlbimp is typically used to convert COM definitions into definitions usable from .NET. I can't verify whether all expectations succeed between C#/VB.NET and COM clients and servers; However, I can verify that using a specific pragma setting other than 8 will work if you reference a .tlb that was created from an IDL compiled under that setting. While I wouldn't recommend going against the default pragma pack, here are the steps to perform if you'd like a working example to use as a reference. I created a C++ ATL project and a C# project to check.

Here are the C++ side instructions.

  1. I created an ATL project called SampleATLProject with the default settings in Visual Studio 2010, no fields changed. This should create a dll project for you.
  2. Compiled the project to assure that the proper C-side interface files are being created (SampleATLProject_i.c and SampleATLProject_i.h).
  3. I added an ATL Simple Object called SomeFoo to the project. Again, no defaults were altered. This creates a class called CSomeFoo that is added to your project.
  4. Compile SampleATLProject.
  5. I right-clicked the SampleATLProject.idl file, then under the MIDL settings, set the Struct Member Alignment to 4 bytes (/Zp4).
  6. Compile SampleATLProject.
  7. I altered the IDL to add a struct definition called 'BarStruct'. This entailed adding a C-style struct definition with the MIDL uuid attribute, and an entry in library section referencing the struct definition. See snippet below.
  8. Compile SampleATLProject.
  9. From the Class View, I right-clicked on ISomeFoo and added a method called FooIt, that takes a struct BarStruct as an [in] parameter called theBar.
  10. Compile SampleATLProject.
  11. In SomeFoo.cpp, I added some code to print out the size of the struct and throw up a Message Box containing the details.

Here is my IDL for the ATL project.

import "oaidl.idl";
import "ocidl.idl";

[uuid(D2240D8B-EB97-4ACD-AC96-21F2EAFFE100)]
struct BarStruct
{
  byte a;
  int b;
  byte c;
  byte d;
};

[
  object,
  uuid(E6C3E82D-4376-41CD-A0DF-CB9371C0C467),
  dual,
  nonextensible,
  pointer_default(unique)
]
interface ISomeFoo : IDispatch{
  [id(1)] HRESULT FooIt([in] struct BarStruct theBar);
};
[
  uuid(F15B6312-7C46-4DDC-8D04-9DEA358BD94B),
  version(1.0),
]
library SampleATLProjectLib
{
  struct BarStruct;
  importlib("stdole2.tlb");
  [
    uuid(930BC9D6-28DF-4851-9703-AFCD1F23CCEF)      
  ]
  coclass SomeFoo
  {
    [default] interface ISomeFoo;
  };
};

Inside the CSomeFoo class, here is the implementation for FooIt().

STDMETHODIMP CSomeFoo::FooIt(struct BarStruct theBar)
{
  WCHAR buf[1024];
  swprintf(buf, L"Size: %d, Values: %d %d %d %d", sizeof(struct BarStruct), 
           theBar.a, theBar.b, theBar.c, theBar.d);

  ::MessageBoxW(0, buf, L"FooIt", MB_OK);

  return S_OK;
}

Next, on the C# side:

  1. Go to the debug or desired output directory for SampleATLProject and run tlbimp.exe on the .tlb file generated as part of the C++ project output. The following worked for me:

    tlbimp SampleATLProject.tlb /out:Foo.dll /namespace:SampleATL.FooStuff

  2. Next, I created a C# console application, and added a reference to Foo.dll to the project.

  3. In the References folder, go to the Properties for Foo and turn off Embed Interop Types by setting it to false.
  4. I added a using statement to reference the namespace SampleATL.FooStuff as given to tlbimp, added the [STAThread] attribute to Main() (the COM apartment models have to match for in-proc consumption), and added some code to call the COM component.

Tlbimp.exe (Type Library Importer) @ MSDN

Here is the source code for that console app.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using SampleATL.FooStuff;

namespace SampleATLProjectConsumer
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            BarStruct s;
            s.a = 1;
            s.b = 127;
            s.c = 255;
            s.d = 128;

            ISomeFoo handler = new SomeFooClass();
            handler.FooIt(s);
        }
    }
}

Finally, it runs and I get a modal popup with the following string displayed:

Size: 12, Values: 1 127 255 128

To be sure that a pragma pack change can be made (as 4/8 byte packing are the most common alignments used), I followed these steps to change it to 1:

  1. I returned to the C++ project, went to the properties for SampleATLProject.idl and changed the Struct Member Alignment to 1 (/Zp1).
  2. Recompile SampleATLProject
  3. Run tlbimp again with the updated .tlb file.
  4. A warning icon will appear on the .NET File Reference to Foo, but may disappear if you click on the reference. If it doesn't, you can remove and re-add the reference to the C# console project to be sure it is using the new updated version.

I ran it from here and got this output:

Size: 12, Values: 1 1551957760 129 3

That's weird. But, if we forcefully edit the C-level pragma in SampleATLProject_i.h, we get the correct output.

#pragma pack(push, 1)
/* [uuid] */ struct  DECLSPEC_UUID("D2240D8B-EB97-4ACD-AC96-21F2EAFFE100") BarStruct
    {
    byte a;
    int b;
    byte c;
    byte d;
    } ;
#pragma pack(pop)

SampleATLProject is recompiled here, no changes to the .tlb or .NET project, and we get the following:

Size: 7, Values: 1 127 255 128

Regarding IDispatch, it depends on whether your client is late-bound. Late-bound clients have to parse the type information side of IDispatch and discern the proper definitions for non-trivial types. The documentation for ITypeInfo and TYPEATTR suggests that it is possible, given that the cbAlignment field provides the information necessary. I suspect most will never alter or go against the defaults, as this would be tedious to debug if things went wrong or if the pack expectations had to change between versions. Also, structures are not typically supported by many scripting clients that can consume IDispatch. One can frequently expect that only the types governed by the IDL oleautomation keyword are supported.

IDispatch interface @ MSDN
IDispatch::GetTypeInfo @ MSDN
ITypeInfo interface @ MSDN
TYPEATTR structure @ MSDN

oleautomation keyword @ MSDN

March 16, 07:49 AM

I don't think there is a trivial way to resolve the actual owner of a Mutex, but the process that owns it can create other secondary items whose lifetimes are tied to it. There are plenty of mechanisms that are suitable for calling back across-process without having a main window.

  1. Register an object in the COM Running Object Table. Clients that are unable to take ownership of the Mutex can lookup the owner via the ROT and call back to the owner. A File Moniker should be suitable for registration here.
  2. Create a chunk of shared memory containing location details for the owner process. From there, write into the buffer the process handle and thread handle of a thread that can receive windows messages, and then use PostThreadMessage() to send a notification. Any other competing process may open the shared memory for read-only to determine where to send a windows message.
  3. Listen in the owner process on a Socket or Named Pipe. Probably overkill and not a good match for your needs.
  4. Use a shared file with locking. I'm not fond of this because the owner will need to poll, and it won't gracefully handle N potential other processes that could be trying to contact the owner at the same time.

Here are reference links for the first two options.

  1. IRunningObjectTable @ MSDN , File Monikers @ MSDN
  2. Creating Named Shared Memory @ MSDN
March 06, 05:40 PM

MessageBox() has a windows message pump cycle built into it to service window messages.

Somewhere in your application at a very low level within your design, you need a windows message loop to service messages for the window hosting your openGL content. This should run from within the thread that created the window. The ill effects you are seeing in other places could easily be caused by contention side-effects when MessageBox() is invoked from a different thread.

Here is an intro to the operation of window messages at MSDN.

Using Messages and Message Queues @ MSDN

Very simply put (via a code sample from wikipedia), you need a standing loop akin to the following:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    MSG msg;
    while(GetMessage(&msg, NULL, 0, 0) > 0)
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}

Depending on how you have handled updating the window, if you are using paint messages (WM_PAINT), you need to ensure these are dispatched as quickly as possible, or you may need to suppress them entirely if you are drawing direct to the the device DC. I'm mentioning this because you may find additional bugs once a message loop is properly setup.

WM_PAINT message @ MSDN

March 06, 05:31 PM

The sample you've provided doesn't match the members of the class TwitterProfile. Notwithstanding this, you don't need a helper class to handle an array. You can simply target the array type directly at deserialization.

Here's a code sample that you can use to test. I've removed your TwitterProfiles class and stripped down TwitterProfile to just a field named CreatedAt.

Note the following line in the source below:

DataContractJsonSerializer js = 
    new DataContractJsonSerializer(typeof(TwitterProfile[]));

Here is the rest.

using System.Windows.Forms;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;

namespace TwProfileJson
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            if (dlg.ShowDialog() != DialogResult.OK) { return; }
            string json = System.IO.File.ReadAllText(dlg.FileName);

            using(MemoryStream stm = new MemoryStream(Encoding.UTF8.GetBytes(json)))
            {
                DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(TwitterProfile[]));
                TwitterProfile[] pps = (TwitterProfile[])js.ReadObject(stm);

                foreach(TwitterProfile p in pps)
                {
                    Console.WriteLine(p.CreatedAt);
                }
            }

            Console.ReadKey();
        }

        [DataContract]
        public class TwitterProfile
        {
            [DataMember(Name = "created_at")]
            public string CreatedAt { get; set; }
        }
    }
}
March 05, 02:59 PM

The original specification for COM is old in age, but the specification as well as the concepts are still in use, and you can still create and consume COM objects.

For .NET, you can start by looking at the following links:

Com Interop Part 1: C# Client Tutorial (C#) @ MSDN
Interoperating with unmanaged code @ MSDN

In addition, there are other specs that are very similar to COM or have semantics that are the same. Most notably, XPCOM is in use in FireFox for their plugin spec and also used internally to FireFox to connectable objects.

XPCOM @ MDN (Mozilla)

WinRT is an upcoming platform update for windows that is also heavy in COM concepts.

There are some useful here: Why is WinRT unmanaged @ StackOverflow

For .NET developers, a lot of the declarative overhead is hidden as mentioned here: WinRT demystified - Miguel de Icaza

The head of the spec is here: The Windows Runtime @ MSDN

And in the context of COM, developing WinRT components with C++ has similarities, although some syntax is borrowed from managed C++: Creating Windows Runtime Components in C++ @ MSDN

March 05, 02:40 PM

You were quite close in syntax. The key here is that d["members"] is of type Object[] / object[]. Instead of Array, you can use dynamic[] and everything works just fine.

Also note that even this declaration isn't explicitly necessary, as shown in DPeden's updated sample.

Here is the code for your updated snippet (I used a console app to test):

JavaScriptSerializer js = new JavaScriptSerializer();
dynamic d = js.Deserialize<dynamic>(json);

string key = d["key"];
string status = d["status"];
dynamic[] members = d["members"];

Console.WriteLine("key = {0}", key);
Console.WriteLine("status = {0}", status);

Console.WriteLine("members.length = {0}", members.Length);
Console.WriteLine("members type name = {0}", members.GetType().Name);
Console.WriteLine("d[\"members\"] type name = {0}", d["members"].GetType().Name);

And here is additional code showing array and member access.

Console.WriteLine("--");

for (int i = 0; i < members.Length; i++)
{
    Console.WriteLine("members[{0}][\"id\"] = {1}", i, members[i]["id"]);
    Console.WriteLine("members[{0}][\"name\"] = {1}", i, members[i]["name"]);
}

Console.WriteLine("--");

Console.WriteLine("{0}", d["members"][0]["id"]);
Console.WriteLine("{0}", d["members"][0]["name"]);

Console.ReadKey();
March 01, 07:35 PM

Added after comment:

You would need to pickup some latent detail that you can exploit to be able to accomplish that goal.

One thing that comes to mind is creating your own Forms/WPF timer at construction time and then use this and some synchronization to hide the details of coordination across threads. We can infer from your sample that construction of your poller should always happen in context of your consumer's thread.

This is a rather hack-ish way to accomplish what you want, but it can accomplish the deed because the construction of your poll-listener happens from the consumer's thread (which has a windows message pump to fuel the dispatches of Forms/WPF timers), and the rest of the operation of the class could occur from any thread as the forms Timer's tick will heartbeat from the original thread. As other comments and answers have noted, it would be best to reassess and fix the operating relationship between your polling operations and the consumer.

Here is an updated version of the class, PollingListener2 that uses a ManualResetEvent and a concealed System.Windows.Forms.Timer to ferry the polling notice across threads. Cleanup code is omitted for the sake of brevity. Requiring the use of IDisposable for explicit cleanup would be recommended in a production version of this class.

ManualResetEvent @ MSDN

public class PollingListener2
{
    System.Timers.Timer timer = new System.Timers.Timer(1000);
    public event EventHandler<EventArgs> Polled;

    System.Windows.Forms.Timer formsTimer;
    public System.Threading.ManualResetEvent pollNotice;

    public PollingListener2()
    {
        pollNotice = new System.Threading.ManualResetEvent(false);
        formsTimer = new System.Windows.Forms.Timer();
        formsTimer.Interval = 100;
        formsTimer.Tick += new EventHandler(formsTimer_Tick);
        formsTimer.Start();
        timer.Elapsed += new System.Timers.ElapsedEventHandler(PollNow);
        timer.Start();
    }

    void formsTimer_Tick(object sender, EventArgs e)
    {
        if (pollNotice.WaitOne(0))
        {
            pollNotice.Reset();
            var temp = Polled;
            if (temp != null)
            {
                Polled(this, new EventArgs());
            }
        }
    }

    void PollNow(object sender, EventArgs e)
    {
        pollNotice.Set();
    }
}

This has some precedent in the distant Win32 past where some people would use hidden windows and the like to maintain one foot in the other thread without requiring the consumer to make any significant changes to their code (sometimes no changes are necessary).


Original:

You could add a member variable on your helper class of type Control or Form and use that as the scope for a BeginInvoke() / Invoke() call on your event dispatch.

Here's a copy of your sample class, modified to behave in this manner.

public class PollingListener
{
    System.Timers.Timer timer = new System.Timers.Timer(1000);
    public event EventHandler<EventArgs> Polled;

    public PollingListener(System.Windows.Forms.Control consumer)
    {
        timer.Elapsed += new System.Timers.ElapsedEventHandler(PollNow);
        timer.Start();
        consumerContext = consumer;
    }

    System.Windows.Forms.Control consumerContext;

    void PollNow(object sender, EventArgs e)
    {
        var temp = Polled;
        if ((temp != null) && (null != consumerContext))
        {
            consumerContext.BeginInvoke(new Action(() =>
                {
                    Polled(this, new EventArgs());
                }));
        }
    }
}

Here's a sample that shows this in action. Run this in debug mode and look at your output to verify that it is working as expected.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        listener = new PollingListener(this);
    }

    PollingListener listener;

    private void Form1_Load(object sender, EventArgs e)
    {
        listener.Polled += new EventHandler<EventArgs>(listener_Poll);
    }

    void listener_Poll(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("ding.");
    }
}
March 01, 05:44 PM

There are multiple ways to parse this; but in the style you've initially presented, you should try accessing it with [] indexers.

Note that your data has a root object with two properties, meta and response. Assuming response can't be null, you can access categories from it directly like this:

var root = JObject.Parse(/* your json string here */);
var categories = root["response"]["categories"];
var firstCategory = categories[0];

Note that you can use strings matching property names to descend into nested levels, and integers to index into arrays in scope.

Here is the rest of a sample program that can parse the json snippet you've provided.

using System.Windows.Forms;

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;

namespace _4sqCatResponse
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            if(dlg.ShowDialog() != DialogResult.OK){return;}
            string json = System.IO.File.ReadAllText(dlg.FileName);

            var root = JObject.Parse(json);
            var categories = root["response"]["categories"];
            var firstCategory = categories[0];
            Console.WriteLine("id: {0}", firstCategory["id"]);
            Console.WriteLine("name: {0}", firstCategory["name"]);
            Console.WriteLine("pluralName: {0}", firstCategory["pluralName"]);
            Console.WriteLine("shortName: {0}", firstCategory["shortName"]);
            var icon = firstCategory["icon"];
            Console.WriteLine("icon.prefix: {0}", icon["prefix"]);
            Console.WriteLine("icon.sizes[0]: {0}", icon["sizes"][0]);
            Console.WriteLine("icon.name: {0}", icon["name"]);

            Console.ReadKey();
        }
    }
}

Also I'm a little confused by your json sample; I think you may have overlaid part of your sample or cut something out as you have categories nested in categories. If there is indeed a 2nd level categories inside your categories element and that's what you want, you can access it with this:

var categories2 = root["response"]["categories"][0]["categories"][0];
Console.WriteLine("inner categories id: {0}", categories2["id"]);

Here is the json source I used to test, copied from yours but with closing } and ] marks where needed to make it parse.

{
    "meta": {
        "code": 200
    },
    "response": {
        "categories": [{
            "id": "4d4b7104d754a06370d81259",
            "name": "Arts & Entertainment",
            "pluralName": "Arts & Entertainment",
            "shortName": "Arts & Entertainment",
            "icon": {
                "prefix": "https:\/\/foursquare.com\/img\/categories\/arts_entertainment\/default_",
                "sizes": [32, 44, 64, 88, 256],
                "name": ".png"
            },
            "categories": [{
                "id": "4bf58dd8d48988d1e1931735"
                }]
            }]
    }
}
February 24, 08:41 PM

The byte array arguments to Socket.IOControl() are specific to the IOControlCode that is specified as the first argument.

The first array is for input data, the second array is for output data.

To find more information about the specific layout for these arrays, it is helpful to start by looking at the enumeration, which lists all the possible operations for you. From there, you should cross reference with the documentation listed for the C-operable functions that Socket.IOControl() wraps. These are WSAIoctl() and ioctlsocket().

IOControlCode Enumeration @ MSDN

WSAIoctl() function @ MSDN
ioctlsocket() function @ MSDN

Per the documentation for IOControlCode.ReceiveAll:

Enable receiving all IPv4 packets on the network. The socket must have address family InterNetwork, the socket type must be Raw, and the protocol type must be IP. The current user must belong to the Administrators group on the local computer, and the socket must be bound to a specific port. This control code is supported on Windows 2000 and later operating systems. This value is equal to the Winsock 2 SIO_RCVALL constant.

Cross referencing SIO_RCVALL, we find it has an entry in the winsock documentation.

SIO_RCVALL control code @ MSDN

Reading through this entry, it mentions that the input buffer is required to select a mode of operation, with minimum size corresponding to a RCVALL_VALUE. In your statement you are passing the value 1 in the input argument array. We can check header files to see what this should mean.

You should double check this with C header files at hand, but the interface-compatible copy for wine (windows emulator) says the value for mode RCVALL_ON is 1. The .NET method should wrap the details of managing array size for you, so the code snippet you encountered is trying to enable RCVALL_ON for the socket.

Here is the link to the C header file at winehq.org: mstcpip.h at winehq.org

If you've installed C/C++ support for visual studio, you may be able to locate mstcpip.h and winsock2.h locally at a path similar to the following:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\

My copy says:

//
// Values for use with SIO_RCVALL* options
//
typedef enum {
    RCVALL_OFF             = 0,
    RCVALL_ON              = 1,
    RCVALL_SOCKETLEVELONLY = 2,
    RCVALL_IPLEVEL         = 3,
} RCVALL_VALUE, *PRCVALL_VALUE;

I couldn't find any documentation that specifically says what size byte array should be used to pass a RCVALL_VALUE, but if you look at the the samples for IOControl(), they use BitConverter.GetBytes(0) for default parameters which would have a size of 4 bytes (corresponding to a .NET int) and matches your example. This is large enough to fit a RCVALL_VALUE in C operation as well.

February 21, 01:43 PM

Both sets of types you've given work; the issue is the source data returned is an array of the core type, not a single instance. Note the square brackets in the JSON sample you've provided around the entire unit of data.

Here is a test console app that you can use to check the JSON you're seeing.

To use it, copy the JSON you have provided above into an arbitrary text file and open it from the app.

Note that deserializing as an array works fine, but single element (per your expectations) fails.

If you create a sample text file containing the same sample data but without the outer [ ] brackets, you'll see that the array deserialization fails and single elements work.

using System.Windows.Forms;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace RptSuiteMetricsTest1
{
    class Program
    {
        public class report_suite_metrics
        {
            public string rsid { get; set; }
            public string site_title { get; set; }
            public metric[] available_metrics { get; set; }
        }

        public class metric
        {
            public string metric_name { get; set; }
            public string display_name { get; set; }
        }

        public class AvailableMetric
        {
            public string metric_name { get; set; }
            public string display_name { get; set; }
        }

        public class RootObject
        {
            public string rsid { get; set; }
            public string site_title { get; set; }
            public List<AvailableMetric> available_metrics { get; set; }
        }

        [STAThread]
        static void Main(string[] args)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            DialogResult dr = dlg.ShowDialog();
            if (dr != DialogResult.OK) { return; }

            // NOTE: ...or replace this with a string containing the json data to test.
            string jsonData = System.IO.File.ReadAllText(dlg.FileName);

            Console.WriteLine("Deserialize as array");
            try
            {
                report_suite_metrics[] dataset = JsonConvert.DeserializeObject<report_suite_metrics[]>(jsonData);
                Console.WriteLine("{0} items found.", dataset.Length);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception of type {0}", ex.GetType().Name);
            }

            Console.WriteLine("Deserialize as array, alternate type");
            try
            {
                RootObject[] dataset = JsonConvert.DeserializeObject<RootObject[]>(jsonData);
                Console.WriteLine("{0} items found.", dataset.Length);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception of type {0}", ex.GetType().Name);
            }

            Console.WriteLine();

            Console.WriteLine("Deserialize as single item");
            try
            {
                report_suite_metrics dataset = JsonConvert.DeserializeObject<report_suite_metrics>(jsonData);
                Console.WriteLine("rsid=\"{0}\"", dataset.rsid);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception of type {0}", ex.GetType().Name);
            }

            Console.WriteLine("Deserialize as single item, alternate type");
            try
            {
                RootObject dataset = JsonConvert.DeserializeObject<RootObject>(jsonData);
                Console.WriteLine("rsid=\"{0}\"", dataset.rsid);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Exception of type {0}", ex.GetType().Name);
            }

            Console.ReadKey();
        }
    }
}
November 10, 05:09 PM

You can write a helper class that circumvents the usual handling of System.Uri and treats it purely as a string, using the Uri.OriginalString property.

Here's a code sample that does exactly that with a converter class derived from Json.Net's JsonConverter.

OriginalString Property (System.Uri) @ MSDN

One caveat is that you must update all places where you use JsonConvert to include the helper class as one of the extra JsonConverter parameters.

I've also added an example using Uri as a member variable in a class, to demonstrate that one wouldn't necessarily have to override the attributes on a class, though it might be more convenient for you. If so, you could use [JsonConverter(UriConverter)] as an attribute on members that need it.

using Newtonsoft.Json;

namespace JsonUriSerializeTest
{
    class Program
    {
        public class UriConverter : JsonConverter
        {
            public override bool CanConvert(Type objectType)
            {
                return objectType.Equals(typeof(Uri));
            }

            public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
            {
                if (reader.TokenType == JsonToken.String)
                {
                    return new Uri((string)reader.Value);
                }

                if (reader.TokenType == JsonToken.Null)
                {
                    return null;
                }

                throw new InvalidOperationException("Unhandled case for UriConverter. Check to see if this converter has been applied to the wrong serialization type.");
            }

            public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
            {
                if (null == value)
                {
                    writer.WriteNull();
                    return;
                }

                if (value is Uri)
                {
                    writer.WriteValue(((Uri)value).OriginalString);
                    return;
                }

                throw new InvalidOperationException("Unhandled case for UriConverter. Check to see if this converter has been applied to the wrong serialization type.");
            }
        }

        public class UriPair
        {
            public string label { get; set; }
            public Uri first { get; set; }
            public Uri second { get; set; }

            public void Display()
            {
                Console.WriteLine(string.Format("label:  {0}", label));
                Console.WriteLine(string.Format("first:  {0}", first));
                Console.WriteLine(string.Format("second: {0}", second));
            }
        }

        static void Main(string[] args)
        {
            string input = "http://test.com/%22foo+bar%22";
            Uri uri = new Uri(input);
            string json = JsonConvert.SerializeObject(uri, new UriConverter());
            Uri output = JsonConvert.DeserializeObject<Uri>(json, new UriConverter());

            Console.WriteLine(input);
            Console.WriteLine(output.ToString());
            Console.WriteLine();

            UriPair pair = new UriPair();
            pair.label = input;
            pair.first = null;
            pair.second = new Uri(input);
            string jsonPair = JsonConvert.SerializeObject(pair, new UriConverter());
            UriPair outputPair = JsonConvert.DeserializeObject<UriPair>(jsonPair, new UriConverter());

            outputPair.Display();
            Console.WriteLine();

            Console.ReadKey();
        }
    }
}
November 10, 04:29 PM

Updated Answer:

Looking at how JSON.Net maps XML, it takes the approach that what it sees is what it serializes, except that if it sees multiples, it will make an array. This is great for many XML DOM trees with consistent layout, but unfortunately cannot work for your purposes.

You can verify this by looking at the body for the functions SerializeGroupedNodes() and SerializeNode() in the following file source.

XmlNodeConverter.cs source code @ CodePlex, ChangeSet #63616

There's another option that I'd previously thought might be overkill but would be helpful now that we know what to expect from the default behavior on the serializing end.

Json.Net supports using custom converters derived from JsonConverter to map particular cases of values on a case-by-case basis.

We can handle this either at the serializing side or the deserializing side. I've chosen to write a solution on the deserializing side, as you probably have other existing reasons to map XML to JSON.

One great benefit is that your class can stay intact except for the override, which requires that you apply an attribute. Here's a code sample demonstrating how to use JsonAttribute and a custom converter class (MMArrayConverter) to fix your problem. Note that you will probably want to test this more thoroughly and maybe update the converter to handle other cases, say if you eventually migrate to IList<string> or some other funky case like Lazy<List<string>>, or even make it work with generics.

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Converters;

namespace JsonArrayImplictConvertTest
{
    public class MMArrayConverter : JsonConverter
    {
        public override bool CanConvert(Type objectType)
        {
            return objectType.Equals(typeof(List<string>));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.StartArray)
            {
                List<string> parseList = new List<string>();
                do
                {
                    if (reader.Read())
                    {
                        if (reader.TokenType == JsonToken.String)
                        {
                            parseList.Add((string)reader.Value);
                        }
                        else
                        {
                            if (reader.TokenType == JsonToken.Null)
                            {
                                parseList.Add(null);
                            }
                            else
                            {
                                if (reader.TokenType != JsonToken.EndArray)
                                {
                                    throw new ArgumentException(string.Format("Expected String/Null, Found JSON Token Type {0} instead", reader.TokenType.ToString()));
                                }
                            }
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("Broken JSON Input Detected");
                    }
                }
                while (reader.TokenType != JsonToken.EndArray);

                return parseList;
            }

            if (reader.TokenType == JsonToken.Null)
            {
                // TODO: You need to decide here if we want to return an empty list, or null.
                return null;
            }

            if (reader.TokenType == JsonToken.String)
            {
                List<string> singleList = new List<string>();
                singleList.Add((string)reader.Value);
                return singleList;
            }

            throw new InvalidOperationException("Unhandled case for MMArrayConverter. Check to see if this converter has been applied to the wrong serialization type.");
        }

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            // Not implemented for brevity, but you could add this if needed.
            throw new NotImplementedException();
        }
    }

    public class ModifiedXX
    {
        public string yy { get; set; }

        [JsonConverter(typeof(MMArrayConverter))]
        public List<string> mm { get; set; }

        public void Display()
        {
            Console.WriteLine("yy is {0}", this.yy);
            if (null == mm)
            {
                Console.WriteLine("mm is null");
            }
            else
            {
                Console.WriteLine("mm contains these items:");
                mm.ForEach((item) => { Console.WriteLine("  {0}", item); });
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string jsonTest1 = "{\"yy\":\"nn\", \"mm\": [ \"zzz\", \"aaa\" ] }";
            ModifiedXX obj1 = JsonConvert.DeserializeObject<ModifiedXX>(jsonTest1);
            obj1.Display();

            string jsonTest2 = "{\"yy\":\"nn\", \"mm\": \"zzz\" }";
            ModifiedXX obj2 = JsonConvert.DeserializeObject<ModifiedXX>(jsonTest2);
            obj2.Display();

            // This test is now required in case we messed up the parser state in our converter.
            string jsonTest3 = "[{\"yy\":\"nn\", \"mm\": [ \"zzz\", \"aaa\" ] },{\"yy\":\"nn\", \"mm\": \"zzz\" }]";
            List<ModifiedXX> obj3 = JsonConvert.DeserializeObject<List<ModifiedXX>>(jsonTest3);
            obj3.ForEach((obj) => { obj.Display(); });

            Console.ReadKey();
        }
    }
}

Original Answer:

It would be best to fix the JSON you're receiving at the source, as many have already pointed out. You may wish to post an update showing how the XML in your updated comment is being mapped to JSON, as that would be the best route overall.

However, if you find that this is not possible and you want some way to serialize and handle the variant value after-the-fact, you can patch things up by declaring mm to be type object, and then handling the possible cases yourself using JSON.Net's Linq support. In the two scenarios you described, you'll find that declaring mm to be type object will result in either a null, a string, or a JArray being assigned to mm by the call to DeserializeObject<>.

Here's a code sample that shows this in action. There's also a case in other circumstances where you could receive a JObject, which is also covered in this sample. Note that the member function mmAsList() does the work of patching up the difference for you. Also note that I've handled null here by returning a null for List<string>; you will probably want to revise this for your implementation.

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace JsonArrayUnionTest
{
    public class ModifiedXX
    {
        public string yy { get; set; }
        public object mm { get; set; }

        public List<string> mmAsList()
        {
            if (null == mm) { return null; }
            if (mm is JArray)
            {
                JArray mmArray = (JArray)mm;
                return mmArray.Values<string>().ToList();
            }

            if (mm is JObject)
            {
                JObject mmObj = (JObject)mm;
                if (mmObj.Type == JTokenType.String)
                {
                    return MakeList(mmObj.Value<string>());
                }
            }

            if (mm is string)
            {
                return MakeList((string)mm);
            }

            throw new ArgumentOutOfRangeException("unhandled case for serialized value for mm (cannot be converted to List<string>)");
        }

        protected List<string> MakeList(string src)
        {
            List<string> newList = new List<string>();
            newList.Add(src);
            return newList;
        }

        public void Display()
        {
            Console.WriteLine("yy is {0}", this.yy);
            List<string> mmItems = mmAsList();
            if (null == mmItems)
            {
                Console.WriteLine("mm is null");
            }
            else
            {
                Console.WriteLine("mm contains these items:");
                mmItems.ForEach((item) => { Console.WriteLine("  {0}", item); });
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            string jsonTest1 = "{\"yy\":\"nn\", \"mm\": [ \"zzz\", \"aaa\" ] }";
            ModifiedXX obj1 = JsonConvert.DeserializeObject<ModifiedXX>(jsonTest1);
            obj1.Display();

            string jsonTest2 = "{\"yy\":\"nn\", \"mm\": \"zzz\" }";
            ModifiedXX obj2 = JsonConvert.DeserializeObject<ModifiedXX>(jsonTest2);
            obj2.Display();

            Console.ReadKey();
        }
    }
}
November 07, 11:27 AM

The assignment and dereference for AddRef() are correct.

When MFCreateVideoSampleFromSurface() is called, the second argument to it is the location where the pointer to the interface should be stored. You use &pSample to obtain the address to pass to the function. This matches the IMFSample ** type required. Note that the & operator on CComPtr<> via CComPtrBase<> returns the correct type.

CComPtrBase::& operator @ MSDN

ppVideoSample is type IMFSample ** as well, which requires the * operator to dereference the interface pointer. That yields a pointer of type IMFSample *, which you can call with the -> operator to access AddRef() and other functions on the interface.

November 03, 07:43 PM

Short Answer: You can get individual tokens of text via Doc.GetText("SVG"), parsing the XML for TEXT and TSPAN elements, and determining if there is layout spacing that should be treated as actual spaces. The behavior you're seeing from PDFBox is probably their attempt to make that assumption. Also, even Adobe Acrobat can return spaced text via the clipboard as PDFBox does.

Long Answer: This may cause more problems, as this may not be the original intent of the text in the PDF.

ABCpdf is doing the correct thing here, as the PDF spec only describes where things should be placed in the output medium. One can construct a PDF file that ABCpdf interprets in both styles, even though the original sentence looks nearly the same.

To demonstrate this, here is a snapshot of a document from Adobe InDesign that shows a text layout matching both cases for your sample sentence.

Note that the first row was not constructed with actual spaces, instead, the words were placed by hand in individual text regions and lined up to look approximately like a properly spaced sentence. The second row has a single sentence that has actual text spaces between the words, in a single text region.

When exported to PDF and then read in by ABCpdf, Doc.GetText("TEXT") will return the following:

ThisSentenceDoesn'tHaveAnySpacesBetweenWords.  
This Sentence Doesn't Have Any Spaces Between Words.

Thus if you wish to detect layout spaces, you must use SVG output and step through the tokens of text manually. Doc.GetText("SVG") returns text and other drawing entities as ABCpdf sees them on the page, and you can decide how you want to handle the case of layout based spacing.

You'll receive output similar to this:

<?xml version="1.0" standalone="no"?>
<svg width="612" height="792" x="0" y="0" version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<text xml:space="preserve" x="36" y="46.1924" font-size="14" font-family="ArialMT" textLength="26.446" transform="translate(36, 46.1924) translate(-36, -46.1924)">This</text>
<text xml:space="preserve" x="66.002" y="46.1924" font-size="14" font-family="ArialMT" textLength="59.15" transform="translate(66.002, 46.1924) translate(-66.002, -46.1924)">Sentence</text>
<text xml:space="preserve" x="129.604" y="46.1924" font-size="14" font-family="ArialMT" textLength="47.46" transform="translate(129.604, 46.1924) translate(-129.604, -46.1924)">Doesn&#8217;t</text>
<text xml:space="preserve" x="181.208" y="46.1924" font-size="14" font-family="ArialMT" textLength="32.676" transform="translate(181.208, 46.1924) translate(-181.208, -46.1924)">Have</text>
<text xml:space="preserve" x="219.61" y="46.1924" font-size="14" font-family="ArialMT" textLength="24.122" transform="translate(219.61, 46.1924) translate(-219.61, -46.1924)">Any</text>
<text xml:space="preserve" x="249.612" y="46.1924" font-size="14" font-family="ArialMT" textLength="46.69" transform="translate(249.612, 46.1924) translate(-249.612, -46.1924)">Spaces</text>
<text xml:space="preserve" x="301.216" y="46.1924" font-size="14" font-family="ArialMT" textLength="54.474" transform="translate(301.216, 46.1924) translate(-301.216, -46.1924)">Between</text>
<text xml:space="preserve" x="360.016" y="46.1924" font-size="14" font-family="ArialMT" transform="translate(360.016, 46.1924) translate(-360.016, -46.1924)"><tspan textLength="13.216">W</tspan><tspan dx="-0.252" textLength="31.122">ords.</tspan></text>
<text xml:space="preserve" x="36.014" y="141.9944" font-size="14" font-family="ArialMT" transform="translate(36.014, 141.9944) translate(-36.014, -141.9944)">
<tspan textLength="181.3">This Sentence Doesn&#8217;t Have </tspan><tspan dx="-0.756" textLength="150.178">Any Spaces Between W</tspan><tspan dx="-0.252" textLength="31.122">ords.</tspan></text>
</svg>

And note that the basic structure reveals the original intent that gave you problems. (xml:space and attributes removed, whitespace modifications for the sake of example)

<?xml version="1.0" standalone="no"?>
<svg>
  <text>This</text>
  <text>Sentence</text>
  <text>Doesn&#8217;t</text>
  <text>Have</text>
  <text>Any</text>
  <text>Spaces</text>
  <text>Between</text>
  <text><tspan>W</tspan><tspan>ords.</tspan></text>
  <text>
    <tspan>This Sentence Doesn&#8217;t Have </tspan>
    <tspan>Any Spaces Between W</tspan>
    <tspan>ords.</tspan>
  </text>
</svg>
July 21, 06:24 PM

A stack imbalance occurs when the data structure used to keep track of called functions, arguments, and return values becomes corrupted or misaligned.

Most times, the stack is a memory pointer that stores the address where control will resume when the current function call exits back to the caller. There are different variants on this, sometimes the arguments to a function are also appended to the stack, as well as the return value. What is most important here is that the caller and callee should agree upon how to restore it back to the prior state when the callee exits. This agreement is frequently known as the Calling Convention.

In .NET, stack imbalances are a rare to nonexistent problem in pure managed code. However, this can be a frequent problem when calling unmanaged code, as you will need to tell the compiler how the method should be called, which then implies how the stack should be cleaned up per the calling convention.

On windows, there are a few standard calling conventions that cover the bulk of invocation cases.

stdcall - Callee will fix the stack upon exit.
fastcall - Potentially no need to fix the stack aside from return address, instead, CPU registers are used to pass arguments.
cdecl - The caller will fix the stack after the called function returns.

A formal reference is available here: Argument Passing and Naming Conventions @ MSDN

This is also of interest: X86 calling convention list @ Wikipedia

Within a given development domain, this tends not to be a problem. Each language generally has a convention that is implicit for all method calls. C/C++ uses the same convention for invocation of C/C++ calls, Python for other Python calls, etc. When crossing domains, it can become a problem if one domain doesn't use the same as another. Perhaps most common in windows, a function exported with "C" style declarations (cdecl) may cause an unbalanced stack (or worse) when called as though it had a stdcall convention, which is the method recognized by WINAPI (windows system) calls.

July 19, 02:33 PM

While your sample data is not strictly valid JSON, your attempt to parse it was pretty close.

The layout that you're seeing is sometimes used by some parties who believe that the size of their result sets could be improved (decreased) by aliasing the field names. Unfortunately it isn't as straightforward to work with this, but you can pivot the items back into objects.

My preference in these cases is to use the dynamic keyword and ExpandoObjects. You can use a class if you like, as the bulk of the work of creating an object happens in the final Select() below and you can rewrite it to map the v element sets into fields of a class instead of an ExpandoObject. The syntax to access a field is the same, as you can see by the snippet at the end that writes all the values to the Console.

Note that I've written a helper lambda to handle the case of mapping Date() into DateTime(). I'm just pointing this out as you may have a better place to put this method (an extension method on DateTime, perhaps); but there's no harm in copying and pasting it as-is into a suitable place your code.

using System.Dynamic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

// ... other code removed

// You already have a means that loads your pseudo-json into results
// I used a file for the sake of this example
string results = File.ReadAllText(@"C:\temp\sample.json");

var o = JObject.Parse(results);
var headers = o.SelectToken("cols")
    .Select(x => { return new { label = x.SelectToken("label").Value<string>(), type = x.SelectToken("type").Value<string>()}; }).ToArray();
var rows = o.SelectToken("rows").Select(s => { return s.SelectToken("c");}).ToList();

Func<JConstructor, DateTime> MapAsDateTime = (s) =>
{
    // This is sloppy on my part, you should improve this as you like.
    List<int> v = new List<int>();
    foreach (JToken t in s)
    {
        v.Add(t.Value<int>());
    }
    return new DateTime(v[0], v[1], v[2], v[3], v[4], v[5]);
};

IEnumerable<dynamic> finalValues = rows.Select(s =>
    {
        var innerValues = s.ToList().Select(x => { return x.SelectToken("v"); }).ToArray();
        int i = 0;
        dynamic val = new ExpandoObject();
        IDictionary<string, object> valueMap = (IDictionary<string, object>)val;
        foreach (var innerValue in innerValues)
        {
            switch (headers[i].type)
            {
                case "string":
                    // NOTE: This can be improved, you could try to match and convert GUIDs with a regex or something else.
                    valueMap[headers[i].label] = innerValue.Value<string>();
                    break;
                case "datetime":
                    valueMap[headers[i].label] = MapAsDateTime((JConstructor)innerValue);
                    break;
                case "number":
                    // NOTE: This can be improved, your specific case needs decimal to handle things like 0.25, but many others could get by with just int
                    valueMap[headers[i].label] = innerValue.Value<decimal>();
                    break;
                case "boolean":
                    valueMap[headers[i].label] = innerValue.Value<bool>();
                    break;
                default:
                    // NOTE: You will need to add more cases if they 'define' more types.
                    throw new ArgumentException(string.Format("unhandled type \"{0}\" found in schema headers.", headers[i].type));
            }
            i++;
        }
        return val;
    });

foreach (dynamic d in finalValues)
{
    Console.WriteLine("name: {0}", d.name);
    Console.WriteLine("caller_id_number: {0}", d.caller_id_number);
    Console.WriteLine("destination_number: {0}", d.destination_number);
    Console.WriteLine("call_start: {0}", d.call_start);
    Console.WriteLine("duration: {0}", d.duration);
    Console.WriteLine("bill_seconds: {0}", d.bill_seconds);
    Console.WriteLine("uuid: {0}", d.uuid);
    Console.WriteLine("call_bill_total: {0}", d.call_bill_total);
    Console.WriteLine("recorded: {0}", d.recorded);
    Console.WriteLine("--");
}

And finally, the sample output for the very first unit of data in your sample.

name: mydomain.com
caller_id_number: 1650
destination_number: 01902321654
call_start: 6/19/2011 2:12:25 PM
duration: 3
bill_seconds: 0
uuid: 07752f6c-b203-11e0-92e6-495a2db86d6d
call_bill_total: 0
recorded: True
--
June 28, 06:56 PM

TCP is a streaming protocol, so you will always receive whatever data has arrived since the last read, up to the streaming window size on the recipient's end. This buffer can be filled with data received from multiple packets of any given size sent by the sender.

TCP Receive Window Size and Scaling @ MSDN

Although you have observed 1 unified blob of data containing 2 bytes on the receiving end in your example, it is possible to receive sequences of 1 byte by 1 byte (as sent by your sender) depending on network conditions, as well as many possible combinations of 0, 1, and 2 byte reads if you are doing non-blocking reads. When debugging on a typical uncongested LAN or a loopback setup, you will almost never see this if there is no delay on the sending side. There are ways, at lower levels of the network stack, to detect per-packet transmission but they're not used in typical TCP programming and are out of application scope.

If you switch to UDP, then every packet will be received as it was sent, which would match your expectations. This may suit you better, but keep in mind that UDP has no delivery promises and network routing may cause packets to be delivered out of order.

You should look into delimiting your data or finding some other method to detect when you have reached the end of a unit of data as defined by your application, and stick with TCP.

May 31, 03:09 PM

They're somewhat the same. LRESULT is intended to be a return value type that can hold something at least the size of a pointer on a given platform.

From Windows Data Types (Windows)

LRESULT:
Signed result of message processing.
This type is declared in WinDef.h as follows:

typedef LONG_PTR LRESULT;

LONG_PTR:
A signed long type for pointer precision. Use when casting a pointer to a long to perform pointer arithmetic.
This type is declared in <BaseTsd.h> as follows:

#if defined(_WIN64)
 typedef __int64 LONG_PTR; 
#else
 typedef long LONG_PTR;
#endif

The LRESULT type has gone through a number of changes over the years. I believe prior to Win64, it was defined as INT_PTR, but then updated for portability under Win64. A number of other types went through similar changes, such as WPARAM and LPARAM, which used to be 16 bit values in Win16, are 32 bit values in Win32, and are now 64 bit in Win64.

The actual value returned varies depending on the windows message context, as @ildjarn pointed out. There's also a chance the example source that you're reading was probably created before Win64 became a big deal, and may not have been updated or checked for portability since it was written.

For portability, the symbols are defined slightly differently depending on compile target. Hence, (INT_PTR)TRUE is better even if you know the exact value that should be returned that happens to match your build. While return 0; may return the correct result in cases where the return value is empty, this is bad form when compiling under scenarios where portability matters. Using return -1; or even return 0x7FFFFFFF; is even worse, as you may truncate, mask, or otherwise mangle the response that should be given for all platform compile targets.

Using the predefined symbols and constants is best, as the correct values and types will be substituted in for you as you change your compile targets.

April 21, 07:02 PM

Unfortunately, the behavior you're describing is not possible for Atom Tables. This is because Atom Tables in Windows are basically Hash Tables, and the mapping process handles strings in entirety and not by parts.

Of course, it almost sounds like it would be possible, as quoted from the MSDN documentation:

Applications can also use local atom tables to save time when searching for a particular string. To perform a search, an application need only place the search string in the atom table and compare the resulting atom with the atoms in the relevant structures. Comparing atoms is typically faster than comparing strings.

However, they are referring to exact matches. This limitation probably seems dated compared to what is possible with resources currently available to software. However, Atoms have been available as far back as Win16 and in those times, this facility allowed a means for applications to manage string data effectively in minimal memory. Atoms are still used now to manage window class names, and still provide decent benefits in reducing the footprint of multiple stored copies of strings.

If you need to store string data efficiently and to be able to scan by partial starting matches, a Suffix Tree is likely to meet or exceed your needs.

April 13, 05:56 AM

Looks like output parameters are not supported; while ByRef / [in, out] parameters are, but only on VARIANT parameters.

From the following KB article:

INFO: Type mismatch errors when you pass parameters from an ASP component to Visual Basic Component @ support.microsoft.com

"VBScript only supports VARIANT ByRef parameters. You can use VBScript to call a procedure that takes ByRef strings, but the default behavior of components built with Visual Basic is to fail with a type mismatch error when trying to pass ByRef parameters to these components. OLE Automation's default type-coercion function fails when asked to convert a ByRef variant into any other ByRef type."

Also, here are other links on the topic:

In, Out, In-Out, Make up your mind Already @ MSDN blogs
VBScript “Type Mismatch” issue with “[in, out] BSTR * ” parameter SO Question

April 13, 05:39 AM

It looks like you may have stumbled upon an error code (STATUS_GRAPHICS_DRIVER_MISMATCH) that is defined incorrectly in available documentation (see NTSTATUS values, shown as 0x401E0117); but it exists in the header file <ntstatus.h> in the Windows Platform SDK and matches your value.

My installed copy of the Windows SDK (v7.0, Windows 7 / .NET 3.5sp1) describes it as follows (line 13743):

//
// MessageId: STATUS_GRAPHICS_DRIVER_MISMATCH
//
// MessageText:
//
// The kernel driver detected a version mismatch between it and the user mode driver.
//
#define STATUS_GRAPHICS_DRIVER_MISMATCH  ((NTSTATUS)0xC01E0009L)

Other D3D functions have this symbol listed but not the value. Here are links to the documentation, along with the quoted text.

DxgkDdiOpenAllocation @ MSDN
STATUS_GRAPHICS_DRIVER_MISMATCH - "The display miniport driver is not compatible with the user-mode display driver that initiated the call to DxgkDdiOpenAllocation (that is, supplied private data to the display miniport driver)."

DxgkDdiCreateAllocation @ MSDN
STATUS_GRAPHICS_DRIVER_MISMATCH - "The display miniport driver is not compatible with the user-mode display driver that initiated the call to DxgkDdiCreateAllocation."

April 13, 04:58 AM

The Socket class has the Handle property, which could be used.

Socket.Handle @ MSDN

I was skeptical about whether this would work, but I was able to get it to work with no fuss at all.

To start, I made an unmanaged C++ dll to export a single function that can do something with a socket. Here's the function I created.

#include <WinSock.h>

// This is an example of an exported function.
extern "C" __declspec(dllexport) void __stdcall DoStuffWithSocket(DWORD sock)
{
  const char *data = "woot\r\n";
  send((SOCKET)sock, data, strlen(data), 0);
}

The project outputs a dll named UnmanagedSocketHandler.dll, which is the library mentioned in the P/Invoke signature in the next snippet.

Here's a quick and dirty C# console app to call that function as a Server.

using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;

namespace SocketHandleShareTest
{
    class Program
    {
        static void Main(string[] args)
        {
            IPEndPoint ep = new IPEndPoint(IPAddress.Any, 5353);
            Socket sListen = new Socket(AddressFamily.InterNetwork, 
                                        SocketType.Stream, ProtocolType.Tcp);
            sListen.Bind(ep);
            sListen.Listen(10);
            Socket sClient = sListen.Accept();
            Console.WriteLine("DoStuffWithSocket() enter");
            Console.ReadLine();
            DoStuffWithSocket(sClient.Handle);
            Console.WriteLine("DoStuffWithSocket() exit");
            Console.ReadLine();
            sClient.Close();
            sListen.Close();
            Console.WriteLine("Done.");
            Console.ReadLine();
        }

        [DllImport("UnmanagedSocketHandler.dll")]
        static extern void DoStuffWithSocket(IntPtr sock);
    }
}    

Last, a quick and dirty C# client app to talk to the server. I was unable to find any documentation on why this works, but it works. I'd be wary about what you try to do with the socket.

using System.Net;
using System.Net.Sockets;

namespace SocketHandleShareTestClient
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] buf = new byte[40];
            Socket s = new Socket(AddressFamily.InterNetwork,
                                  SocketType.Stream, ProtocolType.IP);
            s.Connect("localhost", 5353);
            int len = s.Receive(buf);
            Console.WriteLine("{0} bytes read.", len);
            if (len > 0)
            {
                string data = Encoding.ASCII.GetString(buf, 0, len);
                Console.WriteLine(data);
            }
            s.Close();
            Console.ReadLine();
        }
    }
}
April 12, 07:32 PM

Twitter doesn't allow basic Auth (username+password) logins through their API anymore.

You should look for a method that supports OAuth-based login.

You'll need to fetch OAuth keys for your application, which can be done from the following links. The first link allows you to enroll a new application, the second one allows you to see what applications you've registered.

New Twitter Application @ dev.twitter.com
Twitter Applications (Existing) @ dev.twitter.com

A more in-depth guide is available at the following link. You will want to read this as OAuth requires at least two steps to authenticate before you can use the twitter API.

Authenticating Requests with OAuth

April 11, 07:06 PM

There's two ways of handling them without knowing the contents at runtime.

The first way is to use JSON.Net's JObject, which will handle the case you've mentioned, plus hierarchies.

The second way is to use System.Dynamic's ExpandoObject, which is newly supported by recent releases of JSON.Net. Unfortunately it doesn't quite handle hierarchies, but JSON.Net falls back onto JObject to support them when encountered. For your purposes, it might be more straightforward.

Here's an example with the snippet and definitions you've given. Also note that ExpandoObject is directly castable to IDictionary<string, object>, whereas JObject has explicit methods to access properties.

Person corresponds to ExpandoObject, and JPerson corresponds to JObject.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Dynamic;

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;

namespace YourFavoriteNamespace
{
    public class JPerson
    {
        public string FNAME;
        public string LNAME;
        public BodyType bodyType;
        public JObject belongings;
        public JObject signs;
    }

    public class Person
    {
        public string FNAME;
        public string LNAME;
        public BodyType bodyType;
        public ExpandoObject belongings;
        public ExpandoObject signs;
    }

    public class BodyType
    {
        public int height;
        public int weight;
        public string race;
        public string hair;
    }

    class Program
    {
        static void DumpDynamic(dynamic d)
        {
            IDictionary<string, object> dynMap = (IDictionary<string, object>)d;
            foreach (string key in dynMap.Keys)
            {
                Console.WriteLine("  {0}={1} (type {2})", key, dynMap[key], null == dynMap[key] ? "null" : dynMap[key].GetType().Name);
            }
        }

        static void DumpJProperties(JObject jo)
        {
            var props = jo.Properties();
            foreach (JProperty prop in props)
            {
                Console.WriteLine("  {0}={1} (type {2})", prop.Name, prop.Value, null == prop.Value ? "null" : prop.Value.GetType().Name);
            }
        }

        static void DumpPerson(Person p)
        {
            Console.WriteLine("Person");
            Console.WriteLine("  FNAME={0}", p.FNAME);
            Console.WriteLine("  LNAME={0}", p.LNAME);
            Console.WriteLine("Person.BodyType");
            Console.WriteLine("  height={0}", p.bodyType.height);
            Console.WriteLine("  weight={0}", p.bodyType.weight);
            Console.WriteLine("  race  ={0}", p.bodyType.race);
            Console.WriteLine("  hair  ={0}", p.bodyType.hair);
            Console.WriteLine("Person.belongings");
            DumpDynamic(p.belongings);
            Console.WriteLine("Person.signs");
            DumpDynamic(p.signs);
        }

        static void DumpJPerson(JPerson p)
        {
            Console.WriteLine("Person");
            Console.WriteLine("  FNAME={0}", p.FNAME);
            Console.WriteLine("  LNAME={0}", p.LNAME);
            Console.WriteLine("Person.BodyType");
            Console.WriteLine("  height={0}", p.bodyType.height);
            Console.WriteLine("  weight={0}", p.bodyType.weight);
            Console.WriteLine("  race  ={0}", p.bodyType.race);
            Console.WriteLine("  hair  ={0}", p.bodyType.hair);
            Console.WriteLine("Person.belongings");
            DumpJProperties(p.belongings);
            Console.WriteLine("Person.signs");
            DumpJProperties(p.signs);
        }

        static void DoSimplePerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":\"dorky\"}}";
            Person p = JsonConvert.DeserializeObject<Person>(initJson);
            DumpPerson(p);
            Console.ReadLine();
        }

        static void DoComplexPerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":[\"dorky\",\"hipster\"]}}";
            Person p = JsonConvert.DeserializeObject<Person>(initJson);
            DumpPerson(p);
            Console.ReadLine();
        }

        static void DoJPerson()
        {
            string initJson = "{\"FNAME\":\"joe\",\"LNAME\":\"doe\",\"BodyType\":{\"height\":180,\"weight\":\"200\",\"race\":\"white\",\"hair\":\"black\"},\"BELONGINGS\":{\"shirt\":\"black\",\"Money\":15,\"randomThing\":\"anyvar\"},\"Signs\":{\"tattoo\":0,\"scar\":\"forehead\",\"glasses\":\"dorky\"}}";
            JPerson p = JsonConvert.DeserializeObject<JPerson>(initJson);
            DumpJPerson(p);
            Console.ReadLine();
        }

        static void Main(string[] args)
        {
            DoSimplePerson();
            DoComplexPerson();
            DoJPerson();
        }
    }
}
April 06, 09:33 PM

Shared Memory is available as a data transport to and from SQL providers. You don't have to write any additional code for this if you are using built-in drivers to access your provider. Instead, you would just configure the driver and the server to use this, and your application would have to reside on the same server as your SQL provider.

The ODBC drivers available for windows support shared memory for SQL activities. To write code for these from C, you would use the ODBC API to communicate with your provider. Here's a link with a function reference.

ODBC Function Summary @ MSDN

Also note that there is support for BLOBs for all SQL providers that can handle arbitrary binary data. A list of the types known to ODBC API is available here. There's no strict requirement that your statement results must be expressible in tabular form.

SQL Data Types @ MSDN

On the other hand, if are concerned about communicating with internal SQL entities on your own terms, you might be able to patch something together via extensions to the SQL service you are using. For example, MS SQL Server allows extensions via Ole Automation Procedures or CLR (.net) Integration (available in MS SQL Server). You could potentially use these make something to communicate out-of-band. However, neither of these is easily created with a pure C solution.

Ole Automation Procedures in SQL Server @ MSDN

CLR Integration in SQL Server @ MSDN

However, I recommend that you avoid doing this, as you will find that you're at the mercy of the environment of the host service and you may not be able to participate in transactions.

If your dataset size requirements are so large that you consider RAM and direct access your best option, your needs would probably be better fulfilled by communicating only the parts that change in the dataset held outside of SQL. In addition, as a shared-memory solution is restricted to one machine, you would probably want to consider splitting the work on your dataset across multiple machines. It is more likely that you would see a performance/productivity improvement by such means than by changing how you reference data in SQL.

Last, it is tough to dictate to a SQL provider that it should avoid using filesystem storage. For MS SQL Server, one possible option is to force tempdb to reside in RAM. Here's a KB article with more details. Other DBMSs may have similar configuration options.

INF: When to use tempdb in RAM

However, the use of disk storage isn't necessarily a cause for concern. I'm unable to find a good example of how SQL providers manage a RAM / Filesystem balance, but one good analogue for SQL server is how windows is affected by page-file use. Here's a great link that details how windows behaves at high limits of operation, and how memory use doesn't necessarily correspond into overflow to disk use. Also note that applications written to run on windows are also adversely affected when the host's operation approaches these limits.

Pushing the Limits of Windows: Virtual Memory @ TechNet

March 09, 11:18 PM

If you are only doing scraping and requests, you would probably be best off using the WebRequest object that ships with .NET to do your work.

WebRequest Class @ MSDN

However, if you must have exact access to what is represented in the IE DOM, you should use Microsoft Active Accessibility to gain access. Provided you can identify the window handle or reliable location for the target IE window, and it is visible in a user session, Active Accessibility is the best way to access the target IE window and dig into the DOM. It isn't absolutely necessary to use C++, but it will probably be easier to do most of this in C++.

Active Accessibility User Interface Services @ MSDN

You'll want to use EnumChildWindows to locate (or brute force query) the DOM window either from the desktop or a frame window's handle retrieved from enumerating processes. In .NET, enumeration of processes is available from the System.Process class.

EnumChildWindows @ MSDN

EnumWindows signature @ pinvoke.net
EnumChildWindows signature @ pinvoke.net

Process.GetProcesses() @ MSDN
Process.MainWindowHandle @ MSDN

To add the type declarations you need to be able to walk the DOM in C# and to talk to MSAA, add a COM reference to 'Microsoft HTML Object Library' to your project, and add P/Invoke signatures for MSAA.

AccessibleObjectFromWindow Signature @ pinvoke.net

Once you can call MSAA, retrieve an IDispatch through Active Accessibility from the window handle. You will want to send in OBJID_NATIVEOM, which will get you an IDispatch you can interrogate.

Retrieving an IAccessible Object @ MSDN
AccessibleObjectFromWindow() @ MSDN

From here, IDispatch may be cast to IHTMLWindow2 or IHTMLDocument2 (and derivatives), which has all of the DOM script model methods and more. Unfortunately I can't remember which one is returned via this method, but in any case, IHTMLWindow2 has the document property (same as window.document in script). Either can be resolved to provide access to the DOM, which is represented by IHTMLDocument2 and all derived interfaces.

March 09, 10:32 PM

Provided your target window is following the standard method to update its caption, you can add a hook to catch the precise moment when the caption has changed.

To do this, you will need to add a windows message return hook with SetWindowsHookEx, passing it a CallWndRetProc handler from your code to receive notices upon completion of windows messages by the target window's message handler.

SetWindowsHookEx() @ MSDN
CallWndRetProc @ MSDN

The windows message you need to trap is WM_SETTEXT, which is sent to trigger the change in the default text/caption for a window.

WM_SETTEXT @ MSDN

If you would like to test this in isolation, WM_SETTEXT is an implicit message sent upon calling SetWindowText to change the window text/caption.

SetWindowText() @ MSDN

Also, you might also be able to get rid of your cbt hook, as WM_ACTIVATE, WM_MOUSEACTIVATE, and WM_SETFOCUS can be trapped with the same hook used to trap WM_SETTEXT. These messages cover various levels of activation activity and type for windows.

WM_ACTIVATE @ MSDN
WM_MOUSEACTIVATE @ MSDN
WM_SETFOCUS @ MSDN

Last, if the target window is a window you create and control in your own process, you could simply intercept those windows messages instead of using hooks. If it is impossible to use your available frameworks to intercept those messages, SetClassLongPtr is also another alternative, which may be used to implement a subclass for that type of window to allow you to intercept window messages. If you use this method, you would delegate all calls to the original windows message handler, and only act during a return from the original procedure upon receiving a message of interest.

SetClassLongPtr() @ MSDN
WindowProc @ MSDN

March 04, 08:08 PM

Database projects in Visual Studio have the features that you need. You can do schema comparisons to keep track of the differences between schema versions. They can also handle deployment, although your deployment needs may differ.

Database Projects @ MSDN

There are also other 3rd party tools that may be used as well, such as SQL Compare by Redgate.

SQL Compare by Redgate

Added:

Unfortunately, neither of these has intrinsic support for git. But, this wouldn't prevent you from bridging the gap if you don't mind doing most of the work yourself.

With Visual Studio, you can use MSBuild to automatically run scripts/executables associated with compile actions. From there, you could attach your own interactions with git.

MSBuild Reference @ MSDN

If you're looking for a tool that can automatically deploy a schema change from git, I don't know of any that exist at this time; but you could roll your own using SMO. It has all the functionality you need to be able to script SQL Server objects and execute scripts against SQL Server. You will probably have to do your own incremental scripts for table changes (as a matter of safety), but you could do drop/replace for many other objects that aren't data (Stored Procedures, User Functions, etc.).

SQL Server Management Objects @ MSDN

March 04, 07:48 PM

It sounds like PLINQ (available in .NET 4.0) has most of the parts that you would like for your solution.

Parallel LINQ @ MSDN

In particular, the place to start trying out prototypes would be the ForAll() extension method. This method can be used to perform a unit of work or task over all the items in an enumerable collection, over parallel threads.

ParallelEnumerable @ MSDN
ParallelEnumerable.ForAll() Method @ MSDN

For the flow that you're describing, you might find it useful to create an enumerator that can provide items one at a time. The C# yield return statement can be used in a method to provide an enumerable list. This can then be made into a ParallelEnumerable via the AsParallel() extension method.

yield (C#) Reference @ MSDN
ParallelEnumerable.AsParallel() @ MSDN

From there, the rest of the work is determining how to partition your transformations along the processing boundaries that you need. You can also use regular enumeration / foreach to iterate work in those places where you feel parallelism is not necessary.

You may find that you wish to tweak the number of threads used in a parallel query. The WithDegreeOfParallelism() extension method can be used to adjust how many threads are created for your work/query.

ParallelEnumerable.WithDegreeOfParallelism() @ MSDN

There may be places in your flow where you need to manipulate sets of data during parallel work. Use concurrent collections from System.Collections.Concurrent to maintain orderly access to those sets of data.

Thread-Safe Collections @ MSDN

Last, if you need even greater separation of duties, you may also wish to consider modeling and building your transformations in WF (Workflow Foundation).

Windows Workflow Foundation Intro @ MSDN

Added:

If you are positive that you don't want to use existing .net facilities for your design; you'll probably want to start modeling at a higher level of abstraction. Given that you've mentioned that you may wish to port to Java, I recommend you consider reading about the Producer::Consumer Communication model. From there, you can decide where to break up your transformation and Input/Output boundaries and work on individual parts based on lower-level primitives.

Other Producer / Consumer Questions on Stack Overflow

Also, you may wish to implement a cascade of work queues for your work flow. I don't know of very many existing solutions that are available to both .NET and java consumers; but reading up on other message queue solutions may give you some good ideas. Amazon SQS is a cloud-based one that comes to mind, and MSMQ (and derivative works) has been a solid available service on windows since Windows 2000.

Amazon Simple Queue Service @ AWS
MSMQ (Microsoft Messaging Queue) @ MSDN
Build a Queued WCF Response Service @ MSDN Magazine

April 11, 08:19 PM

One could write a custom tokenizer for Lucene that emits tokens to be indexed based upon the reverse of each token, just the suffix fragments, or special sentinel fragments (if it is necessary to specifically handle s____s and similar wildcards. ex. word -> w~d, letter -> l~r; then alter a query against the index to look for s____s via indexed s~s).

April 03, 11:38 PM

+1 for mentioning connection string synonyms

March 07, 03:27 PM

there is a toolbar for firefox called "Operator" that can help you inspect pages for some of the more common uf patterns. addons.mozilla.org/en-US/firefox/addon/operator

March 06, 07:50 PM

Per pezcode's note on my answer, it would help if you could post stack traces from breakpoints set at the places where you need to insert a MessageBox(), both from Debug builds and Release builds. This would help paint a clearer picture for us without requiring you to post a lot of code.

March 06, 07:45 PM

There shouldn't be any appreciable difference in running debug or release; I can only infer based upon what we know MessageBox() does that causes the symptoms to go away. We could also speculate that there is an additional detail that has been overlooked, such as debug ASSERT()s or other debug-specific code that also implicitly causes messages to be pumped. I will ask the Op to post stack traces; as these are probably the most useful bits of information that can help diagnose this without requiring a deep inspection of code.

March 01, 06:07 PM

Those timers could block the UI thread if calling his polling operation from those timers could block for any notable amount of time.

February 24, 09:24 PM

The parameter slot specified with byOut is to receive data back from the IOControl feature selected. In the case of SIO_RCVALL, no special return data is expected (see the notes for lpvOutBuffer on the SIO_RCVALL link). You may be able to pass an empty array or possibly even null.

February 21, 01:24 PM

You have square brackets around the single item returned; are you deserializing into type report_suite_metrics[] or report_suite_metrics? The former should work, the latter will give you the error you are seeing.

January 26, 03:10 PM

If you're testing against a windows machine; you should note that connection behavior will change if your scan triggers SYN flood protection. See: msdn.microsoft.com/en-us/library/ff648853.aspx and technet.microsoft.com/en-us/library/cc759239%28WS.10%29.aspx

November 21, 03:37 PM

Also note that Monikers are based upon named parts that are meaningful only to the provider of a Moniker. It's pretty convenient to register with a GUID because they're generally unique, but doing this doesn't prevent someone else from trying to register a name that has a part that contains the same GUID.

November 21, 03:34 PM

The exception occuring at .GetDisplayName() is exactly what makes me suspicious of other foreign objects in the ROT. The ROT is a shared resource, so any application that wishes to use it can place objects there. You can observe this in action by launching MS Word or MS Excel and noting the presence of their open Documents in the ROT. Another angle of attack is to make a test program to dump the GUIDs in the ROT while running as an account with administrator rights. This could provide extra clues. A GUID collision would fail elsewhere, not in the sample you've provided.

November 21, 01:59 PM

This is a speculative guess, but given that only 3 out of 39,000 have observed this issue, it seems more likely that the exception is caused by a 3rd party component that is registered in the ROT, perhaps as another identity other than the logged-in user. Your code looks fine to me. Can you get a list of running processes and installed software from those customers?

July 21, 01:07 PM

+1 for good link on handling this in .NET

Posts

The folks at Ch9 have just released (today) a video announcing details on a computing appliance for Azure.

Some time ago, when Azure was first announced, I spoke with a number of colleagues about whether this would work out for Microsoft. There seemed to be some trepidation about whether it would be worth targeting Azure, as it is essentially a new OS and platform to support.

I felt it had some merit, until I looked at the cost. Ouch. The only competitor with higher operating cost was Amazon. But, it does allow most windows developers to continute to write code to something familiar. Perhaps if it were possible to host Azure on-site, this would have a lot of value to developers.

One thing that isn’t mentioned in the video on Ch9, is how the Azure box will be setup. I don’t think people will settle for single units. Also, it would be huge if the boxes can be scaled horizontally by merely adding more to a group and deploying (within reasonable limits).

I can definitely see some of these being purchased for testing purposes, if the price of the box is low enough. It seems debatable whether local use is also worthwhile against the compute/traffic cost.

Finally, the failover abstraction may be lost if one does switch to local hosting. This may not be a big deal for people who are wary of things such as PCI/PABP compliance; as they have a lot of hurdles to conquer to be able to use cloud hosting. But, some of those who actually need the abstraction over any other benefits may fool themselves into thinking they don’t. The number of nines of uptime possible with a local solution remains to be seen.

Adventures in OAuth Echo with twitpic

Sometime this summer, use of Basic Authentication with the twitter API will be coming to an end. During the transition period, all of the third-party services that delegate calls have to stop using Basic Auth and will now have to use OAuth Echo for authorization.

Fortunately, OAuth Echo is pretty straightforward, with two catches that aren’t initially obvious but trivial to overcome. For reference, here is a link to the documentation of twitpic’s upload method.

http://dev.twitpic.com/docs/2/upload/

The two required headers are X-Verify-Credentials-Authorization and X-Auth-Service-Provider. The verify-credentials header is the same as a properly signed Authorization header pointed at the auth-service endpoint at twitter.

Herein lies the first snag that caught me. The current value used by twitpic is the following (not a clickable link):

https://api.twitter.com/1/account/verify_credentials.json

When signing the string for OAuth Echo, the URL you send in should be this, not the endpoint for twitpic (not https://api.twitpic.com/2/upload.json ).

The second snag that caught me was the HTTP method call. Calls to verify_credentials at twitter are GET, but calls to upload at twitpic are POST. The generated OAuth signature should use GET.

At first this didn’t make sense to me, but after some muddling about, I realize that this is about the easiest way for twitter’s third parties to be delegated control over a single call. The OAuth signature ensures that the only thing they can do at twitter is lookup credentials, and the middleman (twitpic) already has the work of generating the signature done for them by the client. The only thing that twitpic or others would have to do is copy the verify-credentials header into the authorization header when making the checkup call to twitter.

This is hardly just the first chapter, though, in what I expect will be further adventures in OAuth. The other, more important, API call at twitpic is the uploadAndPost call. This call, I speculate, is the root of where a ton of their homefront traffic is eventually generated. Right now, there is no equivalent OAuth Echo procedure that can allow twitpic to post to twitter. I’d imagine it isn’t too much effort (if any at all) to allow the twitter update-status method to be the target of the auth-service provider.

Some possible hijinks stand out with that particular method. One, is that the delegate may not necessarily be 100% trusted. Since the signer has already created a valid access token, the delegate could post content as it sees fit for that one call. It is unlikely anyone would do this, as that would open up a breach in trust, possibly causing them to lose access to twitter. There are some high-follow accounts where it may be worth it to a malicious insider to attempt this once, though.

Another potential issue is in error handling. Because a delegate is being used, the caller may be misinformed in a number of scenarios. The first is if twitter reports an error but succeeds, causing the delegate to report an error on the relayed call. The second is if the delegate fails internally after a call to twitter, leaving the potential result completely unknown to the caller. In recent times, under load, there have been gateway errors reported by twitter while API calls were actually succeeding; fortunately there were only two nights (that I recall) where this resulted in double-posts.

Last, it is unknown whether it will be possible to delegate by a single call to cover cases where the delegate needs to make several calls to the twitter api in a single unit of work. This will probably open up a number of questions as to whose API limit pays for the calls. I haven’t checked the results of rate-limit-headers yet, but I would guess that the client’s tally pays for the expense. This may not be good for delegates if they are performing tasks that might significantly cut into the caller’s hourly limit, which might make some clients wary of using their services.

My best friend, who is also a developer/engineer, asked me today if there were any VS add-ons that I’d ever dreamed of creating.

Well, to be honest, I’ve spent a lot of time in the past, writhing and bitter over broken Macro projects that no longer worked between versions of Visual Studio. And thus, given up on trying to extend the environment to suit me. One thing, though, stands out as something that I think would be useful. I’ve always wanted to be able to right-click on any project/file/solution item; and go to the physical location where that item is stored.

My friend feels this is useful as well. But, he warned, what about the case of temporary projects?

Whoa, hold the presses, temporary projects?

A little bit of digging, and sure enough, temporary projects that may be thrown away are a new feature in VS2010.

I have some reservations about this feature. It isn’t that much work to make a throwaway project. Also, I usually have an extra prototype-only solution open that I use for reference. Not really impressed, here.

Well, as they say, a rising tide lifts all boats. Maybe it is just too hard to preach a good workflow to the developer masses. I’m sure there are many things that I’ve missed out on; but I do try to keep my eyes and ears open to new things that make me better. My friend and I agree, though, that sometimes there is too much effort spent on features that demo well; but haven’t added real value to those who get things done.

Someday, I hope my VS plugin exists, whether via add-on or native integration. I think I would pay for someone else to make it for me, too. I also think people would find it useful, when importing files extraneous to VS; like unit test-case data.

partial (methods) in .NET

I’ve been working on writing a library that provides functionality using fluent syntax, as a practice exercise. During the course of mapping an existing prototype into the syntax, I came across a rather bizarre bit of .NET language functionality.

In .NET, it is well known by now to any ASP.NET or Forms developer that you can have partial classes, where the body of the class’s source is split up among a number of locations. Similarly, an interface and structure may be declared using the partial keyword with the same segmentation as well.

In C# 3.0, lesser known, is the fact that you may also declare partial methods, where the body is defined in one place, and the declaration in another. These appear to act as forward declarations in C/C++. But in .NET they are restricted, as any partial method must return void.

This seems strange to me, but in digging through some articles written by other people, it became clear the body of the function doesn’t necessarily need to be defined. How bizarre. But, with this capability, things make sense. These partial methods now become optional- if an implementation exists, it will be called. If not, then they won’t. One of the blog articles I read, points out that this is similar to how conditional methods are supported.

http://bartdesmet.net/blogs/bart/archive/2007/07/28/c-3-0-partial-methods-what-why-and-how.aspx

Partial methods must return void because no action occurs if there is no body, and no return value can exist if there is no implementation.

In all, this is a rather curious thing, but I think this has some decent uses. The first thing that comes to mind is the creation of logging stubs. If the logging methods are present, they get called. If not, then no action. I don’t know if this is necessarily better than conditional compilation, but the ability to defer the actual handling would be nice. Separation of Concerns, as usual.

discovering more stuff in .net 4.0

Found a few more interesting things in the past week.

SortedSet - Sorted version of HashSet, which should allow you to do foreach() on items with a determinate order. Regarding LINQ, this is a good alternative to doing a Take() on the first N after a sortby, as you can avoid repeating the LINQ query over and over, especially if the taken portion is not necessarily the same amount each time, and if the data set is always the same group.

Here’s the link:
http://msdn.microsoft.com/en-us/library/dd412070.aspx (SortedSet)

System.Numerics - A namespace containing two new classes, BigInteger, and Complex (complex numbers).

BigInteger is .NET’s native arbitrary-precision integer class, while Complex is a complex number class (a + bi).

Here are the links to each:
http://msdn.microsoft.com/en-us/library/system.numerics.biginteger.aspx (BigInteger)
http://msdn.microsoft.com/en-us/library/system.numerics.complex.aspx (Complex)

Finally, parallel extensions to LINQ are pretty sweet. My current favorite is ForAll(), which significantly reduces the amount of code to run heavyweight processing of items on a list in parallel fashion. This is incredibly powerful, given that you can also write a lambda / anonymous method in place for the Action() parameter.

http://msdn.microsoft.com/en-us/library/dd383744.aspx (ParallelEnumerable.ForAll())

sometimes things are blindingly simple

Haven’t tested this out just yet, but it compiles, and while i’m sure there is a better way of doing this, I spent more time thinking about the implications than I did on writing the actual code.

Ready? Check this out.

public class ChannelMultiplex
{
  public static IEnumerable<Tuple<short, short>> MonoToStereo(IEnumerable<short> source)
  {
    foreach (short sample in source)
    {
      yield return new Tuple<short, short>(sample, sample);
    }
  }
}

Too easy, right? Of course, this probably isn’t going to run very fast. But nonetheless… I <3 you Tuple<>.

first three impressions of vs2010 and .NET 4.0

1. WPF Text rendering is gorgeous

2. VS2010 is pretty. Superfluous, but other than that, no complaints here.

3. DispatchTimer feels different. Seems that AppIdle priority really means when the application is idle, not when the message queue is empty. Had to adjust for this.

Also, I can’t really make any claim to this, but using ThreadPool feels different too.

I look forward to trying out the DLR languages as well.

This is not as accurate as putting a Stopwatch in your source code, but for quick and dirty profiling, good enough. I feel it is handy to be able to /abuse/use/ using() semantics for this scenario. I think this could also be improved by adding another constructor that takes a delegate to handle printing out the timer element; or perhaps a delegate to a given logging method of choice.

Syntax is straightforward.

using(new AutoTimer())
{
// do stuff here
}

using(new AutoTimer(“working in fn()”))
{
// stuff that allegedly is inside of fn()
}

One drawback is that the using() semantics become overhead even if you #ifdef away code for non-debug builds. I might be wrong about that, though. I’m sure someone with more knowledge than me can figure out a way for the using() block to be optimized away for a retail build.

quick and dirty converter that calls blip.fm’s api to pickup recent blips from a user.

some notes:

only plucks the most recent 25
embeds youtube players if the content was sourced from youtube
silverlight support redacted, as i was unable to source the xap from my domain and use it on flavors.me
individual song links on blip.fm are not documented, but the following URL layout works, replace USERNAME and BLIPID with respective items from the api
-> http://blip.fm/profile/USERNAME/blip/BLIPID
i used a stringbuilder because the output size is pretty small, and if the handler dies, i can still override the output and set the content type too.

REF: http://api.blip.fm/

see the results in action here: http://flavors.me/meklarian

port Processing to WPF/Silverlight?

I’ve been thinking… there really isn’t a metafile format out there for WPF or Silverlight. While Processing wouldn’t cover all the bases, it would certainly do enough to allow people to program meta-elements for the canvas tag.

Just a thought.

my fundamental theory of data

All things have representation.

There’s really nothing groundbreaking about it. However, if you keep this line in mind and close to your heart, all things are possible.

What is data?

Bytes.

What does it look like in memory?

00 01 02 03 04 05 … if you’re looking at bytewise hex values. Is it in endian order? Some bytes may be swapped about, if this is the case.

How do I get it from point A to point B?

Well, this depends. Here is where you need to remember a couple things.

Is it text? What is the character set? Is it numeric data? Is it arbitrary blobs?

Ultimately, all data is transferred with a wrapper of some kind.

In the old days, these wrappers were headers. Usually length, followed by data.

Now we have XML. JSON. All still wrappers.

Then there are wires. Serial cables. Ethernet. Internet.

Why does this matter?

This matters because no matter what programming language, what operating system, whatever computer is in use; to date, they all must store data in some form somewhere. Bytes. Formatting.

If you remember that all things are mere bytes, then you may start from anywhere by looking up what it should look like, how you can manipulate it, how you can transfer it, how you can display it.

hello world!

testing this out.

// this is some code.

Audio

Recent tracks

Top tracks

Posts

November 14, 02:21 AM

Exitmusic - "The Hours" (Official Video) ♫ blipped by meklarian



November 07, 11:57 PM

Taking Control - Eisley ♫ blipped by meklarian



November 06, 08:04 PM

El Ten Eleven - Every Direction is North ♫ blipped by meklarian



October 25, 01:31 AM

Luke Chable - Skyline Road (Original Mix) ♫ blipped by meklarian



October 20, 11:45 PM

The Decemberists - Calamity Song ♫ blipped by meklarian



October 19, 01:10 AM

Wild Nothing - Summer Holiday ♫ blipped by meklarian



October 15, 01:09 AM

Miles Davis & John Coltrane - Kind of blue ♫ blipped by meklarian

(blue in green)

October 14, 11:53 PM

Ra Ra Riot - Each Year ♫ blipped by meklarian



October 11, 01:48 AM

The War on Drugs - "Come to the City" (Official Video) ♫ blipped by meklarian

via [reply]idlewild577[/reply]

October 10, 02:51 AM

- Diagrams 'Antelope' ♫ blipped by meklarian



October 07, 01:47 AM

- The Octopus Project- Hallucinists ♫ blipped by meklarian



September 16, 11:46 PM

- Looking for Astronauts, The National ♫ blipped by meklarian



September 15, 04:35 AM

Vetiver - More Of This / 7 ♫ blipped by meklarian



June 24, 03:28 AM

Nina Semone - I Shall Be Released - garlandgrey ♫ blipped by meklarian

via [reply]bildungsroman[/reply]: "Nina Simone singing Dylan. Beautiful."

June 04, 03:28 AM

Arcade Fire - The Suburbs ♫ blipped by meklarian

May 28, 10:42 PM

Pepper Rabbit - Harvest Moon ♫ blipped by meklarian

via [reply]orangekittypie[/reply]

May 28, 10:28 PM

Film School - Heart Full Of Pentagons ♫ blipped by meklarian

via [reply]orangekittypie[/reply]

May 28, 02:34 AM

- Nicola Conte: Jazz Pour Dadine ♫ blipped by meklarian



May 13, 01:24 AM

The Last Shadow Puppets - My Mistakes Were Made For You ♫ blipped by meklarian



May 13, 01:07 AM

Young The Giant - Apartment ♫ blipped by meklarian



May 13, 12:58 AM

noofficialmusic - Black Gold by Foals ♫ blipped by meklarian

April 24, 07:01 AM

Neko Case - Star Witness ♫ blipped by meklarian

April 23, 04:06 AM

Muse - Starlight ♫ blipped by meklarian

April 22, 01:37 AM

The Shins - Australia ♫ blipped by meklarian

April 19, 09:55 PM

Generationals - Ten-Twenty-Ten ♫ blipped by meklarian

via [reply]orangekittypie[/reply]

Posts

January 08, 02:20 PM

paul_shinn: @Colleen_Clark Thank you. And thank you for the cupcakes!

December 15, 01:02 AM

paul_shinn: Today I have discovered it is possible to stir fry kumquats. Pretty good.

November 22, 03:04 PM

paul_shinn: @crumbpeople @steenyweeny here is one i have on file. my pencil giraffes are better.

October 27, 02:48 AM

paul_shinn:

October 17, 08:48 PM

paul_shinn: @alsocan the apple t-shirt arrived today and it is awesome :) going to wear it tomorrow. (spider one is awesome too)

October 15, 06:44 PM

paul_shinn: for @beingtheo

October 09, 09:51 PM

paul_shinn: @fading_roses19 @justindignation hope you like bruschetta (i'll pour some wine, too)

October 06, 01:27 AM

paul_shinn: @napcat1947 thank you :) turned out great once i got control of the pan back (bechamel sauce in this pic)

October 06, 12:43 AM

paul_shinn: with enough profanity and butter, i have discovered that one can make crepes in a regular pan

October 01, 02:40 AM

paul_shinn: @JettSuperior it is important that i share these with you. wouldn't you agree?

September 25, 11:36 PM

paul_shinn: gluttony

September 24, 02:33 AM

paul_shinn:

September 21, 12:54 AM

paul_shinn: @glamxoxo awww i'm sorry. if it helps; they're gorgeous when they're done. :) go for it!

September 11, 01:58 AM

paul_shinn: @JettSuperior i have this too. have never tried the brand before. was recommended @janeurysm long ago

September 11, 01:24 AM

paul_shinn: @JettSuperior i'm still hungry here :) want to share some ice cream with me?

September 11, 12:10 AM

paul_shinn: For @AliciaATobin. Drunken Pasta.

September 08, 02:27 AM

paul_shinn: The time for roasted tomatoes has finally arrived. Sensory dynamite. Not very pretty, though.

August 28, 07:58 PM

paul_shinn: @JettSuperior Hi Jett! I forgot to mention, I passed by your namesake town in western Montana on my travels last week.

June 18, 10:48 PM

paul_shinn: #bstu @AdInsanitum @scenesfromahat @EmpPalp @shariv67 in pose

March 04, 05:15 AM

paul_shinn: @Navanax Getting closer. Need collision detection, gravity, seams, and volume on the tiles. :)

Posts

May 14, 04:49 PM

As promised, here are some updated screenshots.

This screenshot demonstrates a number of the changes. Links no longer have underlines (too much clutter). Improvements from .NET 4.0 include better text rendering, better pixel-snap on certain 1-pixel high features, etc. Protected accounts are identified now. Also note the inline preview of images from twitpic.

Handling of native retweets has been improved. Marking a favorite on a native retweet will link correctly to the original tweet. Also, both profile images are shown for the retweeter (larger, background) and the retweetee (smaller, foreground). This is in line with comments I’ve overheard on twitter by a number of people who still prefer to quote the original tweet when retweeting.

Direct messages are shown in a similar vein, but with same-sized images, and the sender in the foreground. Images are a bit smaller but still a recognizable size. If you are viewing a message sent to you, the link to continue says ‘reply’, whereas if you are viewing a message you sent, the repeat-action link says ‘Message’. A subtle difference.

All of the prior images have a font-boost applied for large-screen viewing. Here are some screenshots with the regular default-sized font.

I am a little bit divided on whether I will keep the font-boost, as text is much improved in .NET 4.0; we’ll have to see.

Not much different with direct messages. Did you know (at this time, anyhow) that it is possible to send a direct message to yourself via the API?

A retweet.

Inline preview of a twitpic image, and another view of a retweet.

Permalink

May 14, 04:01 PM

I've been off from blogging for some time, while chasing down some performance bugs.

I decided to rewrite a large chunk of code related to data persistence. In previous versions, data would be stored before being displayed. In the current version and going forward, data will not be stored unless specified by the user, and it goes straight to the display model queue.

In addition, the core has been rewritten to use a single background stage. Using persistence required some parts to double-hop, but this made initial loads very slow. Initial load times are still less than ideal by my standards, but the time to usable interaction has improved considerably.

The application now targets .NET 4.0, as this version finally fixes the WPF text-rendering treatments that were present in .NET 3.5 and 3.0. In addition, some of the prioritization behind the scenes appears to have been changed. This required some tweaking in the application. In tradeoff, the UI is a little bit more responsible, but columns are slower to load; albeit the actual CPU burden is not any different. I may boost the priority higher in the dispatch chain, but I'm reluctant to do this as it is currently one step below layout, and thus could compete with redraws.

Support for specific hashtags has been added. However, in the interest of sparing some startup effort, no interaction is really possible yet. Clicking on hashtags in any tweet (or search result) will cause a new column to be displayed.

User profile support still hasn't been added yet. This will be coming soon.

The styling has been altered just a bit. Previews for twitpic links have been added. A screenshot will follow.

Some items I would like to get done next:

1. User Profiles

2. Interaction with saved search info from Twitter

3. User Lists

4. More media previews.

Permalink

May 04, 03:36 PM

Had an injured wrist at the end of the last week, so I took a day and a half off.

Here are items that were addressed since day 70.

1. Found a really nasty bug in my code that caused a lot of the slowdowns in initial startup. It didn't manifest itself as much, up until I tried to improve decoupling work from the main user interface thread. This is now fixed and hopefully should not regress in the future.

2. All actions that cause background activities or updates now have limited visual feedback as to their progress.

3. Merged the direct message columns into a single column. Support still exists for viewing separate received and sent messages, but for now they're merged together.

4. Direct messages that were sent, may now behave as received messages when a reply is issued. This is transparent to the user, only the link used to activate the post is different.

5. Started preliminary support for inline image previews. Right now, only twitpic is supported. Other image providers will be added in time.

I've been thinking about ditching some of the persistence model. Right now, initializing it from the start makes things very slow. I'm thinking that perhaps it should only save items as marked by the user.

Lots of little bugs need to be worked out too. However, speed and presentation are the biggest priorities right now.

Permalink

April 30, 08:55 PM

Taking a break today and also part of yesterday. Have some injuries to attend to.

Been playing around with the app a bit, along with other apps published by other people. Really need to improve speed- right now my app drags quite a bit in debug mode. Memory footprint is still excellent but I need to trade some of that back for speed.

Hopefully will be able to resume work tomorrow at 100%.

Permalink

April 29, 11:10 AM

Fixed up a number of things. Here's the list.

1. Favorites are now applied to the original tweet of a new-style retweet, in line with how they work on the twitter website.

2. Retweets are saved in an adjunct table, to keep the main homeline table clear.

3. Displays of direct messages and retweets have been improved, using pairs of offset images.

4. Old-Style retweets are now possible with one click to get into the editor.

5. New-Style retweets are now possible with one click. No feedback or good availability option yet, though.

6. Found some internals still using .xml versions of the twitter API. All of these were ported over successfully.

Unfortunately, improving support for re-tweets has increased the footprint on persistence. Out of the items listed yesterday, only one item remains.

1. Add in-line support to view user account profiles.

Here are new items that need to be done as well.

1. Improve persistence performance. I will probably create a in-memory cache or tweak cache settings for SQLite. Been thinking about doing this for user profiles.

2. Add support for non-account columns (search/hashtags).

3. Issue another release. Right now, I've set default reloads down to 20 items and the app is at 100% within about 5 seconds. When set longer, the app tends to grind a bit.. I may just release and keep going.

Permalink

April 28, 11:06 AM

Really poor progress yesterday. A bit mad at myself. But, I did get some things done.

Cleared through some bugs. Here's the list.

1. Missed a round of HTML encoding in handling DMs. Now they are unencoded properly and stored properly.

2. Found a bug where DMs could arrive from twitter with a length greater than 140. This is still perplexing, but I added sanity checks and truncation to avert this issue. As a matter of safety, I did this for all string fields, as well.

3. Decided to bite the bullet on certain bits of layout to be fixed, and now the keyboard accessibility bug with dynamically generated options is fixed. I'm still not sure this is the greatest way to handle this, but keyboard focus is preserved and that seems satisfactory for now.

4. Adding an account, removing the account, then adding it back would cause an error due to boarding the initial user's info twice. Fixed.

Today I will try to work on as many of the following things as I can.

1. Finish visual feedback/background operation for existing update actions.

2. Add profile views for user accounts.

3. Make retweets stand out.

4. Favorites should favor the original tweet, not the retweet.

5. Allow retweets.

Permalink

April 27, 03:24 AM

On the forward end of wrap-around days right now. Here's what happened yesterday.

1. Improved display of tweets and direct messages.

2. Started adding feedback for update actions.

3. Added user profile images in places where it is important to identify accounts.

4. Issued another release (0.0.7)

Today, I am going to work on the following things:

1. Finish feedback/backgrounding for update actions.

2. Add profile views for user accounts.

3. Fix DM encoding bug.

4. Make retweets (new-style) stand out.

5. Favorites should be applied to the original tweet, of a retweet.

6. Allow retweets for a tweet.

 

Permalink

April 26, 04:21 PM

Much improved. This is a sample with a font boost on.

Permalink

April 26, 02:46 AM

Fixed the following items:

1. Multiline input is now enabled for all new posts

2. Inline post-interfaces may be dismissed with the Esc key.

3. Greatly improved load speeds. Still have lots of head-way to make in this area.

Also added the following features:

1. If all available monitors are 1024x1024 in pixel area or bigger, then the minimum font size is boosted to 14pt.

Partly done with the following changes:

1. Fix captions and formats in the display of tweets/direct messages.

Today's goals:

1. Finish fixing display of tweets/direct messages.

2. Add feedback for update actions.

3. Add side-adjacent profile view.

4. Add user images in places where it is important to identify accounts.

5. Issue another release.

Permalink

April 25, 03:39 AM

Already received some feedback from two people who have tried out the alpha. Lots of new issues to address.

New Items:

1. Add/Remove Account needs improvement.

I skimped on this because I wanted to get something up and running, but account management is important and I think I may work on this soon.

2. Improve Account Identification in places where account items need to be differentiated.

3. Improve feedback for drag & drop.

Some potential features I had not thought of doing.

1. Tearoff/Detachable Columns

I'm a little bit worried this could get out of hand, but definitely a nice to have for #hashtag chats and direct messages.

2. Moving the main update panel to other locations

A possibility, but I think in-column update UI might make this a moot point.

Bug fixes:

1. Multiline input is not possible for new posts

2. Need to be able to dismiss inline-posts with the Esc key

3. Captions using labels need to be fixed or updated, to remove quirks involving underscore characters.

For now, priorities still rule. Bugfixes first, then features.

Permalink

April 23, 11:36 AM

It's slow, buggy, and generally horrendous; but it is just stable enough and has some key features that it is worth trials by other people.

The only item outstanding, which I skipped, is the following:

1. Missing Notifications when update actions are performed.

The items completed are the following:

1. Test Installation from MSI

2. Add Column should be disabled if no accounts are setup

3. Improve Speed

4. Schema Bug is fixed.

It still needs a lot of work in terms of speed, and it has a lot of missing features and capabilities. However, it is nice to be able to hand it off to someone else to try out.

Permalink

April 23, 12:41 AM

Items outstanding:

1. Schema Bug

2. Missing Notifications when update actions are performed

3. Test Installation from MSI

4. Add Column Should be disabled on first init until an account is added

5. Improve speed.

Items fixed/completed:

1. Drag & Drop ordering of columns.

I'm looking to work on speed at this time. Right now the app load and view update speed is horrendous.

Permalink

April 21, 11:37 PM

Items outstanding:

1. Schema Bug - Still not observed nor reproduced on x64.

2. Drag & Drop Ordering of Columns

3. Missing Notifications when update actions are performed

4. Test installation from MSI

5. Add Column should be disabled on first init until an account is added.

Items fixed:

1. Slow Column Addition/Removal

2. Click-View support on column list

I'm looking to get drag and drop in, and fix the Schema bug. The other items are not critical at this time.

Permalink

April 21, 02:45 AM

Uncovering more items to be fixed. For now, it may just be best to list the items outstanding.

1. Schema Bug - Still not reproduced on x64.

2. Focus on Favorite - Attempted fix, but keyboard focus cannot be set on a hyperlink. This item may be deferred.

3. Slow Column Addition/Removal - Not fixed yet.

4. Click-View support on column list - Not completed.

5. Drag & Drop ordering - Not completed.

6. Missing notification when an update action is performed. - Not completed.

7. Test installation from MSI - Not completed.

8. On first init, add column is enabled although no accounts are available. - Not completed. This item may be deferred.

Not much else to bring up except to continue to fix bugs and add features. Right now, bug fixes are top priority.

Permalink

April 19, 07:59 PM

Back home after Chirp. Lots to do right now.

While on the road, I found the following bugs:

1. First Account Init Failure - User information retrieved during authorization at twitter is not stored and thus doesn't exist when the UI for the account is setup. Status: Fixed.

2. Schema bug - DataReader fails at times when reading data, not observed on x64 but discovered on x86. Not sure about the cause. Status: Not Fixed.

3. Marking a tweet as a favorite, causes focus to be lost. Status: Not Fixed.

In addition, the following things need to be fixed.

1. Slow Column Addition/Removal - Views are reset on column changes. This reset is not necessary and needs to be fixed. Status: Not Fixed.

I'm setting a deadline for myself for this Sunday to release an alpha. Here are remaining tasks for Alpha, including fixing the aforementioned bugs.

1. Add clickable support in the column list to bring a column into focus and into view.

2. Add drag & drop reordering support for columns.

3. Test installation from MSI.

Permalink

April 12, 06:29 PM

This week is going to be a spotty week for me. I'll be out on the west coast attending Chirp and visiting a friend. Updates may follow if anything interesting arises. Otherwise, I'll be back in a week.

Permalink

April 11, 01:23 AM

Polished up the look of the app today, as I’m at a point in development where I don’t think I will mess with the layout for a while. Also caught up on all the other items required, except for the inline view stubs. Here’s a little gallery of what it looks like right now.

First, the main window frame.

Not bad, right? Here’s a snapshot with the column categories and poster retracted.

Inline post UI is up and running. Needs more work, but the basic concept is up and running.

Note that the original tweet is also echoed below. Can you have two at once? Yes. Here’s a snapshot of that.

Direct Messages? Got those covered too.

There are lots of little user interface layout quirks that need attention, but I’m quite happy to have taken a day to polish things up a little. The direct message layout still needs work- the little envelope icons are quite shabby and should be replaced.

Keyboard accessibility is pretty good, but also has some quirks that need work as well. Overall I’m pleased with how everything looks at this time, given the relatively small amount of effort put into it all.

Permalink

April 10, 12:55 AM

Today was a half day. I'm still going to be working another 2-3 hours, but I was away part of the day attending a processing.js panel and presentation in Boston.

I have to start weaning myself off of other twitter clients. From here forward, I will be forcing myself to stick with Landscape Deck, unless there is a feature that I need that I have not implemented yet. I'm believe that this will help me stay focused on adding features and improving the app. I've started adding inline reply/dm support, and I hope to get this done asap.

The alpha is going to be pretty rough. There's a lot of foreground interruption (lag) while columns are updated. I need to work on making it feed columns in smaller chunks, perhaps, and eventually I have to move a lot of stuff into asynchronous handlers.

The spec is getting a little bit out of hand. I'm wondering if it is time to split it into two specs: Implementation and Functional. I definitely don't have any problem with making the functional spec public- as it isn't anything that people can't compile on their own. The implementation spec, of course, should probably stay private.

There was quite a bit of surprise and a lot of anxiety today as Twitter announced the purchase of Tweetie for iPhone/iPod, on the heels of announcing a Blackberry app. A lot of devs are concerned about whether this is going to spell the end of third-party applications. I think it is premature to announce the end of third-party applications. There are a lot of features that Twitter will not support right away, and there should be plenty of ways for application developers to stay afloat.

Also, not to cause grief to anyone, but a lot of applications are simply immature. I'm a little bit amused that I mentioned to someone today that I would never dream of trying to create a Mac twitter client, because then I'd have to compete with Tweetie. There is still plenty that can be done to make a better experience. I can't predict whether I'm going to deliver on this, but there is no reason anyone can't go the extra mile to create a good mainstream experience. I won't call out anyone in particular, but I am absolutely shocked at the lack of progress that some, vendors, have in supporting a better Twitter experience.

Perhaps Twitter is more active in looking to acquire applications that do deliver a good mainstream experience than everyone has expected. While it may be a case for fear by everyone involved, people are forgetting that all large platforms/vendors do this. In example, note that Oracle bought MySQL, Google bought Youtube, Adobe bought Macromedia, and Microsoft bought Visio.

Not to rehash the oft-used Judo symbolism, I think it behooves everyone to remember this: All actions create possibilities for reaction. Will Twitter's application goals coincide with Tweetie? Who knows. But there will definitely be a void left behind, and a window of opportunity for any other client to step up to the plate before the official Twitter client is released. I'd say the time to strike is now. Tweetie was notably absent among the iPad-specific application releases. Anyone can jump in and take the lead now.

Permalink

April 09, 12:09 AM

Found my first uncaught crash bug in the App, caused by unicode URLs that require IDN handling. Since this is a show-stopper and has to be supported (due to URLs from sources like http://tinyarro.ws/ ); I spent today fixing this bug and also improving the parsing of tweets.

Fortunately, my efforts have resulted in an improvement in the working memory set, along with proper handling of IDN URLs.

However, there is a caveat to handling IDN URLs. Cases where ASCII is expected in a URL, now fail if enclosed directly in grouping punctuation marks (parenthesis, brackets, etc). I'm not sure how I will handle this case at this time.

After all of the time spent, here's what I need to work on next, out of the goals set earlier in the week.

1. Allow replies to a tweet

2. Allow replies to a direct message, via direct message

3. Inline support to reply / direct message within the column UI.

4. Add stubs to show an inline profile of a user when a @USER link is clicked.

Tomorrow will be a half day. I'm going to be attending a presentation by the processing.js people. We'll see how much progress is possible before the event tomorrow.

Permalink

April 07, 03:25 PM

Spent yesterday and today hunting down layout bugs. One of the bugs is fixable with a rather ugly hack- I am going to keep the hack but I suspect that I will have to spend time updating it in the future.

Functionally, the app does what is outlined in the spec for alpha, aside from in-column update UI. The overall experience is still pretty poor. While hunting down bugs, I came across some things that vastly improved the memory footprint of the app. I'm looking to keep the amount of overall memory use down, except where it improves response times. A fair tradeoff, I think.

Today I will be attending a jQuery meetup, so not much will get done today. Once I return from the meetup, I will resume layout work and bug hunting.

Permalink

abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz