[Tutorial] Anything to/from a hex string - Printable Version +- Support Forums (https://www.supportforums.net) +-- Forum: Categories (https://www.supportforums.net/forumdisplay.php?fid=87) +--- Forum: Coding Support Forums (https://www.supportforums.net/forumdisplay.php?fid=18) +---- Forum: Programming with C++ (https://www.supportforums.net/forumdisplay.php?fid=20) +---- Thread: [Tutorial] Anything to/from a hex string (/showthread.php?tid=4164) |
[Tutorial] Anything to/from a hex string - MrD. - 01-04-2010 This is a re-post of an article I originally posted on my website. Introduction I recently needed to be able to convert any instance of an object in C++ to a file so it could be serialised, and then restored later; I did most of this by writing out each member variable of the object individually at the most basic level. This works fine and is easy enough to implement; but then came the time to do the "generic" version, the version that could write out any object (such as a struct) as a whole. The I/O classes can write out/read in using either binary or text, the binary version of the generic writer is simply a case of writing out the length of the data, and then each byte of the data. The text version however required me to convert the bytes of data making up the object into something that was sensible as text, I decided to do this by converting each byte into a hex value and adding it to a string. As I was working on this I found that the information about how to do this without using some of the old C-style string manipulation functions is quite sparse on the net, so after much searching, trying, and failing, I now have a solution that works both ways using good old C++ string streams. I should probably point out that I don't think this solution is endian neutral, so you would likely want to add a method of endian detection and switching to ensure consistency across different architectures. The Code When a byte is encoded to hex string, each byte becomes two characters in the range 0 to F. For example, the value “10” would be written out as “0A”. The code works by using a std:tringstream with hex mode set (std::hex), along with using zero's for padding (std:etfill('0')) and a fixed width of two for each byte added as hex (std:etw(2)). The toHex function works by adding each byte of the passed data into the string stream as an integer with a width of two; because zero's have been set as padding, any numbers which are added to the stream that are only one character long will be automatically prefixed with a zero resulting in the correct two character hex value being added to the string stream. The fromHex function works by reading out two characters from the hex string into a string stream, these characters are then converted back into the byte value when read out from the string stream into an integer. Finally, the value of the integer is stored as the value of the byte, and the string is moved on to the next set of two characters. Code: // ------------------------------------------------------------------ Testing The code below can be used to test the functions. The expected output would be: Quote:SGenericData::anInt0: 10 Code: #include <iostream> RE: [Tutorial] Anything to/from a hex string - Gaijin - 01-04-2010 And now the reply on the last on my list...... AWSOME...... This wasn't really what I was looking for, but it will point me into the right direction.. I hope... Thank you for sharing this! RE: [Tutorial] Anything to/from a hex string - g4143 - 01-05-2010 I just quickly scanned your code...does it provide a method/way to handle pointers values? RE: [Tutorial] Anything to/from a hex string - MrD. - 01-05-2010 (01-05-2010, 08:34 AM)g4143 Wrote: I just quickly scanned your code...does it provide a method/way to handle pointers values? No, it just blindly works with the data it is provided. If the data you provide it contains a pointer to something than the function will just blindly write out the pointer as the memory address it is pointing at. This is just designed to be used with simple structs, and quite frankly shouldn't be used for anything else. If you want to serialise/parse a class or anything more complicated (like something with member functions) that I would strongly recommend adding serialise/parse functions to your classes that write out data member variable by member variable since it avoids all sorts of issues you can get with this method such as different compilers packing classes in different ways. This method simply exists for the writeGeneric, and readGeneric functions in my data I/O class (a function which I recommend avoiding, and only really use for writing out GUIDs). |