author | František Kučera <franta-hg@frantovo.cz> |
Tue, 30 Jul 2019 23:56:30 +0200 | |
branch | v_0 |
changeset 6 | ddf0c5d7eda5 |
parent 2 | d1b39a9bd591 |
child 7 | c155b441306f |
permissions | -rw-r--r-- |
0
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
1 |
/** |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
2 |
* Relational pipes |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
3 |
* Copyright © 2018 František Kučera (Frantovo.cz, GlobalCode.info) |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
4 |
* |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
5 |
* This program is free software: you can redistribute it and/or modify |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
6 |
* it under the terms of the GNU General Public License as published by |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
7 |
* the Free Software Foundation, either version 3 of the License, or |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
8 |
* (at your option) any later version. |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
9 |
* |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
10 |
* This program is distributed in the hope that it will be useful, |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
11 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
12 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
13 |
* GNU General Public License for more details. |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
14 |
* |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
15 |
* You should have received a copy of the GNU General Public License |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
16 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
17 |
*/ |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
18 |
#pragma once |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
19 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
20 |
#include <iostream> |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
21 |
#include <sstream> |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
22 |
#include <string> |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
23 |
#include <vector> |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
24 |
#include <codecvt> |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
25 |
#include <locale> |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
26 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
27 |
#include <relpipe/reader/typedefs.h> |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
28 |
#include <relpipe/cli/RelpipeCLIException.h> |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
29 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
30 |
using namespace std; |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
31 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
32 |
namespace relpipe { |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
33 |
namespace out { |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
34 |
namespace asn1 { |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
35 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
36 |
using namespace relpipe::reader; |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
37 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
38 |
/** |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
39 |
* A simple library for writing ASN.1 BER encoded files. |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
40 |
*/ |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
41 |
class ASN1Writer { |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
42 |
private: |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
43 |
ostream& output; |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
44 |
wstring_convert<codecvt_utf8<wchar_t>> convertor; // only UTF8String is supported |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
45 |
int sequenceLevel = 0; |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
46 |
|
1
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
47 |
enum TagClass : uint8_t { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
48 |
/** The type is native to ASN.1 */ |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
49 |
Universal = 0, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
50 |
/** The type is only valid for one specific application */ |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
51 |
Application = 1, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
52 |
/** Meaning of this type depends on the context (such as within a sequence, set or choice) */ |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
53 |
ContextSpecific = 2, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
54 |
/** Defined in private specifications */ |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
55 |
Private = 3, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
56 |
}; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
57 |
|
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
58 |
enum PC : uint8_t { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
59 |
/** The contents octets directly encode the element value. */ |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
60 |
Primitive = 0, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
61 |
/** The contents octets contain 0, 1, or more element encodings. */ |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
62 |
Constructed = 1, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
63 |
}; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
64 |
|
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
65 |
enum UniversalType : uint16_t { |
2
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
66 |
EndOfContent = 0, |
1
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
67 |
Boolean = 1, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
68 |
Integer = 2, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
69 |
OctetString = 4, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
70 |
Null = 5, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
71 |
ObjectIdentifier = 6, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
72 |
Real = 9, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
73 |
UTF8String = 12, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
74 |
RelativeObjectIdentifier = 13, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
75 |
Sequence = 16, |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
76 |
}; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
77 |
|
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
78 |
void writeIdentifier(TagClass tagClass, PC pc, uint16_t tagNumber) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
79 |
if (tagNumber > 30) throw cli::RelpipeCLIException(L"Tag numbers higher than 30 are currently unsupported.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // should not happen, error in the program // TODO: support tag numbers > 30 |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
80 |
uint8_t tag = 0; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
81 |
tag |= tagClass << 6; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
82 |
tag |= pc << 5; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
83 |
tag |= tagNumber; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
84 |
output.put(tag); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
85 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
86 |
|
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
87 |
/** |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
88 |
* @param der |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
89 |
* @param length |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
90 |
*/ |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
91 |
template<typename N, typename = typename std::enable_if<std::is_unsigned<N>::value, N>::type> |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
92 |
void writeLength(N length) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
93 |
if (length < 128) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
94 |
output.put(length); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
95 |
} else { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
96 |
for (int i = sizeof (N) - 1; i >= 0; i--) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
97 |
uint8_t b = length >> (i * 8); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
98 |
if (b || i == 0) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
99 |
output.put((i + 1) | 0x80); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
100 |
for (; i >= 0; i--) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
101 |
b = length >> (i * 8); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
102 |
output.put(b); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
103 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
104 |
break; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
105 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
106 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
107 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
108 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
109 |
|
2
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
110 |
void writeLengthIndefinite() { |
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
111 |
output.put('\x80'); |
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
112 |
} |
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
113 |
|
1
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
114 |
static bool isLittleEndian() { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
115 |
int test = 1; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
116 |
return (*(char *) &test); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
117 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
118 |
|
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
119 |
static bool isBigEndian() { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
120 |
return !isLittleEndian(); |
0
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
121 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
122 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
123 |
public: |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
124 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
125 |
ASN1Writer(std::ostream& output) : output(output) { |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
126 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
127 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
128 |
virtual ~ASN1Writer() { |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
129 |
output.flush(); |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
130 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
131 |
|
1
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
132 |
/** |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
133 |
* Just check whether all sequences are closed. If not, throws RelpipeCLIException. |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
134 |
*/ |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
135 |
void end() { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
136 |
if (sequenceLevel) throw cli::RelpipeCLIException(L"Unable to close ASN1Writer because there are not ended sequences.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // should not happen, error in the program |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
137 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
138 |
|
0
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
139 |
void writeStartSequence() { |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
140 |
sequenceLevel++; |
2
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
141 |
writeIdentifier(TagClass::Universal, PC::Constructed, UniversalType::Sequence); |
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
142 |
writeLengthIndefinite(); |
0
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
143 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
144 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
145 |
void writeEndSequence() { |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
146 |
if (sequenceLevel == 0) throw cli::RelpipeCLIException(L"Unable to writeEndSequence() if not sequence is currently started.", cli::CLI::EXIT_CODE_UNEXPECTED_ERROR); // should not happen, error in the program |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
147 |
sequenceLevel--; |
2
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
148 |
writeIdentifier(TagClass::Universal, PC::Primitive, UniversalType::EndOfContent); |
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
149 |
writeLength(0u); |
0
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
150 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
151 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
152 |
void writeBoolean(const boolean_t& value) { |
2
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
153 |
writeIdentifier(TagClass::Universal, PC::Primitive, UniversalType::Boolean); |
d1b39a9bd591
use more writeIdentifier() and writeLength() methods
František Kučera <franta-hg@frantovo.cz>
parents:
1
diff
changeset
|
154 |
writeLength(1u); |
1
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
155 |
output.put(value ? '\xFF' : '\x00'); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
156 |
|
0
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
157 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
158 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
159 |
void writeInteger(const integer_t& value) { |
1
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
160 |
uint8_t* end = (uint8_t*) & value; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
161 |
uint8_t* start = end + sizeof (value) - 1; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
162 |
uint8_t* current; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
163 |
int direction = -1; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
164 |
|
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
165 |
if (isBigEndian()) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
166 |
std::swap(end, start); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
167 |
direction = -direction; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
168 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
169 |
|
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
170 |
// move current pointer to the first valuable octet |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
171 |
for (current = start; current != end; current += direction) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
172 |
switch (*current) { |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
173 |
case 0x00: if ((*(current + direction) & 0x80) == 0) continue; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
174 |
break; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
175 |
case 0xFF: if ((*(current + direction) & 0x80) != 0) continue; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
176 |
break; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
177 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
178 |
break; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
179 |
} |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
180 |
|
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
181 |
std::vector<char> v; |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
182 |
writeIdentifier(TagClass::Universal, PC::Primitive, UniversalType::Integer); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
183 |
writeLength((size_t) (end > current ? end - current : current - end) + 1); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
184 |
for (end += direction; current != end; current += direction) output.put(*current); |
0
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
185 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
186 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
187 |
void writeString(const string_t& value) { |
1
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
188 |
// TODO: empty string → null? |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
189 |
std::string bytes = convertor.to_bytes(value); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
190 |
writeIdentifier(TagClass::Universal, PC::Primitive, UniversalType::UTF8String); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
191 |
writeLength(bytes.length()); |
e9b4f3a9e436
first working version with ASN.1 BER output
František Kučera <franta-hg@frantovo.cz>
parents:
0
diff
changeset
|
192 |
output << bytes; |
0
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
193 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
194 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
195 |
}; |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
196 |
|
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
197 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
198 |
} |
f4f9cdf7ed59
project and code skeleton: text output
František Kučera <franta-hg@frantovo.cz>
parents:
diff
changeset
|
199 |
} |