Mounting – Linux

Sometimes a USB external drive may not mount in Linux, could be because the the harddrive is getting to that point of I am going to give up soon so you better copy off all of the data!!!!..

Anyway, here are some basic guides to mount a external harddrive if it has not been auto mounted by udev

If you do a dmesg on the command line

dmesg 
 
[ 4454.972580] scsi 6:0:0:0: Direct-Access     Maxtor 4 D040H2           0811 PQ: 0 ANSI: 0                                                            
[ 4454.973682] sd 6:0:0:0: Attached scsi generic sg3 type 0                                                                                            
[ 4454.980992] sd 6:0:0:0: [sdc] 80043264 512-byte logical blocks: (40.9 GB/38.1 GiB)                                                                  
[ 4454.983014] sd 6:0:0:0: [sdc] Test WP failed, assume Write Enabled                                                                                  
[ 4454.983021] sd 6:0:0:0: [sdc] Assuming drive cache: write through                                                                                   
[ 4454.985201] sd 6:0:0:0: [sdc] Test WP failed, assume Write Enabled                                                                                  
[ 4454.985205] sd 6:0:0:0: [sdc] Assuming drive cache: write through                                                                                   
[ 4454.985209]  sdc: sdc1                                                                                                                              
[ 4455.022214] sd 6:0:0:0: [sdc] Test WP failed, assume Write Enabled                                                                                  
[ 4455.022218] sd 6:0:0:0: [sdc] Assuming drive cache: write through                                                                                   
[ 4455.022224] sd 6:0:0:0: [sdc] Attached SCSI disk

and get something like the above, the most interesting part is the sdc:sdc1, because this tells you where the device has been placed onto the /dev directory structure. You could also use the

lsusb

to find out where it was placed in the USB structure as well and try to mount from that device entry, but I just use the /dev/sdc ones normally, both will work through.

To mount a external drive, you need to find somewhere to place it, e.g. /mnt and then create a directory (that is not there already)

cd /mnt
mkdir USBEXT

and then mount the USB external drive, most are the type of V/FAT types so you just specify that in the type (-t) parameter

mount -t vfat /dev/sdc1 /mnt/USBEXT

the /dev/sdc1 is where it was placed and the /mnt/USBEXT was where I want it mounted and the -t was VFAT.

Function arguments – c++

There are sometimes that you want to pass more than a defined number of parameters to a function (arguments). Of course you can pass a array of parameters or just use a inbuilt stdarg.h library. This allows you to pass allot of arguments into a function, but without defining them at compile time.

For example if you want to add up a list of numbers and run time, but do not know how many to pass at the compile time then you define the function method as

int sumvalues(int numbersToBePassed, ...);

The important part is the “…”, you have to always pass in the first parameter at least, because at run time this parameter will tell the function how many additional parts to the function there will be.

Then to setup the argument list, you use the c++ library stdarg.h and this will include the function/methods that will allow this to happen.

To start with you will need to setup the argument list,

va_list args

This will setup the variable args to contain the list of additional arguments passed, then to setup where to start to pull arguments from, e.g. where the last parameter named at compile time will know, if the parameter list is like

int sumedvalues(int value1, int value2, int additionalValues, ...)

then the additionalValues is the last parameter that the compile time will know about, so to setup the pointer to the next parameter for the args variable

// for the above example
va_start(args, additionValues);
//for the code example
va_start(args, numbersToBePassed);

to pull out a argument you just need to use the va_arg function, its parameters are

va_arg(va_list, type);

where the va_list is the args variable and the type is the type that you want back, e.g. int or float.

To complete the argument list you need to end the argument pull by

va_end(va_list)

where again the va_list would be args in this example.

Here is some code that will demo the above as well.

#include <iostream>
#include <stdarg.h>
 
using namespace std;
 
int sumvalues(int numbersToBePassed, ...)
{
  int sumd =0;
  va_list args;
  va_start(args,numbersToBePassed);
 
  for (int i =0; i < numbersToBePassed; i++)
  {
    sumd +=va_arg(args,int);
  }
  va_end(args);
  return sumd;
}
 
int main()
{
  cout << "Add the values 5 4 3 5 together = " << sumvalues(4, 5,4,3,5) << endl;
  return 0;
}

With the output being

Add the values 5 4 3 5 together = 17

Regular expression – PHP

Regular expression is when you have a match condition and a string to search through. Here is a cheat sheet to download to view regular expressions syntax.

The regular matching method in php that I use is preg_match_all

int preg_match_all ( string pattern, string subject, array &matches [, int flags [, int offset]] )

which basically means that it will return a integer value of how many matches it has found within the subject text. The flags and offset are optional values.

Here is a example to pull out HTML A links within a text, A links start with <a and have some optional parameters e.g. href, title >text to display on the screen</a> (the closing tag. So in xml speak as such

<a[optional attributes]>value</a>

So the basics of searching for HTML A links within a string is to look for “” which then has the value and then the closing tag . So to put that in regular expression talk, to break it down we first search for the start <a followed by x amount of characters \s.* with a ending tag of <\/a> the “\” is there because the / is a condition statement for regular expression. And with this together it would look like

<a\s.*<\/a>

But because <\/a> happens twice in the string and either one can be the end point of the search since we are searching string values “\s.*” 0-x amount of them. \s means white space character “.” means any character that is not \n and “*” means 0 – more times of the previous check. So there is potential for a problem here we are not telling the regular expression to stop at the first < character and to this we use the [] to match some characters, the ^ in this context means any character not in this list about to come and "<" is the stopping character. So the full regular expression will be.

<a\s.[^<]*<\/a>

Here is the php code that will display all of the HTML A links from a string.

<?php
// here is a string with 2 a href links inside it and sounding text.
$matchAStr = "coding friends is my site :) <a href=\"http://www.codingfriends.com\">codingfriends.com</a> hi there.. " . 
	    " mountains are nice. <a href=\"http://www.norfolkhospice.org.uk/\">norfolkhospice.org.uk</a>" . 
	    " support the tapping house in Norfolk";
 
// the preg_match_all uses regular expression to match and pull out strings, $matches is the matches found.
 
$matched = preg_match_all("/<a\s.[^<]*<\/a>/",$matchAStr,$matches);
echo "There was $matched matche(s)\n";
 
echo "<ol>\n";
foreach($matches[0] as $url)
{
  echo "<li>".$url."</li>\n";
}
echo "</ol>\n";
?>
There was 2 matche(s)
<ol>
<li><a href="http://www.codingfriends.com">codingfriends.com</a></li>
<li><a href="http://www.norfolkhospice.org.uk/">norfolkhospice.org.uk</a></li>
</ol>

XML reader compile and link – cpp

From the post of the full code of the xml reader project, full code here.

Here is how to compile it up and also link to a basic main run method.

Compile up

g++ cppxmlreader.cpp -c

will create the cppxmlreader.o (which is the object file) if you do file on the object the outout would be

file cppxmlreader.o
cppxmlreader.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

and then using this code xmlreadmain.cpp

#include "cppxmlreader.h"
 
int main(int argv, char** argc)
{
    xmlReader xmlRead;
    xmlRead.loadFile("words.xml");
    xmlRead.printOuterXML();
    return 0;
}

This will include the header file of the cppxmlreader.h and then create a xmlReader object and load a basic file of words.xml and then print out the xml read in.

Here is the words.xml

<?xml version="1.0" encoding="UTF-8"?>
<words>
  <word attname="hi">merry</word>
  <word>old</word>
  <word>sole</word>
  <word>was</word>
  <word>he</word>
</words>

and to compile up the main run the cppxmlreader.o is the object file from the above compiling and the xmlreadmain.cpp is the main runner with -o being the output name of the executable.

g++ xmlreadmain.cpp cppxmlreader.o -o xmlreader

and if you run the xmlreader, the output should be

XML Reader Main Object (Xml main details)
XML Object
Tagname  :
Tagvalue :
Attribute 0 : Name : version Value : 1.0
Attribute 1 : Name : encoding Value : UTF-8
XML Reader xml details
XML Object
Tagname  :words
Tagvalue :
XML Object
Tagname  :word
Tagvalue :merry
Attribute 0 : Name : attname Value : hi
XML Object
Tagname  :word
Tagvalue :old
XML Object
Tagname  :word
Tagvalue :sole
XML Object
Tagname  :word
Tagvalue :was
XML Object
Tagname  :word
Tagvalue :he
XML Object
Tagname  :/words
Tagvalue :

XML reader full – cpp

Here is the full code for the header and class file from the xml reader project

Here is the cppxmlreader.h file.

#ifndef CPPXMLREADER_H
#define CPPXMLREADER_H
 
#include <string>
#include <vector>
 
// using the namespace std for the string type, vector
using namespace std;
 
const int CHARACTERLENGHT = 80;
const string BADXMLVERSION = "Xml version - first line ? - problem";
const string BADTAGNAME = "Tag name was not present";
const string BADXMLTAGEND = "End tag is not the same as tag name";
const string BADATTRIBUTE = "Attribute in wrong format attributeName=\"attributeValue\"";
 
struct xmlAttribute {
    string _attributeName, _attributeValue;
};
 
class xmlObject {
  private :
    string _tagName, _tagValue;
    vector<xmlAttribute> _attributes;
    bool _xmlMainDetails;
 
  public:
      xmlObject() { _xmlMainDetails = false;} ;
      xmlObject(string tag, string tValue, xmlAttribute attribute);
 
      void setTagName(string tagName);
      void setTagValue(string tagValue);
      void addAttributes(xmlAttribute attribute);
      void setAttributeVector(vector<xmlAttribute> setAtt);
      void setXmlMainDetails(bool value);
      bool getXmlMainDetails();
      void printOutXmlObject();
};
 
class xmlReader {
  protected:
    vector<xmlObject> _xmlMainDetails;
    vector<xmlObject> _xmlDetails;
 
  public: 
    xmlReader();
 
    // open file and read in the xml file and place into the _xmlDetails
    bool loadFile(string filename);
    void printOuterXML();
 
  private :
    xmlObject readLine(string xmlToSplitUp, string* tagName);
    string readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine);
    xmlAttribute getAttribute(string attributeString);
    vector<xmlAttribute> getAttributesFromString(string str);
};
 
 
#endif // CPPXMLREADER_H

Here is the cppxmlreader.cpp file

#include "cppxmlreader.h"
#include <iostream>
#include <string.h>
#include <fstream>
 
using namespace std;
 
/* xmlObject */
// constructor for xmlObject, if any details are passed whilst constructing 
xmlObject::xmlObject(string tag, string tValue, xmlAttribute attribute)
{
  _tagName = tag;
  _tagValue = tValue;
  _attributes.push_back(attribute);
}
 
// xml <tagname attributes="attributesvalue">VALUE</tagname>
// set the tag name
void xmlObject::setTagName(string tagName)
{
  _tagName = tagName;
}
 
// set tag value
void xmlObject::setTagValue(string tagValue)
{
  _tagValue = tagValue;
}
 
// add attributes to the vector attributes variable
void xmlObject::addAttributes(xmlAttribute attribute)
{
  _attributes.push_back(attribute);
}
 
// fill in the vector attributes variable.
void xmlObject::setAttributeVector(vector<xmlAttribute> setAtt)
{
  _attributes = setAtt;
}
 
// print out the xml object detais, with the attributes values.
void xmlObject::printOutXmlObject()
{
  cout << "XML Object" << endl;
  cout << "Tagname  :" << _tagName << endl;
  cout << "Tagvalue :" << _tagValue << endl;
  for (int i= 0; i < (int)_attributes.size(); i++)
  {
      cout << "Attribute " << i << " : Name : "<< _attributes.at(i)._attributeName << " Value : " << _attributes.at(i)._attributeValue << endl;
  }
}
 
// set the main set details value
void xmlObject::setXmlMainDetails(bool value)
{	
    _xmlMainDetails = value;
}
 
// get a boolean value to see if the xmlObject is the main <?xml .. ?> value
bool xmlObject::getXmlMainDetails()
{
  return _xmlMainDetails;
}
 
 
/*xmlReader*/
xmlReader::xmlReader()
{
}
 
// attribute is normally in the format of attributeName="attributeValue"
xmlAttribute xmlReader::getAttribute(string attributeString)
{
  xmlAttribute returnAttribute;
 
  // make sure that there is a = in the attribute string
  int findEqual = attributeString.find('=');
  if (findEqual > 0)
  {
    // set the attribute name to the substring till the equal
    returnAttribute._attributeName = attributeString.substr(0,findEqual);
    // make sure that there is some characters after the '=' sign.
    if (attributeString.length() > (findEqual+3))
    {
      returnAttribute._attributeValue = attributeString.substr(findEqual+2,(attributeString.length() - (findEqual +3)));
    }
    else
      throw BADATTRIBUTE;
  }else
    // if there does not appear to be ="" at the end of the string then throw a error.
    throw BADATTRIBUTE;
 
  return returnAttribute;
}
 
vector<xmlAttribute> xmlReader::getAttributesFromString(string str)
{
    vector<xmlAttribute> returnAtt;
    xmlAttribute attribute;
    int args;
    char st1[CHARACTERLENGHT];
 
    // args normally equals 1 because there is a attribute present
    // else there was no attribute there, just do one at a time
    args = sscanf(str.c_str(), "%s", st1);
    while (args  == 1 && (str.length() > 1)) {
      // see if there is a real attribute attributeName="attributeValue"
      try {
	attribute = getAttribute(st1);
	// push back in the vector array the attribute
	returnAtt.push_back(attribute);
      } catch (string errorStr)		// any errors
      {
	cout << "ERROR : " << errorStr << endl;
      }
      // re-do the string to pull out any more attributes.
      str = str.substr(strlen(st1));
      // see if there is any more attributes present.
      args = sscanf(str.c_str(), "%s", st1);
    }
    return returnAtt;
}
 
// scan through the xml string and pull out the tags and the attributes and value.
xmlObject xmlReader::readLine(string xmlToSplitUp, string* tagName)
{
  xmlObject returnObj;
  string returnLine, value, endTagName;
  int findXml;
 
  // pick out the tag name, if none then return and throw a bad tag name error.
  *tagName = readUntilCharacter(xmlToSplitUp, '<','>', &returnLine);
  if (tagName->length() ==0)
  {
     throw BADTAGNAME;
     return returnObj;
  }
 
  // if there is a xml version etc in the tagname then process the xml version encoding values.
  findXml=tagName->find("xml");
  if ((findXml > 0 && findXml < tagName->length()) && tagName->length() > 1 )
  {
    // this is the xml version etc.
    // there should be ? at each end of the xml version statement
    string xmlStr = readUntilCharacter(*tagName, '?','?', &returnLine);
    if (returnLine != "?") 
    {
      throw BADXMLVERSION;
      return returnObj;
    }
    // go passed the xml characters.
    returnLine = xmlStr.substr(findXml+3);
    // read any of the attributes from the string
    returnObj.setAttributeVector(getAttributesFromString(returnLine));
    // I am storing the version and any other xml details, so set the return value to store in the correct place.
    returnObj.setXmlMainDetails(true);
  }else if (tagName->length() > 1) 
  {
    // need to see if there is any attributes
    int findTagAtts = tagName->find(' ');
    if (findTagAtts < tagName->length())
    {
      // the attributes are passed the space character in the tagName variable
      string attributes = tagName->substr(findTagAtts);
      // store only the tagName in the tagName variable since pulled out the attributes
      *tagName = tagName->substr(0,findTagAtts);
      // get the attributes into a vector and store in the return object
      returnObj.setAttributeVector(getAttributesFromString(attributes));
    }
 
    if (returnLine.length() > 1)
    {
      // pull out the value in the xml line <tagname>VALUE</tagname>
      value = readUntilCharacter(returnLine,'>','<',&returnLine);
      returnObj.setTagValue(value);
    }
    if (returnLine.length() > 1)
    {
      // pick out the end tag name and make sure it is the same as the first one.
      endTagName = readUntilCharacter(returnLine,'<','>',&returnLine);
      string compareEndTag = "/"+*tagName;
      //if the end tag is not the same as the tag name then throw a error.
      if (endTagName != compareEndTag) 
      {
	throw BADXMLTAGEND;
      } 
    }
    returnObj.setTagName(*tagName);
 
   }
  return returnObj;
}
 
// pick out the characters between two character points, and also return the rest of the line.
string xmlReader::readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine)
{
  string returnString;
  // find the first occurrence of the character integer placement
  int firstChar = line.find(characterStart);
  // if there is one.
  if (firstChar >= 0)
  {
    // setup the return string, even if a second part cannot be found.
    returnString = line.substr(firstChar+1, (line.length()- firstChar)-1);
    int secChar = returnString.find(characterEnd);
    //if the secound part can be found
    if (secChar > 0)
    {
      *returnLine = returnString.substr(secChar, (returnString.length() - secChar));
      returnString = returnString.substr(0,secChar);
    }
  }
  return returnString;
}
 
// read in the XML file and place each line into the vector xmlObject 
bool xmlReader::loadFile(string filename)
{
  xmlObject xmlObj;
  string line, tagName;
 
  ifstream xmlfile(filename.c_str());
  if (xmlfile.is_open())
  {
      // if the xml version and also the encodingvalues are present.
      //getline(xmlfile,line);
 
      while (!xmlfile.eof())
      {
	  // pull out the start tag and compare against the endtag
	  getline(xmlfile,line);
	  try 
	  {
	    // pick out the xml details from line and return a xmlObject 
	    // to add to the vector array of xml objects
	    // also return the tagName if any futher processing is required.
	    xmlObj = readLine(line, &tagName);
	    // if there is ?xml version etc details present store, else store into the main xml details
	    if (xmlObj.getXmlMainDetails())
	    {
	      _xmlMainDetails.push_back(xmlObj);
	    }
	    else
	    {  
	      _xmlDetails.push_back(xmlObj);
	    }
	  }
	  // if any error occur during the reading of the xml line.
	  catch (string errorStr)
	  {
	    cout << "ERROR : " << errorStr << endl;
	  }
      }
 
      xmlfile.close();
  }
  else
  {
      cout << "Unable to open the file" << endl;
  }
}
 
/* print Out the outer XML values */
void xmlReader::printOuterXML()
{
    cout << "XML Reader Main Object (Xml main details) " << endl;
    for (int i =0; i < _xmlMainDetails.size(); i++)
      _xmlMainDetails.at(i).printOutXmlObject();
 
    cout << "XML Reader xml details" << endl;
    for (int i =0; i < _xmlDetails.size(); i++)
      _xmlDetails.at(i).printOutXmlObject();
}

Xml reader – cpp

The xml reader from the xmlreader in cpp joins together the xmlattribute and xmlobject and this last class, this one is the biggest because it does most of the work. So shall try and explain each part.

As before a xml is

<tagname attributesname="attributesvalue">value</tagname>

The main structure includes the xml definition ( ) in the _xmlMainDetails and the rest of the xml file is in _xmlDetails vectors of xmlObject.

The main file is loaded with the loadLoad ( filename ) and then printout the xml that has been loaded, shall have to do some more public functions to view etc the loaded xml file, but this is just the basics of a xml reader. The rest are private functions because they will load the xml file in the _xmlDetails variable.

class xmlReader {
  protected:
    vector<xmlObject> _xmlMainDetails;
    vector<xmlObject> _xmlDetails;
 
  public: 
    xmlReader();
 
    // open file and read in the xml file and place into the _xmlDetails
    bool loadFile(string filename);
    void printOuterXML();
 
  private :
    xmlObject readLine(string xmlToSplitUp, string* tagName);
    string readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine);
    xmlAttribute getAttribute(string attributeString);
    vector<xmlAttribute> getAttributesFromString(string str);
};

The BADATTRIBUTE are const string values that I have included at the bottom, but they are within a try {} catch {} code, so that it will throw a error to be catch.

The getAttribute, will try and obtain the attribute from a string parameter, e.g. if the string parameter is in the style of attributename=”attributevalue”, then it will store the name and value in the xmlAttribute to return back to the calling method.

/*xmlReader*/
xmlReader::xmlReader()
{
}
 
// attribute is normally in the format of attributeName="attributeValue"
xmlAttribute xmlReader::getAttribute(string attributeString)
{
  xmlAttribute returnAttribute;
 
  // make sure that there is a = in the attribute string
  int findEqual = attributeString.find('=');
  if (findEqual > 0)
  {
    // set the attribute name to the substring till the equal
    returnAttribute._attributeName = attributeString.substr(0,findEqual);
    // make sure that there is some characters after the '=' sign.
    if (attributeString.length() > (findEqual+3))
    {
      returnAttribute._attributeValue = attributeString.substr(findEqual+2,(attributeString.length() - (findEqual +3)));
    }
    else
      throw BADATTRIBUTE;
  }else
    // if there does not appear to be ="" at the end of the string then throw a error.
    throw BADATTRIBUTE;
 
  return returnAttribute;
}

The getAttributesFromString if there are 0-x amount of attributes within a string it will process each one in turn and request the above method getAttributes to actually fill in the xmlAttribute variable.

vector<xmlAttribute> xmlReader::getAttributesFromString(string str)
{
    vector<xmlAttribute> returnAtt;
    xmlAttribute attribute;
    int args;
    char st1[CHARACTERLENGHT];
 
    // args normally equals 1 because there is a attribute present
    // else there was no attribute there, just do one at a time
    args = sscanf(str.c_str(), "%s", st1);
    while (args  == 1 && (str.length() > 1)) {
      // see if there is a real attribute attributeName="attributeValue"
      try {
	attribute = getAttribute(st1);
	// push back in the vector array the attribute
	returnAtt.push_back(attribute);
      } catch (string errorStr)		// any errors
      {
	cout << "ERROR : " << errorStr << endl;
      }
      // re-do the string to pull out any more attributes.
      str = str.substr(strlen(st1));
      // see if there is any more attributes present.
      args = sscanf(str.c_str(), "%s", st1);
    }
    return returnAtt;
}

readLine, is the main part of the xml reading object. Here is the basics of what this class is doing.

If there is no tagname within a xml line, return.

If the xml line is the main definition process that style of xml line input, and pull out any attributes that are present.

Else process a normal xml line input with attributes (if present) get the value of the tag and then check to make sure that the end tag name is the same as the first tagname.

// scan through the xml string and pull out the tags and the attributes and value.
xmlObject xmlReader::readLine(string xmlToSplitUp, string* tagName)
{
  xmlObject returnObj;
  string returnLine, value, endTagName;
  int findXml;
 
  // pick out the tag name, if none then return and throw a bad tag name error.
  *tagName = readUntilCharacter(xmlToSplitUp, '<','>', &returnLine);
  if (tagName->length() ==0)
  {
     throw BADTAGNAME;
     return returnObj;
  }
 
  // if there is a xml version etc in the tagname then process the xml version encoding values.
  findXml=tagName->find("xml");
  if ((findXml > 0 && findXml < tagName->length()) && tagName->length() > 1 )
  {
    // this is the xml version etc.
    // there should be ? at each end of the xml version statement
    string xmlStr = readUntilCharacter(*tagName, '?','?', &returnLine);
    if (returnLine != "?") 
    {
      throw BADXMLVERSION;
      return returnObj;
    }
    // go passed the xml characters.
    returnLine = xmlStr.substr(findXml+3);
    // read any of the attributes from the string
    returnObj.setAttributeVector(getAttributesFromString(returnLine));
    // I am storing the version and any other xml details, so set the return value to store in the correct place.
    returnObj.setXmlMainDetails(true);
  }else if (tagName->length() > 1) 
  {
    // need to see if there is any attributes
    int findTagAtts = tagName->find(' ');
    if (findTagAtts < tagName->length())
    {
      // the attributes are passed the space character in the tagName variable
      string attributes = tagName->substr(findTagAtts);
      // store only the tagName in the tagName variable since pulled out the attributes
      *tagName = tagName->substr(0,findTagAtts);
      // get the attributes into a vector and store in the return object
      returnObj.setAttributeVector(getAttributesFromString(attributes));
    }
 
    if (returnLine.length() > 1)
    {
      // pull out the value in the xml line <tagname>VALUE</tagname>
      value = readUntilCharacter(returnLine,'>','<',&returnLine);
      returnObj.setTagValue(value);
    }
    if (returnLine.length() > 1)
    {
      // pick out the end tag name and make sure it is the same as the first one.
      endTagName = readUntilCharacter(returnLine,'<','>',&returnLine);
      string compareEndTag = "/"+*tagName;
      //if the end tag is not the same as the tag name then throw a error.
      if (endTagName != compareEndTag) 
      {
	throw BADXMLTAGEND;
      } 
    }
    returnObj.setTagName(*tagName);
 
   }
  return returnObj;
}

readUntilCharacter, is to pick out a string between two character points e.g. string = “a place to run to, here is it, codingfriends.com” and you want to pick out “here is it” there is two ‘,’ each side of it. So to pull out the readUntilCharacter(“a place to run to, here is it, codingfriends.com”, ‘,’ , ‘,’ , &returnLine) the returnLine is the rest of the line after the last character searched for.

// pick out the characters between two character points, and also return the rest of the line.
string xmlReader::readUntilCharacter(string line, char characterStart, char characterEnd, string *returnLine)
{
  string returnString;
  // find the first occurrence of the character integer placement
  int firstChar = line.find(characterStart);
  // if there is one.
  if (firstChar >= 0)
  {
    // setup the return string, even if a second part cannot be found.
    returnString = line.substr(firstChar+1, (line.length()- firstChar)-1);
    int secChar = returnString.find(characterEnd);
    //if the secound part can be found
    if (secChar > 0)
    {
      *returnLine = returnString.substr(secChar, (returnString.length() - secChar));
      returnString = returnString.substr(0,secChar);
    }
  }
  return returnString;
}

loadFile will load the xml file into the private _xmlMainDetails and _xmlDetails and just see’s if file is present and try’s to load it.

// read in the XML file and place each line into the vector xmlObject 
bool xmlReader::loadFile(string filename)
{
  xmlObject xmlObj;
  string line, tagName;
 
  ifstream xmlfile(filename.c_str());
  if (xmlfile.is_open())
  {
      // if the xml version and also the encodingvalues are present.    
      while (!xmlfile.eof())
      {
	  // pull out the start tag and compare against the endtag
	  getline(xmlfile,line);
	  try 
	  {
	    // pick out the xml details from line and return a xmlObject 
	    // to add to the vector array of xml objects
	    // also return the tagName if any futher processing is required.
	    xmlObj = readLine(line, &tagName);
	    // if there is ?xml version etc details present store, else store into the main xml details
	    if (xmlObj.getXmlMainDetails())
	    {
	      _xmlMainDetails.push_back(xmlObj);
	    }
	    else
	    {  
	      _xmlDetails.push_back(xmlObj);
	    }
	  }
	  // if any error occur during the reading of the xml line.
	  catch (string errorStr)
	  {
	    cout << "ERROR : " << errorStr << endl;
	  }
      }
 
      xmlfile.close();
  }
  else
  {
      cout << "Unable to open the file" << endl;
  }
}

Will print out the xml loaded from the xml file.

/* print Out the outer XML values */
void xmlReader::printOuterXML()
{
    cout << "XML Reader Main Object (Xml main details) " << endl;
    for (int i =0; i < _xmlMainDetails.size(); i++)
      _xmlMainDetails.at(i).printOutXmlObject();
 
    cout << "XML Reader xml details" << endl;
    for (int i =0; i < _xmlDetails.size(); i++)
      _xmlDetails.at(i).printOutXmlObject();
}

here are the constant string values.

const int CHARACTERLENGHT = 80;
const string BADXMLVERSION = "Xml version - first line ? - problem";
const string BADTAGNAME = "Tag name was not present";
const string BADXMLTAGEND = "End tag is not the same as tag name";
const string BADATTRIBUTE = "Attribute in wrong format attributeName=\"attributeValue\"";

Xml object – c++

From the main project xmlreader, here is the xml object that I created to have a xml line of code which holds the details of a basic xml.

The main basics of a xml are as below

<tagname attributesname="attributesvalue">value</tagname>

So I will need to store the tagname, attributes and the value. Here is the class structure that I did come up with.

class xmlObject {
  private :
    string _tagName, _tagValue;
    vector<xmlAttribute> _attributes;
    bool _xmlMainDetails;
 
  public:
      xmlObject() { _xmlMainDetails = false;} ;
      xmlObject(string tag, string tValue, xmlAttribute attribute);
 
      void setTagName(string tagName);
      void setTagValue(string tagValue);
      void addAttributes(xmlAttribute attribute);
      void setAttributeVector(vector<xmlAttribute> setAtt);
      void setXmlMainDetails(bool value);
      bool getXmlMainDetails();
      void printOutXmlObject();
};

The set/getXmlMainDetails are if the are at the top of the xml file and need to store them in a different place.

A vector is a nice array basically, it allows to dynamically increment the size of the array with using the push_back (and the opposite to shrink pop_back).

The basics of a vector are as below, means to have a vector of type int

vector<int> intvector;

Here is the class implementation of the object structure xmlObject

/* xmlObject */
// constructor for xmlObject, if any details are passed whilst constructing 
xmlObject::xmlObject(string tag, string tValue, xmlAttribute attribute)
{
  _tagName = tag;
  _tagValue = tValue;
  _attributes.push_back(attribute);
}
 
// xml <tagname attributes="attributesvalue">VALUE</tagname>
// set the tag name
void xmlObject::setTagName(string tagName)
{
  _tagName = tagName;
}
 
// set tag value
void xmlObject::setTagValue(string tagValue)
{
  _tagValue = tagValue;
}
 
// add attributes to the vector attributes variable
void xmlObject::addAttributes(xmlAttribute attribute)
{
  _attributes.push_back(attribute);
}
 
// fill in the vector attributes variable.
void xmlObject::setAttributeVector(vector<xmlAttribute> setAtt)
{
  _attributes = setAtt;
}
 
// print out the xml object detais, with the attributes values.
void xmlObject::printOutXmlObject()
{
  cout << "XML Object" << endl;
  cout << "Tagname  :" << _tagName << endl;
  cout << "Tagvalue :" << _tagValue << endl;
  for (int i= 0; i < (int)_attributes.size(); i++)
  {
      cout << "Attribute " << i << " : Name : "<< _attributes.at(i)._attributeName << " Value : " << _attributes.at(i)._attributeValue << endl;
  }
}
 
// set the main set details value
void xmlObject::setXmlMainDetails(bool value)
{	
    _xmlMainDetails = value;
}
 
// get a boolean value to see if the xmlObject is the main <?xml .. ?> value
bool xmlObject::getXmlMainDetails()
{
  return _xmlMainDetails;
}

I shall post on how to implement/compile etc a class in two different files later on, in a lessons basics for different languages but on the whole, if you store the top structure in a .h header file and then the implementation in a .cpp file. Of course shall post the whole code to store in .h .cpp files accordlying for the whole project but this is just a stripped down version.