Home > Articles > Programming > C/C++

  • Print
  • + Share This
Like this article? We recommend

Like this article? We recommend

Putting the Code Together

Listing 7 illustrates the parser class.

Listing 7 Base Parser Class

class ParseAnyDataType {
public:
  virtual ~ParseAnyDataType() {};
  virtual void ParseData() {};
protected:
  ParseAnyDataType() {};
};

Listing 8 illustrates the subclass of ParseAnyDataType.

Listing 8 Main ASN.1 Parser Class

class ParseDataStream : ParseAnyDataType {
public:
  explicit ParseDataStream(const char * dataSet);
  ~ParseDataStream() { }

  void parseAsnElement(const char * dataSet, int * offset, 
    int elementLength, int overallLength); // Recursive member function
  void echoDataStream(const char * dataSet, int offset);
};

The constructor for the class ParseDataStream is illustrated in Listing 9.

Listing 9 Main Parser Constructor

ParseDataStream::ParseDataStream(const char * dataSet) {
  int offset = 0;

  printf("Making the first call to parseAsnElement()\n");
  parseAsnElement(dataSet, &offset, dataSet[1], strlen(dataSet));
}

The code in Listing 9 starts the recursive processing of the ASN.1 data. The parseAsnElement() member function is called by each of the individual parsers (Listings 3–6). I mentioned at the beginning that using recursion can help produce elegant solutions. Recursion has an interesting characteristic that I’ve never seen discussed: it is a type of reuse. In effect, when you call a method recursively—as in the case of parseAsnElement()—you are reusing the code, which can facilitate a certain economy in the solution. Take a look at Listing 10 to see the complete source code for the parseAsnElement()method.

Listing 10 Recursive Member Function—parseAsnElement()

void ParseDataStream::parseAsnElement(const char * dataSet,
                    int * offset,
                    int elementLength,
                    int overallLength) {
  char dataSetType;
  int i;

  while (*offset < overallLength - 1)
  {
    dataSetType = dataSet[*offset];
    elementLength = dataSet[*offset + 1];
  

    switch (dataSetType)
    {
    case SEQ_CLASS:
      *offset += 2;
      parseAsnElement(dataSet, offset, elementLength, overallLength);
      break;
    case INT_CLASS:
      for (i = *offset + 2; i <= *offset + elementLength + 1; i++)
        printf("%x", dataSet[i]);
      printf("\n");
      *offset += 4;
      parseAsnElement(dataSet, offset, elementLength, overallLength);
      break;
    case STR_CLASS:
      printf("String character ");
      for (i = *offset + 2; i <= *offset + elementLength + 1; i++)
        printf("%c", dataSet[i]);
      printf("\n\n");
      *offset += elementLength + 1;
      parseAsnElement(dataSet, offset, elementLength, overallLength);
      break;
    default:
      printf("Unknown type\n");
    break;
    }
  }
}

I think Listing 10 achieves a lot for such a small amount of code! (Please see the "Additional Reading" section for the complete source code.) If you want to execute the code, just drop the two files into a Microsoft Visual C++ console project, build and run.

  • + Share This
  • 🔖 Save To Your Account