Home
Fractals
Tutorials
Books
My blog
My LinkedIn Profile

BOOKS i'm reading

Napoleon Hill Keys to Success: The 17 Principles of Personal Achievement, Napoleon Hill, ISBN: 978-0452272811
The 4-Hour Workweek: Escape 9-5, Live Anywhere, and Join the New Rich (Expanded and Updated), Timothy Ferriss, ISBN: 978-0307465351
The Fountainhead, Ayn Rand, ISBN: 0452273331
Web Hosting Canada

mailto:olivier@olivierlanglois.net

Archives for: 2008

09/12/08

Permalink 07:34:23 pm, by lano1106, 549 words, 16429 views   English (CA)
Categories: AAC

AAC ADTS header buffer fullness field

I was trying to reconstruct ADTS headers from a raw AAC data stream and for most of header fields by knowing the stream properties, it is a straightforward task. There is, however, one exception. It is the ADTS 'Buffer fullness'. There is not much information about its purpose and how it is composed anywhere (including the Internet and the ISO IEC standards 13818-7 and ISO IEC 14496-3). After some analysis of the problem I came to the conclusion that 'buffer fullness' is not reconstructable reliably. However, doing this exercise has allowed me to get a better understanding of 'buffer fullness'. So for the next persons who will google 'AAC ADTS buffer fullness' in hope of finding some info, here is what I have learned:

Buffer fullness is a 11 bits field in the ADTS header. Its purpose is not very clear so I will expose what I know about it:

Definitions:

NCC = Number of Considered Channels. In our case 2

minimum Decoder input size = 6144*NCC = 12288

mean number of bits per block:
For a 96 kbps stereo signal at 44.1 kHz

(96000 bit/s / 44100 samples/s * 1024 samples/block) = 2229.1156 bits/block

maximum bit reservoir = minimum Decoder input size - mean number of bits per block
= (12288 bits - 2229.1156) = 10058

bit_reservoir_state[frame] = bit_reservoir_state[frame-1]+mean_framelength-framelength[frame]

0<=bit_reservoir_state[frame]<=max_bit_reservoir

adts_buffer_fullness=bit_reservoir_state/(NCC*32) (In other words, the state is shifted to the right to drop the 6 LSBs)

The purpose of the bit_reservoir_state is to control the encoder bitrate. The reservoir value gets lower as the encoder outputs frames longer than the mean framelength. Once the reservoir value gets near to 0, this will force the encoder to send few frames shorter than the mean framelength to refill the bit reservoir. If the encoder has prepared a frame and it is too long to respect the bit reservoir constraint it will perform a second pass on it to compress it further. If it is too short, it will add padding to it (with an AAC raw data block fill element type (FIL)) . The consequence of this is that on average each AAC frame will have the same length and the bitrate will be constant.

One observation is that the bit reservoir state is internal to the encoder and you cannot deduce it from the buffer fullness because you do not have the 6 missing LSBs of the state from buffer fullness.

Also the standard ISO IEC 13818-7 and ISO IEC 14496-3 are not clear about what a decoder can do with the buffer fullness. The open source faad decoder ignores it. The open source faac always set it to VBR (all ones) even if it has been configured to do constant bitrate. WinAmp AAC decoder uses it to display the stream bitrate. If the special value reserved for VBR is used, the displayed bitrate will vary, otherwise it will display a constant value (ie 96kbps) no matter what value it is. It could be a constant arbitrary value (ie:0), random or the values from a true encoder, it does not matter to this decoder.

I guess that a decoder could use the buffer fullness to predict approximately the frame length it risks to encounter down the stream but I have never seen a decoder using it.

09/02/08

Permalink 09:54:54 pm, by lano1106, 415 words, 3889 views   English (CA)
Categories: C++

C++ IOStreams Handbook

C++ IOStreams Handbook, Steve Teale, ISBN:020159641

This book has been published in 1993 and iostreams has changed a lot since then so this book is a bit outdated. Things that were not there in 1993 include:

  • extension less header files
  • std namespace
  • IO stream classes were not templates
  • No locale and facet classes
  • classes that are now deprecated strstream

Surprisingly even with all these changes, most of the code in the book would still compile today. This is one sign that C++ designers took a great care to not break existing code unless absolutely necessary. The book is divided into different chapters. Materials that have still value today are:

  • The first 3 chapters that explain why a programmer should prefer using io streams over printf
  • The next few chapters describing the translator classes (istream,ostream,etc)
  • Even if the code is rather cryptic in my opinion, there is a chapter that shows how to write table based extractor and inserter functions (operator<< and operator>>). One application of such function, for instance would be to implement a regular expression processor with a DFA.

There are easier ways to implement regular expressions with the boost library. The value that I see in the third point is that I have always kept my own operators << and >> very simple and I have found this part of the book was eye opening to what was possible to do with these functions.

The chapter that I have found to have failed the test of time is the last and very lengthy chapter that presents close to 50 small test programs so you could test that your iostream implementation was compliant with the latest C++ draft specifications for iostreams. At the publishing time, it was perhaps needed as C++ implementations were trying to catch up with a moving standard but today, iostreams specifications have been stable for many years. I think that it is safe to take for granted that your iostreams behavior is compliant with the standard or it should be a total shame for the library developer if it is not the case.

To conclude, since the book is still accurate on most points, it can still be handy as a reference if it is hanging around. However, at the same time, since iostreams have changed in subtle ways since the publishing date, I would recommend looking for a more recent book for a new purchase. I have not read it but 'Standard C++ IOStreams and Locales' might be a better choice.

08/22/08

Permalink 08:42:32 pm, by lano1106, 372 words, 5526 views   English (CA)
Categories: C++, C++

Ruminations on C++

Ruminations on C++, Andrew Koenig, Barbara Moo, ISBN: 0201423391

I have got interested in this book because I have read from many sources on Mr. Koenig involvement in several key elements of the C++ language such as argument dependant lookup (ADL), also called the Koenig lookup, and the intersect rule for function overloading. In fact, if you read the book 'The design and evolution of C++', Andrew Koenig name is omni present throughout the book. So I was curious to see what Mr. Koenig had to say on C++.

Reading this book has been like a roller coaster ride. First, the cover is intriguing with its recursive pattern where you can see a girl under a tree in a field with cows in the background reading the 'Ruminations on C++' book with the same cover repeating itself over and over. Then the book is divided into six parts and, in my opinion, not all parts are equally good. The first part is taking a more philosophical view on what the C++ language aims to achieve. This part is not too technical and it has somehow a lot of appeal to my eyes. While reading this part, I was thinking that this was very promising for what was to come.

Then at the second part, it is where things are getting spoiled. Part 2 is describing basic C++ techniques. It is not bad but by having read tons of C++ books, to appreciate one of them, I must find some originality that I haven't found in part 2. This part of the book is average.

Finally, I have changed another time my opinion on the book when I have reached part3. Part3 covers templates and more specifically it recreates the whole though process that the STL designers went through to create STL. I see a lot of value to this kind of activities as I believe that understanding why certain things are done in a certain way can help you to better use those things.

In conclusion, I can recommend this book because I feel that mister Koenig goes beyond just the language syntax and try to teach a though process that someone has to go through to solve programming problems. This is a pedagogical approach not found in every programming book.

08/04/08

Permalink 09:03:11 pm, by lano1106, 264 words, 3110 views   English (CA)
Categories: Book reviews, Recommended books

XML Schema - The W3C's Object-Oriented Descriptions for XML

XML Schema, Eric van der Vlist, ISBN:0596002521

I had to create a XML schema at my job for the very first time. This is something that I have never done before and I was a total neophyte on XML schemas. A coworker has lent me this book and I would say that after having been through the book in 2 days, it did its job. I have been able to complete my task and I have created a fairly complex XML schema. One quality that I appreciate in technical books is when the book is entertaining and interesting to read. I know that for the non initiated, technical and entertaining might seem incompatible but I have read such books. XML Schema does not have that quality. However, it has the quality to be extremely good to make its readers learn XML schema. If you need to learn XML schemas, you can read this book. It will not be fun but once you are done with it, you should have a pretty decent understanding on the topic.

Another aspect that I have noted is that on very rare circumstances, that book was lacking clarity in my opinion. There are few sections that I was really trying to understand what the author wanted to explain but after many readings of the same section, I did gave up on trying. The section named 'Asymmetry of these two methods' in chapter 7 is one example of what I am describing.

In conclusion, after weighting in the qualities and the problems of this book, I can recommend this book with confidence for anyone that must learn XML schemas.

07/06/08

Permalink 12:22:15 pm, by lano1106, 249 words, 4356 views   English (CA)
Categories: TCP/IP, TCP/IP

UNIX Network Programming: Networking APIs: Sockets and XTI; Volume 1, Second edition

UNIX Network Programming: Networking APIs: Sockets and XTI; Volume 1, Second edition, W. Richard Stevens, ISBN: 013490012X

This is considered by many as the TCP/IP application programming bible and I am among them. This book is simply the most complete and detailed book on Socket programming. It describes every option under all their small details. This makes the book reading lengthy and tedious but it also makes it an excellent reference. Even experienced socket programmers will most likely learn something from this book. For myself, I got a better understanding of the listen() parameter purpose, a better understanding of socket lingering behavior and I refer the book from time to time to refresh my memory on topics such as how to time out a TCP connection attempt.

After having borrowed the second edition from someone at my work, I have decided to get myself a copy of the book. I have purchased the third edition. As of the time of writing this review the price for a used copy of the second edition is 6$ compared to 60$ for the third edition. Since I had the chance to compare the content of both editions, you might be interested to know that beside 1 bug fix in the sample code that I have noticed, the content of both edition is identical to 90% in my estimation. The changes are very minor. Some unimportant topics from the second edition such as XTI have been replaced by very specialized new topics. This means that, in my opinion, purchasing the older second edition which is still very accurate is a very good purchase.

06/10/08

Permalink 07:47:43 pm, by lano1106, 208 words, 2622 views   English (CA)
Categories: TCP/IP

Why TCPINCR is set to 904?

In the book Internetworking with TCP/IP volume 2 - Design, implementation, and internals at the chapter 13 (TCP: Output processing), section 13.16 Other TCP Procedures, the source code of the function tcpiss() called to obtain the Initial Send Sequence (ISS) is presented. The function works by initializing a static variable with a clock counter value and then increment that value to TCPINCR whose value is 904.

No explanation is provided about the 904 value and there is even an exercise asking the reader to contact the coauthor David Stevens by e-mail to know why they are using 904. I first tried to find the answer on the net before contacting them but the information was unavailable.

So here is the answer of Douglas E. Comer, coauthor of the book, on the topic for the next fellow looking for the same answer:

It's an inside joke. The TCP standard says to choose a value other than 1.
My co-author, Dave Stevens, and I tossed a coin, and we used his birthday (September 4th). There are a couple of other fun items in the book (hint: look in the index).

Regards,
Doug Comer

After reading Mr. Comer reply, I have checked the index and there is a list of well-known constants such as the world renowned 1.3.6.1.2.1 !

06/05/08

Permalink 11:08:40 pm, by lano1106, 669 words, 27231 views   English (CA)
Categories: TCP/IP

CLOSE_WAIT vs TIME_WAIT

While we were using an Apache ActiveMQ broker at my job. It has been reported by the operators last week that the broker could not open new sockets because it has reached the maximum limit of open file descriptors. The operators have also mentioned that the majority of the TCP sockets where in the CLOSE_WAIT state. My initial reaction has been to confuse the TCP state CLOSE_WAIT with the TIME_WAIT state.

Yesterday, someone else reported the same problem on the Apache ActiveMQ developers’ mailing list and I have noted by reading posts from people trying to suggest workarounds that I was not the only one to mix up the TCP state CLOSE_WAIT and TIME_WAIT. So this gave me the idea to take this opportunity to write about the differences between these 2 states since apparently there is a widespread need for clarifications on that matter.

A TCP connection goes into the CLOSE_WAIT state when it receives a FIN segment from its peer. From that point the connection becomes half-duplex and the TCP connection will not receive any new data from its peer but it will still be able to send any amount of data back to the peer. Hence, the socket will stay there as long as the server does not call close() explicitly on the socket.

I am not sure on this but I think this is exactly what the state name means. The socket is waiting for the application to call close() before going away.

TIME_WAIT is the TCP state a connection will go when it performs an active close (it is initiating the connection shutdown) after having received the peer FIN segment and sent it back an acknowledgment for the FIN.

The connection will stay in that state for 2 times the maximum segment live (MSL). As an interesting side note, the MSL has nothing to do with IP time to live (TTL) or the TCP connection round time trip (RTT). The MSL value is a constant and varies from one TCP implementation to another. RFC 793 suggests using 2 minutes for the MSL and the implementation shown in this book is using 2 minutes but 4.4BSD is using 75 seconds and Linux close to 4 minutes. The reason why MSL is unrelated to IP TTL and RTT is that a TCP segment can outlive the IP packet carrying it even if routers takes longer than usual to deliver it since a TCP stack will retransmit it.

TIME_WAIT is needed because it is possible that the TCP acknowledgment for the received FIN gets lost (or any segment containing data prior the FIN). In that case, the peer will try to retransmit its FIN for the MSL period. Waiting for a longer period than MSL is the only choice TCP can make as there are no acknowledgements for ACKs (that would be recursive anyway and solve nothing if ACKs were acknowledged).

I have been wondering for some time why TCP does not wait 2 times MSL before leaving the LAST_ACK state like it does for TIME_WAIT since there are scenarios where TCP could receive packets from the previous connection after leaving LAST_ACK and I think that I have understand why. In TIME_WAIT, you want to handle peer retransmission otherwise it could think that its last segments have never been received. In LAST_ACK, there is nothing else to acknowledge so it does not matter if TCP reset the connection after leaving LAST_ACK.

For instance, let’s say that the stack retransmits its FIN and both the original FIN and the retransmitted one get acknowledged. What will happen is that at the reception of the first ACK, TCP will release its Transmission Control Block (TCB) associated to this connection and at the reception of the second ACK, it will reply with a RST. It is no big deal. The other peer will be in the TIME_WAIT state and will just conclude that the peer is gone when it will read the RST.

05/14/08

Permalink 12:36:56 pm, by lano1106, 286 words, 4316 views   English (CA)
Categories: C++

C/C++ register keyword usefulness

I have received a comment for this blog post to the effect that using the keyword 'register' was useless and all compilers will ignore it. I do not agree on this. If you search on the Internet, you will find out that a lot of people speculate and have their opinion on the subject but the truth is that unless you are a compiler writer, you have no idea whether a given compiler is doing something with the 'register' keyword or not. Even if you know the answer for a specific compiler, you cannot generalize for the other compilers. Here is what the C++ standard in section 7.1.1:

A register specifier has the same semantics as an auto specifier together with a hint to the implementation that the object so declared will be heavily used. [Note: the hint can be ignored and in most implementations it will be ignored if the address of the object is taken. -end note]

It is true that today compiler optimizers are very clever and can do a decent job at managing a CPU registers alone but lets imagine how the algorithm managing the registers used by the compiler works. Registers are a scarce resource and the compiler must analyze each variable usage and assign to each variable a score based on various criterias. If the compiler needs to swap back a variable to memory to reuse a register, it would choose the variable having the lowest score. What happens if more than one variable have the same low score? In such situation, a compiler could use the 'register' keyword hint to take a decision.

Situations where the 'register' keyword could be used:

  • temporary variables used in bitwise logical operations
  • loop counters

05/06/08

Permalink 09:16:37 pm, by lano1106, 791 words, 2248 views   English (CA)
Categories: C++

Formatted I/O in C++

In this post, I want to explain why using ostream for formatting output is a better option than using printf. I intend to make my point by showing how these 2 methods work. By the way, an important milestone in my programming career was to come to the realization that standard libraries functions are no more magical than your own functions. I believe that once you stop considering system functions as black boxes and start getting interested in how they work, your programming skill will improve. This is especially true, since a lot of these libraries source code is available for your leisure to consult it.

printf was extremely versatile when it has been introduced with the C language standard library. However, it suffers serious problems:

  1. Performance issue: printf is interpreting the format string at run-time. It scans the string looking for the next '%' character. Once found, it goes in a switch case on the following char to determine the type of the next variable to extract from the stack and to format its value in its string representation.
  2. Safety: printf is unsafe from the fact that the variables type and size passed to printf are lost and they are removed from the stack solely based on the content of format string. printf is a source of many security exploits in networked server. With a carefully crafted input string containing '%' chars in it (like in a HTTP user-agent string), it is possible to crash a server that is using printf incorrectly. Some compilers such as gcc tries to warn you about potential problems with printf but usually these warnings go unnoticed so even with them, printf is still very error prone.

std::ostream does not suffer from any of printf problems. ostream is using the function overloading language feature to determine what is the type of the variable to format. Because all the work is performed by the compiler, there is no runtime cost as with printf. A good implementation of C++ I/O streams can offer a substantial performance advantage compared to printf based code. Of course, there are bad implementations like old implementations. The standard library shipped with VC++ 6 is one of these bad implementations where I/O streams are implemented under the hood with printf. Obviously, with such implementation you can only have slower I/O than using directly printf but that type of implementation is becoming quite rare. You also have safety since type checking is performed by the compiler.

Also, when using C++ output string streams, as you would initialize a string with its initial value rather than creating an empty string followed by assigning it its initial value, you can do the same thing ostrstring. If the first element of string to format is a string, pass it to the ostrstring constructor:

explicit
basic_stringstream(const basic_string<Ch,Tr,A>& s,
                   openmode m = out|in);

use:

std::ostringstream ost("First string chunk:",
                       std::ios_base::ate);
ost << 123;

instead of:

std::ostringstream ost;
ost << "First string chunk:" << 123;

And finally, there is, in my opinion, the boost abomination. The format class. This is a glorified object oriented printf. It is slightly improved compared to printf in the sense that the parameters type is validated and hence using format is safer than printf. However, it has the same performance problem than printf because it has to evaluate the format string at runtime exactly like printf. I guess that the motivation for writing this class was that there is some niche situations where using C++ streams are rather messy. My problem with this class is that having multiple options to achieve the same outcome is confusing. This is especially true for people learning C++. The language itself is already complex enough without adding an unnecessary complexity by adding multiple options. Another category of programmers for whom having format as an option can be problematic is the blind followers of boost. Programmers of this category are usually junior and they have been told that the next C++ cool thing was the boost library and since then they started to incorporate boost classes everywhere they can without understanding the implications or looking how boost classes are working.

I am concerned about this class because boost is considered as the playground for the persons designing what will be future standard libraries. In my opinion, only the best option to perform a certain task for most of the cases should find its way into mainstream libraries. We need to keep printf for backward compatibility but format that is only a better printf but not quite as good as I/O streams should not have that status.

05/04/08

Permalink 06:20:38 pm, by lano1106, 168 words, 2842 views   English (CA)
Categories: C++

C++ function overloading

This is the C++ language feature that allows multiple functions to have the same name. Having multiple functions with the same name was not possible in C. The compiler is able to choose the right function by checking its parameters:

int f(int)
{
  printf("This is f(int)\n");
}

int f(char *)
{
  printf("This is f(char *)\n");
}

int test()
{
  f(1); // This is f(int)
  f("test"); // This is f(char *)
}

The way it works is that the compiler mangles function names. Mangling means that the function parameters type gets encoded in the exported function name. How a compiler mangles a function name is not specified by the standard. Hence this is one of the reasons why it is not possible to use an object file generated with compiler X with compiler Y. Most tools manipulating C++ object files (like nm) perform the reverse operation: demangling. That is extracting the function signature (including the parameters) from the exported C++ mangled function name.

04/28/08

Permalink 09:55:06 pm, by lano1106, 680 words, 4655 views   English (CA)
Categories: C++

ODR, inline functions and C++ compiler generated functions

ODR is the One Definition Rule. This is the rule that stipulates that a name (a function, a class or global variable and much more other types) must be defined not more than once in the same program. The compiler will emit an error if a name is defined more than once in the same translation unit (TU) or if the name is defined more than once but in differents TUs, it is the linker that will catch the error and it will emit a duplicate symbol error.

The ODR is the reason why header files guards are used (#ifndef XXX #define XXX #endif). If a header file was not protected by guards and included more than once in a TU, the ODR would be violated.

All C++ programmers have a formal knowledge of the ODR or at least an intuition of its details learned by experience but this rule gets very interesting when you start to study the exceptions to it. Studying these things makes you more appreciate the complexity of the C++ language.

For instance, there are the inline functions. Usually, when we think about inline functions, we consider them as fancy macros with strong type checks. However the inline keyword can be considered only as a hint given to the compiler and the compiler is free to completely ignore the inline specifier. If it does ignore it, it will generate a regular function and export it from the resulting object file. If the inline functions are defined in many TUs and linked together then according to the ODR, this would be an error but inline functions are exempted from the ODR and the linker only keeps one copy of the inline functions defined multiple times. I would be very eager to figure out how the linker knows that a given function is exempted from the ODR because as you will see next, there are no apparent hints to this effect.

The next exception to the ODR is the C++ compiler generated functions for a class. Those functions include the copy constructor and the assignment operator. The C++ standard says that these functions are always implicitly declared if not explicitly done by the user but implicitly defined only if they are used. They will also be considered as inline hence also exempted from the ODR. Another property of the generated functions is that they are classified as trivial or non-trivial. Essentially, a trivial copy constructor simply means that the class looks more like a C POD (Plain Old Data) structure than a class and the compiler can use the same C compiler technique to perform the deep copy (probably something like a memcpy). Otherwise, it will need to create a real constructor function. Here is a simple example to demonstrate these notions:

C.h: 

class C 
{ 
public: 
   C() : a(0), b(0), c(0), d(0), e(0) {} 
//  virtual ~C() {} 
private: 
   int a; 
   int b; 
   int c; 
   int d; 
   int e; 
}; 

f.cpp: 

#include "C.h" 

C f() 
{ 
     C a; 
     C b = a; 
     return b; 
} 

g.cpp: 

#include "C.h" 

C g() 
{ 
     C a; 
     C b = a; 
     return b; 
} 

main.cpp: 

#include "C.h" 

C f(); 
C g(); 

int main(int argc, char *argv[]) 
{ 
   f(); 
   g(); 
   return 0; 
} 

g++ -c f.cpp 
nm -a -C f.o 

00000000 t 
00000000 d 
00000000 b 
00000000 t 
00000000 n 
00000000 n 
00000000 a f.cpp 
00000000 T f() 
00000000 W C::C() 

No sign of the copy constructor. I am guessing that the compiler make the copy constructor inline because it is trivial. I am adding a virtual destructor to make the copy constructor non-trivial:

00000000 T f() 
          U operator delete(void*) 
00000000 W C::C(C const&) 
00000000 W C::C() 
00000000 W C::~C() 
00000000 W C::~C() 
00000000 V typeinfo for C 
00000000 V typeinfo name for C 
00000000 V vtable for C 
          U vtable for __cxxabiv1::__class_type_info 

Now g.o and f.o have a copy of C copy constructor and the linker will link fine and only one copy of the function will find its way in the final executable file because the implicitly defined copy constructor is inline.

04/12/08

Permalink 03:22:31 pm, by lano1106, 265 words, 2574 views   English (CA)
Categories: C++

shift operator undefined behavior

I was expecting:

int main( int argc, char *argv[] ) 
{ 
   unsigned char m = 32; 
   register unsigned mask = (1<<m); 
   std::cout << std::hex << mask << '\n'; 
   return 0; 
} 

to print 0 but instead this program compiled with g++ (and VC++.NET2003 too) prints 1!

If I change (1<<m) by (1<<32) or if change the program for:

int main( int argc, char *argv[] ) 
{ 
   unsigned char m = 31; 
   register unsigned mask = (1<<m)<<1; 
   std::cout << std::hex << mask << '\n'; 
   return 0; 
} 

it gives me the expected 0.

In the C++ standard document, section 5.8. It is written

"The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand."

The root for this behavior probably originates from C and the safe way to perform a bit shift when the number of bits to shift may exceed the length of the left operand is to implement the shift operation in a function:

Example, almost but not universally portable:

#include <climits> 

unsigned int safe_uint_shift(unsigned int value,
                             unsigned int bits) 
{ 
    if( bits > (CHAR_BIT*std::sizeof(unsigned int) )
    {
      return 0;
    }
    else
    {
        return value << bits; 
    }
}  

Put it in a header and make it inline if you like.

This solution has been proposed by Jack Klein.

The other way that I have used is to promote the left operand to an integer type having enough bits:

register unsigned mask =
  (static_cast<unsigned long long>(1)<<m)<<1;
Permalink 09:04:01 am, by lano1106, 279 words, 1784 views   English (CA)
Categories: C++

operator<< for a private inner class

Suppose we have

class A
{
  private:
  class B
  {
  };
};

and we would like to define operator<< for class B. I had this situation yesterday and it took me few tries to make it work. I first tried:

class A
{
...
};
std::ostream operator<<( ostream &, const A::B & );

It did not work because the compiler complained that B was private. My second attempt:

class A
{
  private:
  class B
  {
  };
  static std::ostream &operator<<( ostream &, const B & );
};

I was getting closer to the solution but this was still not quite right. Apparently, you do not have the right to declare operator<< as a static member of another class or as soon as an operator is defined as a class member, automatically, the compiler expect the left operand to be of this class type.

Then I tried this:

class A
{
  private:
  class B
  {
  };
  friend std::ostream &operator<<( ostream &, const B & );
};
std::ostream &operator<<( ostream &o, const A::B &b )
{
}

This time, I am not sure why but the linker now was complaining about duplicate symbols for my operator<< function. Not sure if it is the code that has a problem. It looks good to me. I suspect that maybe it is parameter type mangling problem and the compiler does not recognize 'const B &' as the same as 'const A::B &' but anyhow, I did not pursue the investigation I have finally made the code work like this:

class A
{
  private:
  class B
  {
  };
  friend std::ostream &operator<<( ostream &o, const B &b )
  {
  }
};

03/31/08

Permalink 10:15:07 pm, by lano1106, 302 words, 4294 views   English (CA)
Categories: General, Video games, AAC

AAC versus MP3

AAC is a new audio codec standardized to supersede the MP3 codec. When I hear about new technologies, I am always a little skeptic since I have long understood that newer technology is too often not synonym with better technology. However, at the company that I am working for, StreamTheWorld, we have developed the first system that stream AAC through Flash players. On StreamTheWorld website, there is a demo where the player connects to one MP3 stream and to one AAC stream with the same bitrate of 48 kbps. Both streams contain the same song and the demo consists of slider that allows you to switch between the AAC version and the MP3 version. You must absolutely check the demo! (PS: Make sure that you have the latest Adobe Flash player installed as AAC playback as being added only in the latest release which is 9.0.115) The difference is so convincing that you will probably want to start converting all your music to AAC!

One note about AAC, is that there exist many versions of AAC. I am listing them in the order that they have been released:

  • MPEG2 AAC
  • MPEG4 AAC
  • AACPlus
  • AACPlus v2

All versions provide improvements over the previous versions and also provide backward compatibility. That is you could listen an AACPlus v2 stream with an MPEG2 AAC decoder. However, the additional information contained for AACPlus v2 will be discarded and the resulting audio will only be as good as an MPEG2 AAC audio stream can be. Players supporting AACPlus v2 includes:

  • Adobe Flash player
  • WinAmp and every player using the open source AAC decoder FAAD2.

iTunes support AAC but not AACPlus v2. Sony with its PS3 and Nintendo with the Wii gaming console have made AAC their official audio codec but I do not know which version they are supporting.

03/25/08

Permalink 08:57:31 pm, by lano1106, 171 words, 1712 views   English (CA)
Categories: Book reviews

Streaming Media

Streaming Media, Gregory C. Demetriades, ISBN: 0471209503

The book proposes you to teach you how to build and implement a streaming system. First, as a software developer, when I read building and implementing a software solution, I usually expect a book about programming. This is not the case, the book proposes to build and implement a system by plugging together components directly off the shelf. I was a little bit disappointed but still it could have been an interesting book. Unfortunately, the book only consists of a catalog of products used in a streaming system without proposing a comprehensible clear picture of how all these components interact together. It looks like:

Chapter on cameras:
 camera X: bla bla bla
 camera Y: bla bla bla
 camera Z: bla bla bla
 
Chapter on encoders
 encoder from company A

and so on...

I am implementing streaming servers for a living and I could not make much sense of this book so do not expect that it will for you if you are looking a book to get introduced to digital streaming.

03/11/08

Permalink 09:09:19 pm, by lano1106, 356 words, 2568 views   English (CA)
Categories: C++, TCP/IP

C++ Network Programming Volume 1

C++ Network Programming, Vol. 1: Mastering Complexity with ACE and Patterns, Douglas C. Schmidt, Stephen D. Huston, ISBN: 0201604647

ACE is an amazing C++ application framework to create portable networked applications. I wish that I could praise as much the first volume describing this framework but it has some weaknesses in my opinion. It enumerates one by one the different low-level ACE classes that encapsulates, by using the wrapper facade pattern, the differences in services provided by the supported platforms. These services include sockets, threading, process management and synchronization primitives. One strong point of the book is that it demonstrates how using C++ features (like strong typing and RAII idiom) with ACE classes can make programs safer and less prone to bugs. The book also briefly discusses how to design networked services based on the service requirement. My complain about the book is that it covers many topics but since it does not focus on any of them, unless you are totally new with C++ or TCP/IP applications, it is likely that you will not learn much. You will find the book interesting if:

  • You have not yet seen the benefits of abstracting the implementation from the users with OO encapsulation
  • You have little experience in programming TCP/IP applications

My expectation for this book was that I would learn details about the inner working of the ACE classes. The type knowledge that should have complemented the official documentation provided with the framework. I have found out that it is not really the case. Except for less experienced developers, I think that someone should be able to become able to use all the covered classes in the book with only the documentation coming with the framework. There are few places in the book where I would have like to get this extra information such as in the section on ACE_InputCDR and ACE_OutputCDR or by making sure it is clear for the readers why calling ACE_Handle_Set::sync() is needed after having called select().

I have started to read the second volume and I believe that the second one will fit better my likings as it covers high level patterns built on top of the low-level classes presented in the first volume.

03/03/08

Permalink 09:03:16 pm, by lano1106, 75 words, 1697 views   English (CA)
Categories: Book reviews

Under Pressure and on time

Under Pressure and on time, Ed Sullivan, ISBN: 073561184X

This book presents how the now defunct company Numega, who developed the famous debugger SoftIce and BoundsChecker, managed software development. It has a very generalist approach by covering a broad range of topics from human resources management to release cycle. It is an ok book presenting very good practices but the problem is that it lacks focus. Instead of covering some topics in depth, it covers a lot of small things for few pages each.

02/26/08

Permalink 08:49:06 pm, by lano1106, 191 words, 1586 views   English (CA)
Categories: Book reviews

Debugging The Development Process

Debugging The Development Process, Steve Maguire, ISBN: 1556156502

This is the sequel of the book 'Writing Solid Code' that I have also enjoyed reading. In this book, the author simply applies the same mindset used to debug software to analyze development process and this makes the result very interesting. Instead of just giving a methodology for managing development, the author brings readers to think about the goals behind these methodologies through real life anecdotes and colorful analogies. In my opinion, this way of teaching is much more efficient than just showing a methodology and asking to follow it without showing the motivations behind it.

Covered topics include: how to keep a team motivated, what not to do to avoid demotivating a team, how to deliver on schedule without overwork,etc...

This is a book easy to read that could take you just few hours to go through. Some people could say that it just state the obvious but unfortunately too often this is exactly what is out of sight for many so I would say that you might get new insights from it or, at worse, a refresher on good strategies by reading a nicely written and entertaining book.

01/21/08

Permalink 08:29:01 pm, by lano1106, 149 words, 1590 views   English (CA)
Categories: Book reviews

AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis

AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis, William J. Brown, Raphael C. Malveau, Thomas J. Mowbray, ISBN: 0471197130

It could have been a good book since the topic is interesting. All developers know what spaghetti code is or how adding features quickly on top of a prototype without modifying the software architecture can lead to a big blob of unmaintainable code. I took this book in hope to learn other bad software development habits in order to avoid them. Despite the potential, this book does not deliver it. It start with a lengthy and half comprehensible 60 pages introduction followed by a catalog of antipatterns where most of them are empty of value. Out of around 30 antipatterns, I would estimate to less than 5 the number of antipattern descriptions interesting. Examples of useless antipatterns are:

Bad management; proposed solution: The manager must become aware of his problem in order to change.
e-mail arguments; proposed solution: Call a meeting to come to an agreement instead of wasting time writing e-mails.

01/16/08

Permalink 07:15:09 pm, by lano1106, 50 words, 1725 views   English (CA)
Categories: General

A serious bug found in the MySQL C library!

After having reported the bug to MySQL and after a lot of patience trying to explain it to the MySQL developers, they have finally verified the validity of my bug discovery and have classified it as serious!!

For the gory details of my discovery, you can consult the bug report.

01/14/08

Permalink 09:13:44 pm, by lano1106, 98 words, 1582 views   English (CA)
Categories: Book reviews

Software Project Survival guide

Software Project Survival Guide, Steve C McConnell, ISBN: 1572316217

I have not found this book very fun to read because of its very structured and academic format. I have not learned much from it as much of its content is general wisdom that anyone with many years of experience in the industry has probably seen around before. Something positive I can say about the book is that I totally adhere to the methodology explained in the book. In my software development career, I have experienced myself the benefits of applying similar software development management methodology and I have also seen the negative consequences of not following it.

01/10/08

Permalink 09:09:14 pm, by lano1106, 518 words, 1581 views   English (CA)
Categories: Book reviews

Dynamics of Software Development

Dynamics of Software Development, Jim McCarthy, ISBN: 1556158238


I have not found this book as interesting as the type of books that I usually read. I prefer books dealing with the more technical aspects of software development. I have read this book because I need to acquire a solid base of knowledge on software project management and not because the topics covered in the book seemed fun and interesting to me. Even if I was not very enthusiast to read it, I must confess that the author made a great job making his book interesting to read by interleaving important concepts with anecdotes from his work experience.

This book is divided into 54 short advices each taking 1 to few pages to expand the rational behind the advice. This is a format that I like and the advices that I have preferred were the ones dealing with the psychological aspect of software development. An example of such rule is that software quality is the mirror of the state of mind of the team. For some this might be obvious but considering the book intended readers which consist of engineers and software professionals, the author has been wise to be explicit on this topic in my opinion as from experience, human interactions is usually not the strongest skill among developers.

The part that seems to me to be outdated is the whole proposed economical model to market software. The author advocates that to make money from software, you must release often like every year and by doing so, your customers will be so happy that they will gladly hand you more money year after year. I think this model used to be true when the software industry was still young 20 years ago but in 2008, the software products are so mature that no matter how hard you try to squeeze more new features, it will not be enough to justify for people to purchase the new version when that last one does everything you want. You just have to think about the sales of Windows Vista or Microsoft Office 2007 to see what I mean. Changing just for the sake of changing does not sell.

In my opinion this model should be changed to one where incremental small evolutions are proposed to customers. I would be willing to pay a small amount of money every year for an OS that is smaller, better and faster at each version. I do not get it how software companies can expect people to be interested in slower and more bloated products than the previous version. Add the possibility to purchase inexpensive add-ons to fill very specific needs to the model and you have a very attractive model. I am not sure if what I would like to see is representative to what the typical customer expects or if my proposal is viable in real life but one thing is sure. The model proposed in the book does not seem to work anymore for many mature businesses.

There is a 2006 edition of this book. I might take a look in it to find out if the advices that I have found outdated have been reworked.

Olivier Langlois's blog

I want you to find in this blog informations about C++ programming that I had a hard time to find in the first place on the web.

2008
 << Current>>
Jan Feb Mar Apr
May Jun Jul Aug
Sep Oct Nov Dec

Search

Custom Search

Misc

XML Feeds

What is RSS?

Who's Online?

  • Guest Users: 2

powered by
b2evolution