]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - tools/elftosb/common/Version.cpp
Unified codebase for TX28, TX48, TX51, TX53
[karo-tx-uboot.git] / tools / elftosb / common / Version.cpp
1 /*
2  * File:        Version.cpp
3  *
4  * Copyright (c) Freescale Semiconductor, Inc. All rights reserved.
5  * See included license file for license details.
6  */
7
8 #include "Version.h"
9 #include "EndianUtilities.h"
10
11 using namespace elftosb;
12
13 /*!
14  * Parses a string in the form "xxx.xxx.xxx" (where x is a digit) into
15  * three version fields for major, minor, and revision. The output is
16  * right aligned BCD in host-natural byte order.
17  *
18  * \param versionString String containing the version.
19  */
20 void version_t::set(const std::string & versionString)
21 {
22         size_t length = versionString.size();
23         unsigned version = 0;
24         unsigned index = 0;
25         
26         typedef enum {
27                 kVersionStateNone,
28                 kVersionStateMajor,
29                 kVersionStateMinor,
30                 kVersionStateRevision
31         } VersionParseState;
32         
33         // set initial versions to 0s
34         m_major = 0;
35         m_minor = 0;
36         m_revision = 0;
37         
38         VersionParseState parseState = kVersionStateNone;
39         bool done = false;
40         for (; index < length && !done; ++index)
41         {
42                 char c = versionString[index];
43                 
44                 if (isdigit(c))
45                 {
46                         switch (parseState)
47                         {
48                                 case kVersionStateNone:
49                                         parseState = kVersionStateMajor;
50                                         version = c - '0';
51                                         break;
52                                 case kVersionStateMajor:
53                                 case kVersionStateMinor:
54                                 case kVersionStateRevision:
55                                         version = (version << 4) | (c - '0');
56                                         break;
57                         }
58                 }
59                 else if (c == '.')
60                 {
61                         switch (parseState)
62                         {
63                                 case kVersionStateNone:
64                                         parseState = kVersionStateNone;
65                                         break;
66                                 case kVersionStateMajor:
67                                         m_major = version;
68                                         version = 0;
69                                         parseState = kVersionStateMinor;
70                                         break;
71                                 case kVersionStateMinor:
72                                         m_minor = version;
73                                         version = 0;
74                                         parseState = kVersionStateRevision;
75                                         break;
76                                 case kVersionStateRevision:
77                                         m_revision = version;
78                                         version = 0;
79                                         done = true;
80                                         break;
81                         }
82                 }
83                 else
84                 {
85                         switch (parseState)
86                         {
87                                 case kVersionStateNone:
88                                         parseState = kVersionStateNone;
89                                         break;
90                                 case kVersionStateMajor:
91                                         m_major = version;
92                                         done = true;
93                                         break;
94                                 case kVersionStateMinor:
95                                         m_minor = version;
96                                         done = true;
97                                         break;
98                                 case kVersionStateRevision:
99                                         m_revision = version;
100                                         done = true;
101                                         break;
102                         }
103                 }
104         }
105         
106         switch (parseState)
107         {
108                 case kVersionStateMajor:
109                         m_major = version;
110                         break;
111                 case kVersionStateMinor:
112                         m_minor = version;
113                         break;
114                 case kVersionStateRevision:
115                         m_revision = version;
116                         break;
117                 default:
118                         // do nothing
119                         break;
120         }
121 }
122
123 //! \brief Converts host endian BCD version values to the equivalent big-endian BCD values.
124 //!
125 //! The output is a half-word. And BCD is inherently big-endian, or byte ordered, if
126 //! you prefer to think of it that way. So for little endian systems, we need to convert
127 //! the output half-word in reverse byte order. When it is written to disk or a
128 //! buffer it will come out big endian.
129 //!
130 //! For example:
131 //!     - The input is BCD in host endian format, so 0x1234. Written to a file, this would
132 //!       come out as 0x34 0x12, reverse of what we want.
133 //!     - The desired BCD output is the two bytes 0x12 0x34.
134 //!     - So the function's uint16_t result must be 0x3412 on a little-endian host.
135 //!
136 //! On big endian hosts, we don't have to worry about byte swapping.
137 void version_t::fixByteOrder()
138 {
139         m_major = ENDIAN_HOST_TO_BIG_U16(m_major);
140         m_minor = ENDIAN_HOST_TO_BIG_U16(m_minor);
141         m_revision = ENDIAN_HOST_TO_BIG_U16(m_revision);
142 }
143