djiparsetxt
parseFieldWithinRecord.cpp
Go to the documentation of this file.
1 /**********
2 This program is free software: you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation, either version 3 of the License, or
5 (at your option) any later version.
6 
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11 
12 You should have received a copy of the GNU General Public License
13 along with this program. If not, see <http://www.gnu.org/licenses/>.
14 **********/
15 /*
16  A C++ program to parse DJI's ".txt" log files (recorded by the "DJI Go 4" app).
17  Version 2021-05-20
18 
19  Copyright (c) 2021 Live Networks, Inc. All rights reserved.
20  For the latest version of this program (and more information), visit http://djilogs.live555.com
21 
22  Parsing individual fields within records within DJI ".txt" files.
23  Implementation.
24 */
25 
27 
29 ::enterSubByteField(char const* label, u_int8_t byte, u_int8_t mask) {
30  // First, use "mask" to select the bits that we want, and move them to the low-order part of the byte:
31  byte &= mask;
32  while (mask != 0x00 && (mask&0x01) == 0) {
33  byte >>= 1;
34  mask >>= 1;
35  }
36 
37  fFieldDatabase->addByteField(label, byte, 0);
38 }
39 
41 ::noteByteField(char const* label, u_int8_t const*& ptr, u_int8_t const* limit,
42  float divisor, int isSigned) {
43  u_int8_t byte = getByte(ptr, limit);
44 
45  if (divisor != 0.0) {
46  // Divide by this, and store the resulting value as a 'float' instead:
47  float value = isSigned ? (int8_t)byte/divisor : byte/divisor;
48  fFieldDatabase->addFloatField(label, value);
49  } else {
50  // Normal case:
51  fFieldDatabase->addByteField(label, byte, isSigned);
52  }
53 }
54 
56 ::note2ByteField(char const* label, u_int8_t const*& ptr, u_int8_t const* limit,
57  float divisor, int16_t offset, int isSigned) {
58  u_int16_t bytes = get2BytesLE(ptr, limit);
59  bytes -= offset;
60 
61  if (divisor != 0.0) {
62  // Divide by this, and store the resulting value as a 'float' instead:
63  float value = isSigned ? (int16_t)bytes/divisor : bytes/divisor;
64  fFieldDatabase->addFloatField(label, value);
65  } else {
66  // Normal case:
67  fFieldDatabase->add2ByteField(label, bytes, isSigned);
68  }
69 }
70 
72 ::note4ByteField(char const* label, u_int8_t const*& ptr, u_int8_t const* limit,
73  float divisor, int isSigned) {
74  u_int32_t bytes = getWord32LE(ptr, limit);
75 
76  if (divisor != 0.0) {
77  // Divide by this, and store the resulting value as a 'float' instead:
78  float value = isSigned ? (int32_t)bytes/divisor : bytes/divisor;
79  fFieldDatabase->addFloatField(label, value);
80  } else {
81  // Normal case:
82  fFieldDatabase->add4ByteField(label, bytes, isSigned);
83  }
84 }
85 
87 ::note4ByteFloatField(char const* label, u_int8_t const*& ptr, u_int8_t const* limit,
88  float divisor) {
89  u_int32_t bytes = getWord32LE(ptr, limit);
90  float value = *(float*)&bytes;
91  if (divisor != 0.0) value /= divisor;
92  fFieldDatabase->addFloatField(label, value);
93 }
94 
96 ::note8ByteDoubleField(char const* label, u_int8_t const*& ptr, u_int8_t const* limit) {
97  u_int64_t bytes = getWord64LE(ptr, limit);
98  fFieldDatabase->addDoubleField(label, *(double*)&bytes);
99 }
100 
101 #ifndef PI
102 #define PI 3.14159265359
103 #endif
104 
106 ::note8ByteLatitudeOrLongitudeFieldInRadians(char const* label, u_int8_t const*& ptr, u_int8_t const* limit) {
107  u_int64_t bytes = getWord64LE(ptr, limit);
108  double* value = (double*)&bytes;
109 
110  // This value is in radians. Convert it to degrees before storing it as a 'double':
111  fFieldDatabase->addDoubleField(label, (*value)*(180/PI));
112 }
113 
115 ::note8ByteLatitudeOrLongitudeFieldInDegrees(char const* label, u_int8_t const*& ptr, u_int8_t const* limit) {
116  u_int64_t bytes = getWord64LE(ptr, limit);
117  double* value = (double*)&bytes;
118 
119  fFieldDatabase->addDoubleField(label, *value);
120 }
121 
123 ::note2ByteDateField(char const* label, u_int8_t const*& ptr, u_int8_t const* limit) {
124  u_int16_t bytes = get2BytesLE(ptr, limit);
125  fFieldDatabase->add2ByteDateField(label, bytes);
126 }
127 
129 ::note8ByteTimestampField(char const* label, u_int8_t const*& ptr, u_int8_t const* limit,
130  int isInMilliseconds) {
131  u_int64_t value = getWord64LE(ptr, limit);
132  fFieldDatabase->add8ByteTimestampField(label, value, isInMilliseconds);
133 }
134 
136 ::noteStringField(char const* label, u_int8_t const*& ptr, unsigned stringLength, u_int8_t const* limit) {
137  if (limit != NULL && ptr > limit - stringLength) throw END_OF_DATA;
138 
139  char str[stringLength+1];
140  unsigned i;
141  for (i = 0; i < stringLength; ++i) str[i] = *ptr++;
142  str[i] = '\0';
143 
144  fFieldDatabase->addStringField(label, str);
145 }
146 
148 ::note3ByteVersionField(char const* label, u_int8_t const*& ptr, u_int8_t const* limit) {
149  u_int8_t v1 = getByte(ptr, limit);
150  u_int8_t v2 = getByte(ptr, limit);
151  u_int8_t v3 = getByte(ptr, limit);
152 
153  // Pack these three bytes into a 4-byte value (big-endian), and store this:
154  u_int32_t value = (v1<<24)|(v2<<16)|(v3<<8);
155  fFieldDatabase->add4ByteVersionField(label, value);
156 }
u_int8_t getByte(u_int8_t const *&ptr, u_int8_t const *limit)
u_int64_t getWord64LE(u_int8_t const *&ptr, u_int8_t const *limit)
void note8ByteDoubleField(char const *label, u_int8_t const *&ptr, u_int8_t const *limit)
#define END_OF_DATA
Definition: DJITxtParser.hh:47
void note8ByteLatitudeOrLongitudeFieldInDegrees(char const *label, u_int8_t const *&ptr, u_int8_t const *limit)
unsigned getWord32LE(u_int8_t const *&ptr, u_int8_t const *limit)
void note8ByteLatitudeOrLongitudeFieldInRadians(char const *label, u_int8_t const *&ptr, u_int8_t const *limit)
void enterSubByteField(char const *label, u_int8_t byte, u_int8_t mask)
void note4ByteField(char const *label, u_int8_t const *&ptr, u_int8_t const *limit, float divisor=0.0, int isSigned=0)
void note8ByteTimestampField(char const *label, u_int8_t const *&ptr, u_int8_t const *limit, int isInMilliseconds=0)
void note3ByteVersionField(char const *label, u_int8_t const *&ptr, u_int8_t const *limit)
u_int16_t get2BytesLE(u_int8_t const *&ptr, u_int8_t const *limit)
void noteStringField(char const *label, u_int8_t const *&ptr, unsigned stringLength, u_int8_t const *limit)
void note2ByteField(char const *label, u_int8_t const *&ptr, u_int8_t const *limit, float divisor=0.0, int16_t offset=0, int isSigned=0)
void note4ByteFloatField(char const *label, u_int8_t const *&ptr, u_int8_t const *limit, float divisor=0.0)
#define PI
void noteByteField(char const *label, u_int8_t const *&ptr, u_int8_t const *limit, float divisor=0.0, int isSigned=0)
void note2ByteDateField(char const *label, u_int8_t const *&ptr, u_int8_t const *limit)