View | Details | Raw Unified | Return to bug 49881
Collapse All | Expand All

(-)file_not_specified_in_diff (-75 / +5340 lines)
Line  Link Here
0
-- pwlib-1.2.5.orig/include/ptclib/asner.h
0
++ pwlib-1.2.5/include/ptclib/asner.h
Lines 507-514 Link Here
507
    operator const PBYTEArray &() const { return value; }
507
    operator const PBYTEArray &() const { return value; }
508
    operator const BYTE *() const { return value; }
508
    operator const BYTE *() const { return value; }
509
    PString AsString() const;
509
    PString AsString() const;
510
    BYTE operator[](PINDEX i) const { return value[i]; }
510
    BYTE operator[](int i) const { return value[(PINDEX) i]; }
511
    BYTE & operator[](PINDEX i) { return value[i]; }
511
    BYTE & operator[](int i) { return value[(PINDEX) i]; }
512
    BYTE * GetPointer(PINDEX sz = 0) { return value.GetPointer(sz); }
512
    BYTE * GetPointer(PINDEX sz = 0) { return value.GetPointer(sz); }
513
    PINDEX GetSize() const { return value.GetSize(); }
513
    PINDEX GetSize() const { return value.GetSize(); }
514
    BOOL SetSize(PINDEX newSize) { return value.SetSize(newSize); }
514
    BOOL SetSize(PINDEX newSize) { return value.SetSize(newSize); }
515
-- pwlib-1.2.5.orig/include/ptlib/unix/ptlib/ptlib.inl
515
++ pwlib-1.2.5/include/ptlib/unix/ptlib/ptlib.inl
Lines 52-58 Link Here
52
 */
52
 */
53
53
54
#if defined(P_LINUX)
54
#if defined(P_LINUX)
55
#if (__GNUC_MINOR__ < 7)
55
#if (__GNUC_MINOR__ < 7 && __GNUC__ <= 2)
56
#include <localeinfo.h>
56
#include <localeinfo.h>
57
#else
57
#else
58
#define P_USE_LANGINFO
58
#define P_USE_LANGINFO
59
-- pwlib-1.2.5.orig/include/ptlib/array.h
59
++ pwlib-1.2.5/include/ptlib/array.h
Lines 400-407 Link Here
400
       value at the array position.
400
       value at the array position.
401
     */
401
     */
402
    T operator[](
402
    T operator[](
403
      PINDEX index  /// Position on the array to get value from.
403
	int index  /// Position on the array to get value from.
404
    ) const { return GetAt(index); }
404
    ) const { return GetAt((PINDEX) index); }
405
405
406
    /**Get a reference to value from the array. If the #index# is
406
    /**Get a reference to value from the array. If the #index# is
407
       beyond the end of the allocated array then the array is expanded. If a
407
       beyond the end of the allocated array then the array is expanded. If a
Lines 414-421 Link Here
414
       reference to value at the array position.
414
       reference to value at the array position.
415
     */
415
     */
416
    T & operator[](
416
    T & operator[](
417
      PINDEX index  /// Position on the array to get value from.
417
	int i  /// Position on the array to get value from.
418
    ) { PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory);
418
    ) { PINDEX index = i;
419
	PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory);
419
        return ((T *)theArray)[index]; }
420
        return ((T *)theArray)[index]; }
420
421
421
    /**Get a pointer to the internal array. The user may not modify the
422
    /**Get a pointer to the internal array. The user may not modify the
Lines 482-488 Link Here
482
    virtual PObject * Clone() const \
483
    virtual PObject * Clone() const \
483
      { return PNEW cls(*this, GetSize()); } \
484
      { return PNEW cls(*this, GetSize()); } \
484
485
485
486
#else // PHAS_TEMPLATES
486
#else // PHAS_TEMPLATES
487
487
488
#define PBASEARRAY(cls, T) \
488
#define PBASEARRAY(cls, T) \
Lines 502-511 Link Here
502
    inline P_##cls##_Base_Type GetAt(PINDEX index) const \
502
    inline P_##cls##_Base_Type GetAt(PINDEX index) const \
503
      { PASSERTINDEX(index); return index < GetSize() ? \
503
      { PASSERTINDEX(index); return index < GetSize() ? \
504
          ((P_##cls##_Base_Type*)theArray)[index] : (P_##cls##_Base_Type)0; } \
504
          ((P_##cls##_Base_Type*)theArray)[index] : (P_##cls##_Base_Type)0; } \
505
    inline P_##cls##_Base_Type operator[](PINDEX index) const \
505
    inline P_##cls##_Base_Type operator[](int index) const \
506
      { PASSERTINDEX(index); return GetAt(index); } \
506
      { PASSERTINDEX((PINDEX) index); return GetAt((PINDEX) index); } \
507
    inline P_##cls##_Base_Type & operator[](PINDEX index) \
507
    inline P_##cls##_Base_Type & operator[](int i) \
508
      { PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory); \
508
      { PINDEX index = i; PASSERTINDEX(index); PAssert(SetMinSize(index+1), POutOfMemory); \
509
        return ((P_##cls##_Base_Type *)theArray)[index]; } \
509
        return ((P_##cls##_Base_Type *)theArray)[index]; } \
510
    inline void Attach(const P_##cls##_Base_Type * buffer, PINDEX bufferSize) \
510
    inline void Attach(const P_##cls##_Base_Type * buffer, PINDEX bufferSize) \
511
      { PAbstractArray::Attach(buffer, bufferSize); } \
511
      { PAbstractArray::Attach(buffer, bufferSize); } \
512
-- pwlib-1.2.5.orig/include/ptlib/channel.h
512
++ pwlib-1.2.5/include/ptlib/channel.h
Lines 175-181 Link Here
175
    virtual int overflow(int=EOF);
175
    virtual int overflow(int=EOF);
176
    virtual int underflow();
176
    virtual int underflow();
177
    virtual int sync();
177
    virtual int sync();
178
#ifdef __MWERKS__
178
#if defined(__MWERKS__) || defined(GCC3)
179
    virtual streampos seekoff(streamoff, ios::seekdir, ios::openmode);
179
    virtual streampos seekoff(streamoff, ios::seekdir, ios::openmode);
180
#else
180
#else
181
    virtual streampos seekoff(streamoff, ios::seek_dir, int);
181
    virtual streampos seekoff(streamoff, ios::seek_dir, int);
182
-- pwlib-1.2.5.orig/include/ptlib/object.h
182
++ pwlib-1.2.5/include/ptlib/object.h
Lines 289-294 Link Here
289
#include <stdlibx.h>
289
#include <stdlibx.h>
290
#endif
290
#endif
291
291
292
#if (__GNUC__ >= 3)
293
using namespace std;
294
#endif
295
292
///////////////////////////////////////////////////////////////////////////////
296
///////////////////////////////////////////////////////////////////////////////
293
// Disable inlines when debugging for faster compiles (the compiler doesn't
297
// Disable inlines when debugging for faster compiles (the compiler doesn't
294
// actually inline the function with debug on any way).
298
// actually inline the function with debug on any way).
295
-- pwlib-1.2.5.orig/include/ptlib/osutil.inl
299
++ pwlib-1.2.5/include/ptlib/osutil.inl
Lines 464-470 Link Here
464
          PChannelStreamBuffer::operator=(const PChannelStreamBuffer & sbuf)
464
          PChannelStreamBuffer::operator=(const PChannelStreamBuffer & sbuf)
465
  { channel = sbuf.channel; return *this; }
465
  { channel = sbuf.channel; return *this; }
466
466
467
PINLINE PChannel::PChannel(const PChannel &)
467
PINLINE PChannel::PChannel(const PChannel &) : iostream(cout.rdbuf())
468
  { PAssertAlways("Cannot copy channels"); }
468
  { PAssertAlways("Cannot copy channels"); }
469
469
470
PINLINE PChannel & PChannel::operator=(const PChannel &)
470
PINLINE PChannel & PChannel::operator=(const PChannel &)
471
-- pwlib-1.2.5.orig/include/ptlib/pstring.h
471
++ pwlib-1.2.5/include/ptlib/pstring.h
Lines 1860-1866 Link Here
1860
    virtual void AssignContents(const PContainer & cont);
1860
    virtual void AssignContents(const PContainer & cont);
1861
1861
1862
  private:
1862
  private:
1863
    PStringStream(int, const PStringStream &) { }
1863
    PStringStream(int, const PStringStream &) : iostream(cout.rdbuf()) { }
1864
1864
1865
    class Buffer : public streambuf {
1865
    class Buffer : public streambuf {
1866
      public:
1866
      public:
Lines 1870-1876 Link Here
1870
        virtual int overflow(int=EOF);
1870
        virtual int overflow(int=EOF);
1871
        virtual int underflow();
1871
        virtual int underflow();
1872
        virtual int sync();
1872
        virtual int sync();
1873
#ifdef __MWERKS__
1873
#if defined(__MWERKS__) || defined(GCC3)
1874
        virtual streampos seekoff(streamoff, ios::seekdir, ios::openmode);
1874
        virtual streampos seekoff(streamoff, ios::seekdir, ios::openmode);
1875
#else
1875
#else
1876
        virtual streampos seekoff(streamoff, ios::seek_dir, int);
1876
        virtual streampos seekoff(streamoff, ios::seek_dir, int);
1877
-- pwlib-1.2.5.orig/include/ptlib/svcproc.h
1877
++ pwlib-1.2.5/include/ptlib/svcproc.h
Lines 140-146 Link Here
140
    /// Create a system log stream
140
    /// Create a system log stream
141
    PSystemLog(
141
    PSystemLog(
142
     Level level   /// only messages at this level or higher will be logged
142
     Level level   /// only messages at this level or higher will be logged
143
    ) { logLevel = level; buffer.log = this; init(&buffer); }
143
    ) : iostream(cout.rdbuf()) { logLevel = level; buffer.log = this; init(&buffer); }
144
144
145
    /// Destroy the string stream, deleting the stream buffer
145
    /// Destroy the string stream, deleting the stream buffer
146
    ~PSystemLog() { flush(); }
146
    ~PSystemLog() { flush(); }
Lines 174-180 Link Here
174
  //@}
174
  //@}
175
175
176
  private:
176
  private:
177
    PSystemLog(const PSystemLog &) { }
177
    PSystemLog(const PSystemLog &) : iostream(cout.rdbuf()) { }
178
    PSystemLog & operator=(const PSystemLog &) { return *this; }
178
    PSystemLog & operator=(const PSystemLog &) { return *this; }
179
179
180
    class Buffer : public streambuf {
180
    class Buffer : public streambuf {
181
-- pwlib-1.2.5.orig/src/ptclib/asner.cxx
181
++ pwlib-1.2.5/src/ptclib/asner.cxx
Lines 4338-4344 Link Here
4338
    return -1;
4338
    return -1;
4339
4339
4340
  value += lower;
4340
  value += lower;
4341
  return 0;
4341
  
4342
  // clamp value to upper limit
4343
  if (value > upper)
4344
    value = upper;
4345
  
4346
 return 0;
4342
}
4347
}
4343
4348
4344
4349
Lines 4377-4383 Link Here
4377
    unsigned base;
4382
    unsigned base;
4378
    if (!MultiBitDecode(CountBits(upper - lower + 1), base))
4383
    if (!MultiBitDecode(CountBits(upper - lower + 1), base))
4379
      return -1;
4384
      return -1;
4380
    return lower + base;   // 10.9.4.1
4385
    len = lower + base;   // 10.9.4.1
4386
4387
    // clamp value to upper limit
4388
    if (len > upper)
4389
      len = upper;
4390
    
4391
    return 0;
4381
  }
4392
  }
4382
4393
4383
  if (upper < 65536)  // 10.9.3.3
4394
  if (upper < 65536)  // 10.9.3.3
Lines 4388-4400 Link Here
4388
  if (IsAtEnd())
4399
  if (IsAtEnd())
4389
    return -1;
4400
    return -1;
4390
4401
4391
  if (SingleBitDecode() == 0)
4402
  if (SingleBitDecode() == 0) {
4392
    return MultiBitDecode(7, len) ? 0 : -1;   // 10.9.3.6
4403
    if (!MultiBitDecode(7, len))   // 10.9.3.6
4393
4404
      return -1;                // 10.9.3.8 unsupported
4394
  if (SingleBitDecode() == 0)
4405
  }
4395
    return MultiBitDecode(14, len) ? 0 : -1;    // 10.9.3.7
4406
  else if (SingleBitDecode() == 0) {
4407
    if (!MultiBitDecode(14, len))    // 10.9.3.7
4408
      return -1;  // 10.9.3.8 unsupported
4409
  }
4396
4410
4397
  return -1;  // 10.9.3.8 unsupported
4411
  // clamp value to upper limit
4412
  if (len > upper)
4413
    len = upper;
4414
  
4415
  return 0;
4398
}
4416
}
4399
4417
4400
4418
4401
-- pwlib-1.2.5.orig/src/ptclib/asner.cxx.orig
4419
++ pwlib-1.2.5/src/ptclib/asner.cxx.orig
Line 0 Link Here
0
-- pwlib-1.2.5.orig/src/ptlib/common/contain.cxx
1
/*
2
 * asner.cxx
3
 *
4
 * Abstract Syntax Notation 1 Encoding Rules
5
 *
6
 * Portable Windows Library
7
 *
8
 * Copyright (c) 1993-1998 Equivalence Pty. Ltd.
9
 *
10
 * The contents of this file are subject to the Mozilla Public License
11
 * Version 1.0 (the "License"); you may not use this file except in
12
 * compliance with the License. You may obtain a copy of the License at
13
 * http://www.mozilla.org/MPL/
14
 *
15
 * Software distributed under the License is distributed on an "AS IS"
16
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
17
 * the License for the specific language governing rights and limitations
18
 * under the License.
19
 *
20
 * The Original Code is Portable Windows Library.
21
 *
22
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
23
 *
24
 * Portions are Copyright (C) 1993 Free Software Foundation, Inc.
25
 * All Rights Reserved.
26
 *
27
 * Contributor(s): ______________________________________.
28
 *
29
 * $Log: asner.cxx,v $
30
 * Revision 1.53  2001/09/14 05:26:11  robertj
31
 * Fixed problem with assigning a PASN_Choice to itself, thanks Chih-Wei Huang
32
 *
33
 * Revision 1.52  2001/09/14 01:59:59  robertj
34
 * Fixed problem with incorrectly initialised PASN_Choice sub-object.
35
 *
36
 * Revision 1.51  2001/08/08 04:19:28  robertj
37
 * Fixed PString<->BMPString conversion so can have embedded nulls.
38
 *
39
 * Revision 1.50  2001/08/07 04:37:03  robertj
40
 * Simplified &#num; parsing.
41
 *
42
 * Revision 1.49  2001/08/07 02:49:05  robertj
43
 * Fixed incorrect alignment if constrained string upper bound is exactly
44
 *     16 bits long. thanks Guntram Diehl & Thomas Arimont.
45
 *
46
 * Revision 1.48  2001/08/06 09:35:25  robertj
47
 * Fixed GNU compatibility.
48
 *
49
 * Revision 1.47  2001/08/06 09:31:48  robertj
50
 * Added conversion of BMPString to PString without losing special characters.
51
 *
52
 * Revision 1.46  2001/08/06 01:39:02  robertj
53
 * Added assignement operator with RHS of PASN_BMPString to classes
54
 *   descended from PASN_BMPString.
55
 *
56
 * Revision 1.45  2001/06/14 02:14:12  robertj
57
 * Added functions to encode and decode another ASN type that is inside
58
 *   an octet string, useful for ANY or EXTERNAL types etc.
59
 *
60
 * Revision 1.44  2001/05/29 00:59:16  robertj
61
 * Fixed excessive padding on constrained strings.
62
 *
63
 * Revision 1.43  2001/05/22 23:37:42  robertj
64
 * Fixed problem with assigning a constrained string value to itself, which
65
 *   can occur when changing constraints.
66
 *
67
 * Revision 1.42  2001/04/30 10:47:33  robertj
68
 * Fixed stupid error in last patch.
69
 *
70
 * Revision 1.41  2001/04/30 06:47:04  robertj
71
 * Fixed problem with en/decoding more than 16 extension fields in a sequence.
72
 *
73
 * Revision 1.40  2001/04/26 08:15:58  robertj
74
 * Fixed problem with ASN compile of single constraints on enumerations.
75
 *
76
 * Revision 1.39  2001/04/23 05:46:06  robertj
77
 * Fixed problem with unconstrained PASN_NumericString coding in 8 bits
78
 *   instead of 4, thanks Chew Kuan.
79
 *
80
 * Revision 1.38  2001/04/23 04:40:14  robertj
81
 * Added ASN standard types GeneralizedTime and UTCTime
82
 *
83
 * Revision 1.37  2001/04/12 03:26:59  robertj
84
 * Fixed PASN_Boolean cosntructor to be compatible with usage in ASN parser.
85
 * Changed all PASN_xxx types so constructor can take real type as only
86
 *   parameter. eg PASN_OctetString s = "fred";
87
 * Changed block encode/decode so does not do a ByteAlign() if zero
88
 *   length, required for interoperability even though spec implies otherwise..
89
 *
90
 * Revision 1.36  2001/01/24 04:37:07  robertj
91
 * Added more bulletproofing to ASN structures to obey constraints.
92
 *
93
 * Revision 1.35  2001/01/03 01:20:13  robertj
94
 * Fixed error in BlockEncode, should ByteAlign() even on zero length strings.
95
 *
96
 * Revision 1.34  2000/10/26 11:09:16  robertj
97
 * More bullet proofing of PER decoder, changed bit type to be unsigned.
98
 *
99
 * Revision 1.33  2000/10/26 01:29:32  robertj
100
 * Fixed MSVC warning.
101
 *
102
 * Revision 1.32  2000/10/25 04:05:38  robertj
103
 * More bullet proofing of PER decoder.
104
 *
105
 * Revision 1.31  2000/09/29 04:11:51  robertj
106
 * Fixed possible out of range memory access, thanks Petr Parýzek <paryzek@wo.cz>
107
 *
108
 * Revision 1.30  2000/02/29 06:32:12  robertj
109
 * Added ability to remove optional field in sequence, thanks Dave Harvey.
110
 *
111
 * Revision 1.29  2000/01/20 06:22:22  robertj
112
 * Fixed boundary condition error for constrained integer encoding (values 1, 256 etc)
113
 *
114
 * Revision 1.28  1999/11/22 23:15:43  robertj
115
 * Fixed bug in PASN_Choice::Compare(), should make sure choices are the same before comparing.
116
 *
117
 * Revision 1.27  1999/08/19 15:43:07  robertj
118
 * Fixed incorrect size of OID if zero length encoded.
119
 *
120
 * Revision 1.26  1999/08/09 13:02:45  robertj
121
 * dded ASN compiler #defines for backward support of pre GCC 2.9 compilers.
122
 * Added ASN compiler #defines to reduce its memory footprint.
123
 *
124
 * Revision 1.25  1999/08/08 15:45:59  robertj
125
 * Fixed incorrect encoding of unknown extensions.
126
 *
127
 * Revision 1.24  1999/08/05 00:44:28  robertj
128
 * Fixed PER encoding problems for large integer values.
129
 *
130
 * Revision 1.23  1999/07/22 06:48:54  robertj
131
 * Added comparison operation to base ASN classes and compiled ASN code.
132
 * Added support for ANY type in ASN parser.
133
 *
134
 * Revision 1.22  1999/07/08 08:39:12  robertj
135
 * Fixed bug when assigning negative number ot cosntrained PASN_Integer
136
 *
137
 * Revision 1.21  1999/06/30 08:58:12  robertj
138
 * Fixed bug in encoding/decoding OID greater than 2.39
139
 *
140
 * Revision 1.20  1999/06/17 13:27:09  robertj
141
 * Fixed bug causing crashes on pass through of unknown extensions.
142
 *
143
 * Revision 1.19  1999/06/07 00:31:25  robertj
144
 * Fixed signed/unsigned problem with number of unknown extensions check.
145
 *
146
 * Revision 1.18  1999/04/26 05:58:48  craigs
147
 * Fixed problems with encoding of extensions
148
 *
149
 * Revision 1.17  1999/03/09 08:12:38  robertj
150
 * Fixed problem with closing a steam encoding twice.
151
 *
152
 * Revision 1.16  1999/01/16 01:28:25  robertj
153
 * Fixed problems with reading stream multiple times.
154
 *
155
 * Revision 1.15  1998/11/30 04:50:44  robertj
156
 * New directory structure
157
 *
158
 * Revision 1.14  1998/10/22 04:33:11  robertj
159
 * Fixed bug in constrained strings and PER, incorrect order of character set.
160
 *
161
 * Revision 1.13  1998/09/23 06:21:49  robertj
162
 * Added open source copyright license.
163
 *
164
 * Revision 1.12  1998/05/26 05:29:23  robertj
165
 * Workaroung for g++ iostream bug.
166
 *
167
 * Revision 1.11  1998/05/21 04:58:54  robertj
168
 * GCC comptaibility.
169
 *
170
 * Revision 1.10  1998/05/21 04:26:54  robertj
171
 * Fixed numerous PER problems.
172
 *
173
 * Revision 1.9  1998/05/11 06:01:55  robertj
174
 * Why did this compile under MSC?
175
 *
176
 * Revision 1.8  1998/05/07 05:19:29  robertj
177
 * Fixed problems with using copy constructor/assignment oeprator on PASN_Objects.
178
 *
179
 * Revision 1.7  1998/03/05 12:49:50  robertj
180
 * MemCheck fixes.
181
 *
182
 * Revision 1.6  1998/02/03 06:28:27  robertj
183
 * Fixed length calculation of integers in BER.
184
 * Added new function to read a block with minimum number of bytes.
185
 *
186
 * Revision 1.5  1998/01/26 01:51:20  robertj
187
 * Removed uninitialised variable warnings.
188
 *
189
 * Revision 1.4  1997/12/18 05:07:56  robertj
190
 * Fixed bug in choice name display.
191
 * Added function to get choice discriminator name.
192
 * Fixed bug in encoding extensions.
193
 *
194
 * Revision 1.3  1997/12/11 10:36:22  robertj
195
 * Support for new ASN parser.
196
 *
197
 */
198
199
#include <ptlib.h>
200
201
#ifdef __GNUC__
202
#pragma implementation "asner.h"
203
#endif
204
205
#include <ptclib/asner.h>
206
207
#define new PNEW
208
209
210
static PINDEX CountBits(unsigned range)
211
{
212
  if (range == 0)
213
    return sizeof(unsigned)*8;
214
215
  PINDEX nBits = 0;
216
  while (nBits < (sizeof(unsigned)*8) && range > (unsigned)(1 << nBits))
217
    nBits++;
218
  return nBits;
219
}
220
221
222
///////////////////////////////////////////////////////////////////////
223
224
PASN_Object::PASN_Object(unsigned theTag, TagClass theTagClass, BOOL extend)
225
{
226
  extendable = extend;
227
228
  tag = theTag;
229
230
  if (theTagClass != DefaultTagClass)
231
    tagClass = theTagClass;
232
  else
233
    tagClass = ContextSpecificTagClass;
234
}
235
236
237
void PASN_Object::SetTag(unsigned newTag, TagClass tagClass_)
238
{
239
  tag = newTag;
240
  if (tagClass_ != DefaultTagClass)
241
    tagClass = tagClass_;
242
}
243
244
245
PINDEX PASN_Object::GetObjectLength() const
246
{
247
  PINDEX len = 1;
248
249
  if (tag >= 31)
250
    len += (CountBits(tag)+6)/7;
251
252
  PINDEX dataLen = GetDataLength();
253
  if (dataLen < 128)
254
    len++;
255
  else
256
    len += (CountBits(dataLen)+7)/8 + 1;
257
258
  return len + dataLen;
259
}
260
261
262
void PASN_Object::SetConstraintBounds(ConstraintType, int, unsigned)
263
{
264
}
265
266
267
void PASN_Object::SetCharacterSet(ConstraintType, const char *)
268
{
269
}
270
271
272
void PASN_Object::SetCharacterSet(ConstraintType, unsigned, unsigned)
273
{
274
}
275
276
277
///////////////////////////////////////////////////////////////////////
278
279
PASN_ConstrainedObject::PASN_ConstrainedObject(unsigned tag, TagClass tagClass)
280
  : PASN_Object(tag, tagClass)
281
{
282
  constraint = Unconstrained;
283
  lowerLimit = 0;
284
  upperLimit =  UINT_MAX;
285
}
286
287
288
void PASN_ConstrainedObject::SetConstraintBounds(ConstraintType ctype,
289
                                                 int lower, unsigned upper)
290
{
291
  constraint = ctype;
292
  if (constraint == Unconstrained) {
293
    lower = 0;
294
    upper = UINT_MAX;
295
  }
296
297
  extendable = ctype == ExtendableConstraint;
298
  PAssert((lower >= 0 || upper < 0x7fffffff) &&
299
          (lower < 0 || (unsigned)lower <= upper), PInvalidParameter);
300
  lowerLimit = lower;
301
  upperLimit = upper;
302
}
303
304
305
int PASN_ConstrainedObject::ConstrainedLengthDecode(PPER_Stream & strm, unsigned & length)
306
{
307
  // The execution order is important in the following. The SingleBitDecode() function
308
  // must be called if extendable is TRUE, no matter what.
309
  if ((extendable && strm.SingleBitDecode()) || constraint == Unconstrained)
310
    return strm.LengthDecode(0, INT_MAX, length);
311
  else
312
    return strm.LengthDecode(lowerLimit, upperLimit, length);
313
}
314
315
316
void PASN_ConstrainedObject::ConstrainedLengthEncode(PPER_Stream & strm, unsigned length) const
317
{
318
  if (ConstraintEncode(strm, length)) // 26.4
319
    strm.LengthEncode(length, 0, INT_MAX);
320
  else
321
    strm.LengthEncode(length, lowerLimit, upperLimit);
322
}
323
324
325
BOOL PASN_ConstrainedObject::ConstraintEncode(PPER_Stream & strm, unsigned value) const
326
{
327
  if (!extendable)
328
    return constraint != FixedConstraint;
329
330
  BOOL needsExtending = value > upperLimit;
331
332
  if (!needsExtending) {
333
    if (lowerLimit < 0) {
334
      if ((int)value < lowerLimit)
335
        needsExtending = TRUE;
336
    }
337
    else {
338
      if (value < (unsigned)lowerLimit)
339
        needsExtending = TRUE;
340
    }
341
  }
342
343
  strm.SingleBitEncode(needsExtending);
344
345
  return needsExtending || constraint != FixedConstraint;
346
}
347
348
349
///////////////////////////////////////////////////////////////////////
350
351
PASN_Null::PASN_Null(unsigned tag, TagClass tagClass)
352
  : PASN_Object(tag, tagClass)
353
{
354
}
355
356
357
PObject::Comparison PASN_Null::Compare(const PObject & obj) const
358
{
359
  PAssert(obj.IsDescendant(PASN_Null::Class()), PInvalidCast);
360
  return EqualTo;
361
}
362
363
364
PObject * PASN_Null::Clone() const
365
{
366
  PAssert(IsClass(PASN_Null::Class()), PInvalidCast);
367
  return new PASN_Null(*this);
368
}
369
370
371
void PASN_Null::PrintOn(ostream & strm) const
372
{
373
  strm << "<<null>>";
374
}
375
376
377
PString PASN_Null::GetTypeAsString() const
378
{
379
  return "Null";
380
}
381
382
383
PINDEX PASN_Null::GetDataLength() const
384
{
385
  return 0;
386
}
387
388
389
BOOL PASN_Null::Decode(PASN_Stream & strm)
390
{
391
  return strm.NullDecode(*this);
392
}
393
394
395
void PASN_Null::Encode(PASN_Stream & strm) const
396
{
397
  strm.NullEncode(*this);
398
}
399
400
401
BOOL PBER_Stream::NullDecode(PASN_Null & value)
402
{
403
  unsigned len;
404
  if (!HeaderDecode(value, len))
405
    return FALSE;
406
407
  byteOffset += len;
408
  return TRUE;
409
}
410
411
412
void PBER_Stream::NullEncode(const PASN_Null & value)
413
{
414
  HeaderEncode(value);
415
}
416
417
418
BOOL PPER_Stream::NullDecode(PASN_Null &)
419
{
420
  return TRUE;
421
}
422
423
424
void PPER_Stream::NullEncode(const PASN_Null &)
425
{
426
}
427
428
429
///////////////////////////////////////////////////////////////////////
430
431
PASN_Boolean::PASN_Boolean(BOOL val)
432
  : PASN_Object(UniversalBoolean, UniversalTagClass)
433
{
434
  value = val;
435
}
436
437
438
PASN_Boolean::PASN_Boolean(unsigned tag, TagClass tagClass, BOOL val)
439
  : PASN_Object(tag, tagClass)
440
{
441
  value = val;
442
}
443
444
445
PObject::Comparison PASN_Boolean::Compare(const PObject & obj) const
446
{
447
  PAssert(obj.IsDescendant(PASN_Boolean::Class()), PInvalidCast);
448
  return value == ((const PASN_Boolean &)obj).value ? EqualTo : GreaterThan;
449
}
450
451
452
PObject * PASN_Boolean::Clone() const
453
{
454
  PAssert(IsClass(PASN_Boolean::Class()), PInvalidCast);
455
  return new PASN_Boolean(*this);
456
}
457
458
459
void PASN_Boolean::PrintOn(ostream & strm) const
460
{
461
  if (value)
462
    strm << "TRUE";
463
  else
464
    strm << "FALSE";
465
}
466
467
468
PString PASN_Boolean::GetTypeAsString() const
469
{
470
  return "Boolean";
471
}
472
473
474
PINDEX PASN_Boolean::GetDataLength() const
475
{
476
  return 1;
477
}
478
479
480
BOOL PASN_Boolean::Decode(PASN_Stream & strm)
481
{
482
  return strm.BooleanDecode(*this);
483
}
484
485
486
void PASN_Boolean::Encode(PASN_Stream & strm) const
487
{
488
  strm.BooleanEncode(*this);
489
}
490
491
492
BOOL PBER_Stream::BooleanDecode(PASN_Boolean & value)
493
{
494
  unsigned len;
495
  if (!HeaderDecode(value, len))
496
    return FALSE;
497
498
  while (len-- > 0) {
499
    if (IsAtEnd())
500
      return FALSE;
501
    value = (BOOL)ByteDecode();
502
  }
503
504
  return TRUE;
505
}
506
507
508
void PBER_Stream::BooleanEncode(const PASN_Boolean & value)
509
{
510
  HeaderEncode(value);
511
  ByteEncode((BOOL)value);
512
}
513
514
515
BOOL PPER_Stream::BooleanDecode(PASN_Boolean & value)
516
{
517
  if (IsAtEnd())
518
    return FALSE;
519
520
  // X.931 Section 11
521
  value = (BOOL)SingleBitDecode();
522
  return TRUE;
523
}
524
525
526
void PPER_Stream::BooleanEncode(const PASN_Boolean & value)
527
{
528
  // X.931 Section 11
529
  SingleBitEncode((BOOL)value);
530
}
531
532
533
///////////////////////////////////////////////////////////////////////
534
535
PASN_Integer::PASN_Integer(unsigned val)
536
  : PASN_ConstrainedObject(UniversalInteger, UniversalTagClass)
537
{
538
  value = val;
539
}
540
541
542
PASN_Integer::PASN_Integer(unsigned tag, TagClass tagClass, unsigned val)
543
  : PASN_ConstrainedObject(tag, tagClass)
544
{
545
  value = val;
546
}
547
548
549
PASN_Integer & PASN_Integer::operator=(unsigned val)
550
{
551
  if (constraint == Unconstrained)
552
    value = val;
553
  else if (lowerLimit >= 0) { // Is unsigned integer
554
    if (val < (unsigned)lowerLimit)
555
      value = lowerLimit;
556
    else if (val > upperLimit)
557
      value = upperLimit;
558
    else
559
      value = val;
560
  }
561
  else {
562
    int ival = (int)val;
563
    if (ival < lowerLimit)
564
      value = lowerLimit;
565
    else if (upperLimit < INT_MAX && ival > (int)upperLimit)
566
      value = upperLimit;
567
    else
568
      value = val;
569
  }
570
571
  return *this;
572
}
573
574
575
PObject::Comparison PASN_Integer::Compare(const PObject & obj) const
576
{
577
  PAssert(obj.IsDescendant(PASN_Integer::Class()), PInvalidCast);
578
  const PASN_Integer & other = (const PASN_Integer &)obj;
579
580
  if (value < other.value)
581
    return LessThan;
582
583
  if (value > other.value)
584
    return GreaterThan;
585
586
  return EqualTo;
587
}
588
589
590
PObject * PASN_Integer::Clone() const
591
{
592
  PAssert(IsClass(PASN_Integer::Class()), PInvalidCast);
593
  return new PASN_Integer(*this);
594
}
595
596
597
void PASN_Integer::PrintOn(ostream & strm) const
598
{
599
  if (lowerLimit < 0)
600
    strm << (int)value;
601
  else
602
    strm << value;
603
}
604
605
606
void PASN_Integer::SetConstraintBounds(ConstraintType type, int lower, unsigned upper)
607
{
608
  PASN_ConstrainedObject::SetConstraintBounds(type, lower, upper);
609
  if (constraint != Unconstrained) {
610
    if ((int)value < lowerLimit)
611
      value = lowerLimit;
612
    else if (value > upperLimit)
613
      value = upperLimit;
614
  }
615
}
616
617
618
PString PASN_Integer::GetTypeAsString() const
619
{
620
  return "Integer";
621
}
622
623
624
static PINDEX GetIntegerDataLength(int value)
625
{
626
  // create a mask which is the top nine bits of a DWORD, or 0xFF800000
627
  // on a big endian machine
628
  int shift = (sizeof(value)-1)*8-1;
629
630
  // remove all sequences of nine 0's or 1's at the start of the value
631
  while (shift > 0 && ((value >> shift)&0x1ff) == (value < 0 ? 0x1ff : 0))
632
    shift -= 8;
633
634
  return (shift+9)/8;
635
}
636
637
638
PINDEX PASN_Integer::GetDataLength() const
639
{
640
  return GetIntegerDataLength(value);
641
}
642
643
644
BOOL PASN_Integer::Decode(PASN_Stream & strm)
645
{
646
  return strm.IntegerDecode(*this);
647
}
648
649
650
void PASN_Integer::Encode(PASN_Stream & strm) const
651
{
652
  strm.IntegerEncode(*this);
653
}
654
655
656
BOOL PBER_Stream::IntegerDecode(PASN_Integer & value)
657
{
658
  unsigned len;
659
  if (!HeaderDecode(value, len) || len == 0 || IsAtEnd())
660
    return FALSE;
661
662
  int accumulator = (char)ByteDecode(); // sign extended first byte
663
  while (--len > 0) {
664
    if (IsAtEnd())
665
      return FALSE;
666
    accumulator = (accumulator << 8) | ByteDecode();
667
  }
668
669
  value = accumulator;
670
  return TRUE;
671
}
672
673
674
void PBER_Stream::IntegerEncode(const PASN_Integer & value)
675
{
676
  HeaderEncode(value);
677
  // output the integer bits
678
  for (int count = GetIntegerDataLength(value)-1; count >= 0; count--)
679
    ByteEncode(value >> (count*8));
680
}
681
682
683
BOOL PPER_Stream::IntegerDecode(PASN_Integer & value)
684
{
685
  return value.DecodePER(*this);
686
}
687
688
689
void PPER_Stream::IntegerEncode(const PASN_Integer & value)
690
{
691
  value.EncodePER(*this);
692
}
693
694
695
BOOL PASN_Integer::DecodePER(PPER_Stream & strm)
696
{
697
  // X.931 Sections 12
698
699
  if ((extendable && strm.SingleBitDecode()) || constraint != FixedConstraint) { //  12.1
700
    unsigned len;
701
    if (strm.LengthDecode(0, INT_MAX, len) != 0)
702
      return FALSE;
703
    return strm.MultiBitDecode(len*8, value);
704
  }
705
706
  if ((unsigned)lowerLimit != upperLimit)  // 12.2.1
707
    return strm.UnsignedDecode(lowerLimit, upperLimit, value) == 0; // 12.2.2 which devolves to 10.5
708
709
  value = lowerLimit;
710
  return TRUE;
711
}
712
713
714
void PASN_Integer::EncodePER(PPER_Stream & strm) const
715
{
716
  // X.931 Sections 12
717
718
  if (ConstraintEncode(strm, (int)value)) { //  12.1
719
    PINDEX nBytes;
720
    unsigned adjusted_value = value - lowerLimit;
721
    if (adjusted_value == 0)
722
      nBytes = 1;
723
    else {
724
      PINDEX nBits = CountBits(adjusted_value+1);
725
      nBytes = (nBits+7)/8;
726
    }
727
    strm.LengthEncode(nBytes, 0, INT_MAX);
728
    strm.MultiBitEncode(adjusted_value, nBytes*8);
729
    return;
730
  }
731
732
  if ((unsigned)lowerLimit == upperLimit) // 12.2.1
733
    return;
734
735
  // 12.2.2 which devolves to 10.5
736
  strm.UnsignedEncode(value, lowerLimit, upperLimit);
737
}
738
739
740
///////////////////////////////////////////////////////////////////////
741
742
PASN_Enumeration::PASN_Enumeration(unsigned val)
743
  : PASN_Object(UniversalEnumeration, UniversalTagClass, FALSE)
744
{
745
  value = val;
746
  maxEnumValue = P_MAX_INDEX;
747
}
748
749
750
PASN_Enumeration::PASN_Enumeration(unsigned tag, TagClass tagClass,
751
                                   unsigned maxEnum, BOOL extend,
752
                                   unsigned val)
753
  : PASN_Object(tag, tagClass, extend)
754
{
755
  value = val;
756
  maxEnumValue = maxEnum;
757
}
758
759
760
static POrdinalToString BuildNamesDict(const PString & nameSpec)
761
{
762
  POrdinalToString names;
763
764
  PStringArray nameList = nameSpec.Tokenise(' ', FALSE);
765
766
  int num = 0;
767
  for (PINDEX i = 0; i < nameList.GetSize(); i++) {
768
    const PString & thisName = nameList[i];
769
    if (!thisName) {
770
      PINDEX equalPos = thisName.Find('=');
771
      if (equalPos != P_MAX_INDEX)
772
        num = (int)thisName.Mid(equalPos+1).AsInteger();
773
      names.SetAt(POrdinalKey(num), thisName.Left(equalPos));
774
      num++;
775
    }
776
  }
777
778
  return names;
779
}
780
781
782
PASN_Enumeration::PASN_Enumeration(unsigned tag, TagClass tagClass,
783
                                   unsigned maxEnum, BOOL extend,
784
                                   const PString & nameSpec,
785
                                   unsigned val)
786
  : PASN_Object(tag, tagClass, extend),
787
    names(BuildNamesDict(nameSpec))
788
{
789
  PAssert(maxEnum > 0, PInvalidParameter);
790
  maxEnumValue = maxEnum;
791
792
  PAssert(val < maxEnum, PInvalidParameter);
793
  value = val;
794
}
795
796
797
PObject::Comparison PASN_Enumeration::Compare(const PObject & obj) const
798
{
799
  PAssert(obj.IsDescendant(PASN_Enumeration::Class()), PInvalidCast);
800
  const PASN_Enumeration & other = (const PASN_Enumeration &)obj;
801
802
  if (value < other.value)
803
    return LessThan;
804
805
  if (value > other.value)
806
    return GreaterThan;
807
808
  return EqualTo;
809
}
810
811
812
PObject * PASN_Enumeration::Clone() const
813
{
814
  PAssert(IsClass(PASN_Enumeration::Class()), PInvalidCast);
815
  return new PASN_Enumeration(*this);
816
}
817
818
819
void PASN_Enumeration::PrintOn(ostream & strm) const
820
{
821
  if (names.Contains(value))
822
    strm << names[value];
823
  else
824
    strm << '<' << value << '>';
825
}
826
827
828
PString PASN_Enumeration::GetTypeAsString() const
829
{
830
  return "Enumeration";
831
}
832
833
834
PINDEX PASN_Enumeration::GetDataLength() const
835
{
836
  return GetIntegerDataLength(value);
837
}
838
839
840
BOOL PASN_Enumeration::Decode(PASN_Stream & strm)
841
{
842
  return strm.EnumerationDecode(*this);
843
}
844
845
846
void PASN_Enumeration::Encode(PASN_Stream & strm) const
847
{
848
  strm.EnumerationEncode(*this);
849
}
850
851
852
BOOL PBER_Stream::EnumerationDecode(PASN_Enumeration & value)
853
{
854
  unsigned len;
855
  if (!HeaderDecode(value, len) || len == 0 || IsAtEnd())
856
    return FALSE;
857
858
  unsigned val = 0;
859
  while (len-- > 0) {
860
    if (IsAtEnd())
861
      return FALSE;
862
    val = (val << 8) | ByteDecode();
863
  }
864
865
  value = val;
866
  return TRUE;
867
}
868
869
870
void PBER_Stream::EnumerationEncode(const PASN_Enumeration & value)
871
{
872
  HeaderEncode(value);
873
  // output the integer bits
874
  for (int count = GetIntegerDataLength(value)-1; count >= 0; count--)
875
    ByteEncode(value >> (count*8));
876
}
877
878
879
BOOL PPER_Stream::EnumerationDecode(PASN_Enumeration & value)
880
{
881
  return value.DecodePER(*this);
882
}
883
884
885
void PPER_Stream::EnumerationEncode(const PASN_Enumeration & value)
886
{
887
  value.EncodePER(*this);
888
}
889
890
891
BOOL PASN_Enumeration::DecodePER(PPER_Stream & strm)
892
{
893
  // X.691 Section 13
894
895
  if (extendable) {  // 13.3
896
    if (strm.SingleBitDecode()) {
897
      unsigned len = 0;
898
      return strm.SmallUnsignedDecode(len) &&
899
             len > 0 &&
900
             strm.UnsignedDecode(0, len-1, value) == 0;
901
    }
902
  }
903
904
  return strm.UnsignedDecode(0, maxEnumValue, value) == 0;  // 13.2
905
}
906
907
908
void PASN_Enumeration::EncodePER(PPER_Stream & strm) const
909
{
910
  // X.691 Section 13
911
912
  if (extendable) {  // 13.3
913
    BOOL extended = value > maxEnumValue;
914
    strm.SingleBitEncode(extended);
915
    if (extended) {
916
      strm.SmallUnsignedEncode(1+value);
917
      strm.UnsignedEncode(value, 0, value);
918
      return;
919
    }
920
  }
921
922
  strm.UnsignedEncode(value, 0, maxEnumValue);  // 13.2
923
}
924
925
926
///////////////////////////////////////////////////////////////////////
927
928
PASN_Real::PASN_Real(double val)
929
  : PASN_Object(UniversalReal, UniversalTagClass)
930
{
931
  value = val;
932
}
933
934
935
PASN_Real::PASN_Real(unsigned tag, TagClass tagClass, double val)
936
  : PASN_Object(tag, tagClass)
937
{
938
  value = val;
939
}
940
941
942
PObject::Comparison PASN_Real::Compare(const PObject & obj) const
943
{
944
  PAssert(obj.IsDescendant(PASN_Real::Class()), PInvalidCast);
945
  const PASN_Real & other = (const PASN_Real &)obj;
946
947
  if (value < other.value)
948
    return LessThan;
949
950
  if (value > other.value)
951
    return GreaterThan;
952
953
  return EqualTo;
954
}
955
956
957
PObject * PASN_Real::Clone() const
958
{
959
  PAssert(IsClass(PASN_Real::Class()), PInvalidCast);
960
  return new PASN_Real(*this);
961
}
962
963
964
void PASN_Real::PrintOn(ostream & strm) const
965
{
966
  strm << value;
967
}
968
969
970
PString PASN_Real::GetTypeAsString() const
971
{
972
  return "Real";
973
}
974
975
976
PINDEX PASN_Real::GetDataLength() const
977
{
978
  PAssertAlways(PUnimplementedFunction);
979
  return 0;
980
}
981
982
983
BOOL PASN_Real::Decode(PASN_Stream & strm)
984
{
985
  return strm.RealDecode(*this);
986
}
987
988
989
void PASN_Real::Encode(PASN_Stream & strm) const
990
{
991
  strm.RealEncode(*this);
992
}
993
994
995
BOOL PBER_Stream::RealDecode(PASN_Real & value)
996
{
997
  unsigned len;
998
  if (!HeaderDecode(value, len) || len == 0 || IsAtEnd())
999
    return FALSE;
1000
1001
  PAssertAlways(PUnimplementedFunction);
1002
  byteOffset += len;
1003
1004
  return TRUE;
1005
}
1006
1007
1008
void PBER_Stream::RealEncode(const PASN_Real &)
1009
{
1010
  PAssertAlways(PUnimplementedFunction);
1011
}
1012
1013
1014
BOOL PPER_Stream::RealDecode(PASN_Real &)
1015
{
1016
  // X.691 Section 14
1017
1018
  if (IsAtEnd())
1019
    return FALSE;
1020
1021
  unsigned len;
1022
  if (!MultiBitDecode(8, len))
1023
    return FALSE;
1024
1025
  PAssertAlways(PUnimplementedFunction);
1026
  byteOffset += len+1;
1027
  return TRUE;
1028
}
1029
1030
1031
void PPER_Stream::RealEncode(const PASN_Real &)
1032
{
1033
  // X.691 Section 14
1034
1035
  MultiBitEncode(0, 8);
1036
  PAssertAlways(PUnimplementedFunction);
1037
  MultiBitEncode(0, 8);
1038
}
1039
1040
1041
///////////////////////////////////////////////////////////////////////
1042
1043
PASN_ObjectId::PASN_ObjectId(const char * dotstr)
1044
  : PASN_Object(UniversalObjectId, UniversalTagClass)
1045
{
1046
  if (dotstr != NULL)
1047
    SetValue(dotstr);
1048
}
1049
1050
1051
PASN_ObjectId::PASN_ObjectId(unsigned tag, TagClass tagClass)
1052
  : PASN_Object(tag, tagClass)
1053
{
1054
}
1055
1056
1057
PASN_ObjectId::PASN_ObjectId(const PASN_ObjectId & other)
1058
  : PASN_Object(other),
1059
    value(other.value, other.GetSize())
1060
{
1061
}
1062
1063
1064
PASN_ObjectId & PASN_ObjectId::operator=(const PASN_ObjectId & other)
1065
{
1066
  PASN_Object::operator=(other);
1067
  value = PUnsignedArray(other.value, other.GetSize());
1068
  return *this;
1069
}
1070
1071
1072
PASN_ObjectId & PASN_ObjectId::operator=(const char * dotstr)
1073
{
1074
  if (dotstr != NULL)
1075
    SetValue(dotstr);
1076
  else
1077
    value.SetSize(0);
1078
  return *this;
1079
}
1080
1081
1082
PASN_ObjectId & PASN_ObjectId::operator=(const PString & dotstr)
1083
{
1084
  SetValue(dotstr);
1085
  return *this;
1086
}
1087
1088
1089
void PASN_ObjectId::SetValue(const PString & dotstr)
1090
{
1091
  PStringArray parts = dotstr.Tokenise('.');
1092
  value.SetSize(parts.GetSize());
1093
  for (PINDEX i = 0; i < parts.GetSize(); i++)
1094
    value[i] = parts[i].AsUnsigned();
1095
}
1096
1097
1098
BOOL PASN_ObjectId::operator==(const char * dotstr) const
1099
{
1100
  PASN_ObjectId id;
1101
  id.SetValue(dotstr);
1102
  return *this == id;
1103
}
1104
1105
1106
PObject::Comparison PASN_ObjectId::Compare(const PObject & obj) const
1107
{
1108
  PAssert(obj.IsDescendant(PASN_ObjectId::Class()), PInvalidCast);
1109
  const PASN_ObjectId & other = (const PASN_ObjectId &)obj;
1110
  return value.Compare(other.value);
1111
}
1112
1113
1114
PObject * PASN_ObjectId::Clone() const
1115
{
1116
  PAssert(IsClass(PASN_ObjectId::Class()), PInvalidCast);
1117
  return new PASN_ObjectId(*this);
1118
}
1119
1120
1121
void PASN_ObjectId::PrintOn(ostream & strm) const
1122
{
1123
  for (PINDEX i = 0; i < value.GetSize(); i++) {
1124
    strm << (unsigned)value[i];
1125
    if (i < value.GetSize()-1)
1126
      strm << '.';
1127
  }
1128
}
1129
1130
1131
PString PASN_ObjectId::GetTypeAsString() const
1132
{
1133
  return "Object ID";
1134
}
1135
1136
1137
BOOL PASN_ObjectId::CommonDecode(PASN_Stream & strm, unsigned dataLen)
1138
{
1139
  value.SetSize(0);
1140
1141
  // handle zero length strings correctly
1142
  if (dataLen == 0)
1143
    return TRUE;
1144
1145
  unsigned subId;
1146
1147
  // start at the second identifier in the buffer, because we will later
1148
  // expand the first number into the first two IDs
1149
  PINDEX i = 1;
1150
  while (dataLen > 0) {
1151
    unsigned byte;
1152
    subId = 0;
1153
    do {    /* shift and add in low order 7 bits */
1154
      if (strm.IsAtEnd())
1155
        return FALSE;
1156
      byte = strm.ByteDecode();
1157
      subId = (subId << 7) + (byte & 0x7f);
1158
      dataLen--;
1159
    } while ((byte & 0x80) != 0);
1160
    value.SetAt(i++, subId);
1161
  }
1162
1163
  /*
1164
   * The first two subidentifiers are encoded into the first component
1165
   * with the value (X * 40) + Y, where:
1166
   *  X is the value of the first subidentifier.
1167
   *  Y is the value of the second subidentifier.
1168
   */
1169
  subId = value[1];
1170
  if (subId < 40) {
1171
    value[0] = 0;
1172
    value[1] = subId;
1173
  }
1174
  else if (subId < 80) {
1175
    value[0] = 1;
1176
    value[1] = subId-40;
1177
  }
1178
  else {
1179
    value[0] = 2;
1180
    value[1] = subId-80;
1181
  }
1182
1183
  return TRUE;
1184
}
1185
1186
1187
void PASN_ObjectId::CommonEncode(PBYTEArray & encodecObjectId) const
1188
{
1189
  PINDEX length = value.GetSize();
1190
  const unsigned * objId = value;
1191
1192
  if (length < 2) {
1193
    // Thise case is really illegal, but we have to do SOMETHING
1194
    encodecObjectId.SetSize(0);
1195
    return;
1196
  }
1197
1198
  unsigned subId = (objId[0] * 40) + objId[1];
1199
  objId += 2;
1200
1201
  PINDEX outputPosition = 0;
1202
1203
  while (--length > 0) {
1204
    if (subId < 128)
1205
      encodecObjectId[outputPosition++] = (BYTE)subId;
1206
    else {
1207
      unsigned mask = 0x7F; /* handle subid == 0 case */
1208
      int bits = 0;
1209
1210
      /* testmask *MUST* !!!! be of an unsigned type */
1211
      unsigned testmask = 0x7F;
1212
      int      testbits = 0;
1213
      while (testmask != 0) {
1214
        if (subId & testmask) {  /* if any bits set */
1215
          mask = testmask;
1216
	        bits = testbits;
1217
	      }
1218
        testmask <<= 7;
1219
        testbits += 7;
1220
      }
1221
1222
      /* mask can't be zero here */
1223
      while (mask != 0x7F) {
1224
        /* fix a mask that got truncated above */
1225
      	if (mask == 0x1E00000)
1226
	        mask = 0xFE00000;
1227
1228
        encodecObjectId[outputPosition++] = (BYTE)(((subId & mask) >> bits) | 0x80);
1229
1230
        mask >>= 7;
1231
        bits -= 7;
1232
      }
1233
1234
      encodecObjectId[outputPosition++] = (BYTE)(subId & mask);
1235
    }
1236
1237
    if (length > 1)
1238
      subId = *objId++;
1239
  }
1240
}
1241
1242
1243
PINDEX PASN_ObjectId::GetDataLength() const
1244
{
1245
  PBYTEArray dummy;
1246
  CommonEncode(dummy);
1247
  return dummy.GetSize();
1248
}
1249
1250
1251
BOOL PASN_ObjectId::Decode(PASN_Stream & strm)
1252
{
1253
  return strm.ObjectIdDecode(*this);
1254
}
1255
1256
1257
void PASN_ObjectId::Encode(PASN_Stream & strm) const
1258
{
1259
  strm.ObjectIdEncode(*this);
1260
}
1261
1262
1263
BOOL PBER_Stream::ObjectIdDecode(PASN_ObjectId & value)
1264
{
1265
  unsigned len;
1266
  if (!HeaderDecode(value, len))
1267
    return FALSE;
1268
1269
  return value.CommonDecode(*this, len);
1270
}
1271
1272
1273
void PBER_Stream::ObjectIdEncode(const PASN_ObjectId & value)
1274
{
1275
  HeaderEncode(value);
1276
  PBYTEArray data;
1277
  value.CommonEncode(data);
1278
  BlockEncode(data, data.GetSize());
1279
}
1280
1281
1282
BOOL PPER_Stream::ObjectIdDecode(PASN_ObjectId & value)
1283
{
1284
  // X.691 Section 23
1285
1286
  unsigned dataLen;
1287
  if (LengthDecode(0, 255, dataLen) < 0)
1288
    return FALSE;
1289
1290
  ByteAlign();
1291
  return value.CommonDecode(*this, dataLen);
1292
}
1293
1294
1295
void PPER_Stream::ObjectIdEncode(const PASN_ObjectId & value)
1296
{
1297
  // X.691 Section 23
1298
1299
  PBYTEArray eObjId;
1300
  value.CommonEncode(eObjId);
1301
  LengthEncode(eObjId.GetSize(), 0, 255);
1302
  BlockEncode(eObjId, eObjId.GetSize());
1303
}
1304
1305
1306
///////////////////////////////////////////////////////////////////////
1307
1308
PASN_BitString::PASN_BitString(unsigned nBits, const BYTE * buf)
1309
  : PASN_ConstrainedObject(UniversalBitString, UniversalTagClass),
1310
    totalBits(nBits),
1311
    bitData((totalBits+7)/8)
1312
{
1313
  if (buf != NULL)
1314
    memcpy(bitData.GetPointer(), buf, bitData.GetSize());
1315
}
1316
1317
1318
PASN_BitString::PASN_BitString(unsigned tag, TagClass tagClass, unsigned nBits)
1319
  : PASN_ConstrainedObject(tag, tagClass),
1320
    totalBits(nBits),
1321
    bitData((totalBits+7)/8)
1322
{
1323
}
1324
1325
1326
PASN_BitString::PASN_BitString(const PASN_BitString & other)
1327
  : PASN_ConstrainedObject(other),
1328
    bitData(other.bitData, other.bitData.GetSize())
1329
{
1330
  totalBits = other.totalBits;
1331
}
1332
1333
1334
PASN_BitString & PASN_BitString::operator=(const PASN_BitString & other)
1335
{
1336
  PASN_ConstrainedObject::operator=(other);
1337
  totalBits = other.totalBits;
1338
  bitData = PBYTEArray(other.bitData, other.bitData.GetSize());
1339
  return *this;
1340
}
1341
1342
1343
void PASN_BitString::SetData(unsigned nBits, const PBYTEArray & bytes)
1344
{
1345
  bitData = bytes;
1346
  SetSize(nBits);
1347
}
1348
1349
1350
void PASN_BitString::SetData(unsigned nBits, const BYTE * buf, PINDEX size)
1351
{
1352
  if (size == 0)
1353
    size = (nBits+7)/8;
1354
  memcpy(bitData.GetPointer(size), buf, size);
1355
  SetSize(nBits);
1356
}
1357
1358
1359
BOOL PASN_BitString::SetSize(unsigned nBits)
1360
{
1361
  if (constraint == Unconstrained)
1362
    totalBits = nBits;
1363
  else if (totalBits < (unsigned)lowerLimit)
1364
    totalBits = lowerLimit;
1365
  else if ((unsigned)totalBits > upperLimit)
1366
    totalBits = upperLimit;
1367
  else
1368
    totalBits = nBits;
1369
  return bitData.SetSize((nBits+7)/8);
1370
}
1371
1372
1373
BOOL PASN_BitString::operator[](PINDEX bit) const
1374
{
1375
  if ((unsigned)bit < totalBits)
1376
    return (bitData[bit>>3] & (1 << (7 - (bit&7)))) != 0;
1377
  return FALSE;
1378
}
1379
1380
1381
void PASN_BitString::Set(unsigned bit)
1382
{
1383
  if (bit < totalBits)
1384
    bitData[(PINDEX)(bit>>3)] |= 1 << (7 - (bit&7));
1385
}
1386
1387
1388
void PASN_BitString::Clear(unsigned bit)
1389
{
1390
  if (bit < totalBits)
1391
    bitData[(PINDEX)(bit>>3)] &= ~(1 << (7 - (bit&7)));
1392
}
1393
1394
1395
void PASN_BitString::Invert(unsigned bit)
1396
{
1397
  if (bit < totalBits)
1398
    bitData[(PINDEX)(bit>>3)] ^= 1 << (7 - (bit&7));
1399
}
1400
1401
1402
PObject::Comparison PASN_BitString::Compare(const PObject & obj) const
1403
{
1404
  PAssert(obj.IsDescendant(PASN_BitString::Class()), PInvalidCast);
1405
  const PASN_BitString & other = (const PASN_BitString &)obj;
1406
  if (totalBits < other.totalBits)
1407
    return LessThan;
1408
  if (totalBits > other.totalBits)
1409
    return GreaterThan;
1410
  return bitData.Compare(other.bitData);
1411
}
1412
1413
1414
PObject * PASN_BitString::Clone() const
1415
{
1416
  PAssert(IsClass(PASN_BitString::Class()), PInvalidCast);
1417
  return new PASN_BitString(*this);
1418
}
1419
1420
1421
void PASN_BitString::PrintOn(ostream & strm) const
1422
{
1423
  BYTE mask = 0x80;
1424
  PINDEX offset = 0;
1425
  for (unsigned i = 0; i < totalBits; i++) {
1426
    strm << ((bitData[offset]&mask) != 0 ? '1' : '0');
1427
    mask >>= 1;
1428
    if (mask == 0) {
1429
      mask = 0x80;
1430
      offset++;
1431
    }
1432
  }
1433
}
1434
1435
1436
void PASN_BitString::SetConstraintBounds(ConstraintType type, int lower, unsigned upper)
1437
{
1438
  PAssert(lower >= 0, PInvalidParameter);
1439
  PASN_ConstrainedObject::SetConstraintBounds(type, lower, upper);
1440
  SetSize(GetSize());
1441
}
1442
1443
1444
PString PASN_BitString::GetTypeAsString() const
1445
{
1446
  return "Bit String";
1447
}
1448
1449
1450
PINDEX PASN_BitString::GetDataLength() const
1451
{
1452
  return (totalBits+7)/8 + 1;
1453
}
1454
1455
1456
BOOL PASN_BitString::Decode(PASN_Stream & strm)
1457
{
1458
  return strm.BitStringDecode(*this);
1459
}
1460
1461
1462
void PASN_BitString::Encode(PASN_Stream & strm) const
1463
{
1464
  strm.BitStringEncode(*this);
1465
}
1466
1467
1468
BOOL PASN_BitString::DecodeBER(PBER_Stream & strm, unsigned len)
1469
{
1470
  totalBits = len*8 - strm.ByteDecode();
1471
  unsigned nBytes = (totalBits+7)/8;
1472
  return strm.BlockDecode(bitData.GetPointer(nBytes), nBytes) == nBytes;
1473
}
1474
1475
1476
void PASN_BitString::EncodeBER(PBER_Stream & strm) const
1477
{
1478
  if (totalBits == 0)
1479
    strm.ByteEncode(0);
1480
  else {
1481
    strm.ByteEncode(8-totalBits%8);
1482
    strm.BlockEncode(bitData, (totalBits+7)/8);
1483
  }
1484
}
1485
1486
1487
BOOL PASN_BitString::DecodePER(PPER_Stream & strm)
1488
{
1489
  // X.691 Section 15
1490
1491
  if (ConstrainedLengthDecode(strm, totalBits) < 0)
1492
    return FALSE;
1493
1494
  SetSize(totalBits);
1495
1496
  if (totalBits == 0)
1497
    return TRUE;   // 15.7
1498
1499
  if (totalBits > strm.GetBitsLeft())
1500
    return FALSE;
1501
1502
  if (totalBits > 16) {
1503
    unsigned nBytes = (totalBits+7)/8;
1504
    return strm.BlockDecode(bitData.GetPointer(), nBytes) == nBytes;   // 15.9
1505
  }
1506
1507
  unsigned theBits;
1508
  if (totalBits <= 8) {
1509
    if (!strm.MultiBitDecode(totalBits, theBits))
1510
      return FALSE;
1511
1512
    bitData[0] = (BYTE)(theBits << (8-totalBits));
1513
  }
1514
  else {  // 15.8
1515
    if (!strm.MultiBitDecode(8, theBits))
1516
      return FALSE;
1517
1518
    bitData[0] = (BYTE)theBits;
1519
1520
    if (!strm.MultiBitDecode(totalBits-8, theBits))
1521
      return FALSE;
1522
1523
    bitData[1] = (BYTE)(theBits << (16-totalBits));
1524
  }
1525
1526
  return TRUE;
1527
}
1528
1529
1530
void PASN_BitString::EncodePER(PPER_Stream & strm) const
1531
{
1532
  // X.691 Section 15
1533
1534
  ConstrainedLengthEncode(strm, totalBits);
1535
1536
  if (totalBits == 0)
1537
    return;
1538
1539
  if (totalBits > 16)
1540
    strm.BlockEncode(bitData, (totalBits+7)/8);   // 15.9
1541
  else if (totalBits <= 8)  // 15.8
1542
    strm.MultiBitEncode(bitData[0] >> (8 - totalBits), totalBits);
1543
  else {
1544
    strm.MultiBitEncode(bitData[0], 8);
1545
    strm.MultiBitEncode(bitData[1] >> (16 - totalBits), totalBits-8);
1546
  }
1547
}
1548
1549
1550
BOOL PASN_BitString::DecodeSequenceExtensionBitmap(PPER_Stream & strm)
1551
{
1552
  if (!strm.SmallUnsignedDecode(totalBits))
1553
    return FALSE;
1554
1555
  totalBits++;
1556
1557
  SetSize(totalBits);
1558
1559
  if (totalBits > strm.GetBitsLeft())
1560
    return FALSE;
1561
1562
  unsigned theBits;
1563
1564
  PINDEX idx = 0;
1565
  unsigned bitsLeft = totalBits;
1566
  while (bitsLeft >= 8) {
1567
    if (!strm.MultiBitDecode(8, theBits))
1568
      return FALSE;
1569
    bitData[idx++] = (BYTE)theBits;
1570
    bitsLeft -= 8;
1571
  }
1572
1573
  if (bitsLeft > 0) {
1574
    if (!strm.MultiBitDecode(bitsLeft, theBits))
1575
      return FALSE;
1576
    bitData[idx] = (BYTE)(theBits << (8-bitsLeft));
1577
  }
1578
1579
  return TRUE;
1580
}
1581
1582
1583
void PASN_BitString::EncodeSequenceExtensionBitmap(PPER_Stream & strm) const
1584
{
1585
  PAssert(totalBits > 0, PLogicError);
1586
1587
  strm.SmallUnsignedEncode(totalBits-1);
1588
1589
  PINDEX idx = 0;
1590
  unsigned bitsLeft = totalBits;
1591
  while (bitsLeft >= 8) {
1592
    strm.MultiBitEncode(bitData[idx++], 8);
1593
    bitsLeft -= 8;
1594
  }
1595
1596
  if (bitsLeft > 0)
1597
    strm.MultiBitEncode(bitData[idx] >> (8 - bitsLeft), bitsLeft);
1598
}
1599
1600
1601
BOOL PBER_Stream::BitStringDecode(PASN_BitString & value)
1602
{
1603
  unsigned len;
1604
  if (!HeaderDecode(value, len) || len == 0 || IsAtEnd())
1605
    return FALSE;
1606
1607
  return value.DecodeBER(*this, len);
1608
}
1609
1610
1611
void PBER_Stream::BitStringEncode(const PASN_BitString & value)
1612
{
1613
  HeaderEncode(value);
1614
  value.EncodeBER(*this);
1615
}
1616
1617
1618
BOOL PPER_Stream::BitStringDecode(PASN_BitString & value)
1619
{
1620
  return value.DecodePER(*this);
1621
}
1622
1623
1624
void PPER_Stream::BitStringEncode(const PASN_BitString & value)
1625
{
1626
  value.EncodePER(*this);
1627
}
1628
1629
1630
///////////////////////////////////////////////////////////////////////
1631
1632
PASN_OctetString::PASN_OctetString(const char * str, PINDEX size)
1633
  : PASN_ConstrainedObject(UniversalOctetString, UniversalTagClass)
1634
{
1635
  if (str != NULL) {
1636
    if (size == 0)
1637
      size = ::strlen(str);
1638
    SetValue((const BYTE *)str, size);
1639
  }
1640
}
1641
1642
1643
PASN_OctetString::PASN_OctetString(unsigned tag, TagClass tagClass)
1644
  : PASN_ConstrainedObject(tag, tagClass)
1645
{
1646
}
1647
1648
1649
PASN_OctetString::PASN_OctetString(const PASN_OctetString & other)
1650
  : PASN_ConstrainedObject(other),
1651
    value(other.value, other.GetSize())
1652
{
1653
}
1654
1655
1656
PASN_OctetString & PASN_OctetString::operator=(const PASN_OctetString & other)
1657
{
1658
  PASN_ConstrainedObject::operator=(other);
1659
  value = PBYTEArray(other.value, other.GetSize());
1660
  return *this;
1661
}
1662
1663
1664
PASN_OctetString & PASN_OctetString::operator=(const char * str)
1665
{
1666
  if (str == NULL)
1667
    value.SetSize(lowerLimit);
1668
  else
1669
    SetValue((const BYTE *)str, strlen(str));
1670
  return *this;
1671
}
1672
1673
1674
PASN_OctetString & PASN_OctetString::operator=(const PString & str)
1675
{
1676
  SetValue((const BYTE *)(const char *)str, str.GetSize()-1);
1677
  return *this;
1678
}
1679
1680
1681
PASN_OctetString & PASN_OctetString::operator=(const PBYTEArray & arr)
1682
{
1683
  PINDEX len = arr.GetSize();
1684
  if ((unsigned)len > upperLimit || (int)len < lowerLimit)
1685
    SetValue(arr, len);
1686
  else
1687
    value = arr;
1688
  return *this;
1689
}
1690
1691
1692
void PASN_OctetString::SetValue(const BYTE * data, PINDEX len)
1693
{
1694
  if ((unsigned)len > upperLimit)
1695
    len = upperLimit;
1696
  value.SetSize((int)len < lowerLimit ? lowerLimit : len);
1697
  memcpy(value.GetPointer(), data, len);
1698
}
1699
1700
1701
PString PASN_OctetString::AsString() const
1702
{
1703
  if (value.IsEmpty())
1704
    return PString();
1705
  return PString((const char *)(const BYTE *)value, value.GetSize());
1706
}
1707
1708
1709
PObject::Comparison PASN_OctetString::Compare(const PObject & obj) const
1710
{
1711
  PAssert(obj.IsDescendant(PASN_OctetString::Class()), PInvalidCast);
1712
  const PASN_OctetString & other = (const PASN_OctetString &)obj;
1713
  return value.Compare(other.value);
1714
}
1715
1716
1717
PObject * PASN_OctetString::Clone() const
1718
{
1719
  PAssert(IsClass(PASN_OctetString::Class()), PInvalidCast);
1720
  return new PASN_OctetString(*this);
1721
}
1722
1723
1724
void PASN_OctetString::PrintOn(ostream & strm) const
1725
{
1726
  int indent = strm.precision() + 2;
1727
  strm << ' ' << value.GetSize() << " octets {\n";
1728
  PINDEX i = 0;
1729
  while (i < value.GetSize()) {
1730
    strm << setw(indent) << " " << hex << setfill('0');
1731
    PINDEX j;
1732
    for (j = 0; j < 16; j++) {
1733
      if (i+j < value.GetSize())
1734
        strm << setw(2) << (unsigned)value[i+j] << ' ';
1735
      else
1736
        strm << "   ";
1737
    }
1738
    strm << "  ";
1739
    for (j = 0; j < 16; j++) {
1740
      if (i+j < value.GetSize()) {
1741
        if (isprint(value[i+j]))
1742
          strm << value[i+j];
1743
        else
1744
          strm << ' ';
1745
      }
1746
    }
1747
    strm << dec << setfill(' ') << '\n';
1748
    i += 16;
1749
  }
1750
  strm << setw(indent-1) << "}";
1751
}
1752
1753
1754
void PASN_OctetString::SetConstraintBounds(ConstraintType type, int lower, unsigned upper)
1755
{
1756
  PAssert(lower >= 0, PInvalidParameter);
1757
  PASN_ConstrainedObject::SetConstraintBounds(type, lower, upper);
1758
  if (constraint != Unconstrained) {
1759
    if (value.GetSize() < (PINDEX)lowerLimit)
1760
      value.SetSize(lowerLimit);
1761
    else if ((unsigned)value.GetSize() > upperLimit)
1762
      value.SetSize(upperLimit);
1763
  }
1764
}
1765
1766
1767
PString PASN_OctetString::GetTypeAsString() const
1768
{
1769
  return "Octet String";
1770
}
1771
1772
1773
PINDEX PASN_OctetString::GetDataLength() const
1774
{
1775
  return value.GetSize();
1776
}
1777
1778
1779
BOOL PASN_OctetString::Decode(PASN_Stream & strm)
1780
{
1781
  return strm.OctetStringDecode(*this);
1782
}
1783
1784
1785
void PASN_OctetString::Encode(PASN_Stream & strm) const
1786
{
1787
  strm.OctetStringEncode(*this);
1788
}
1789
1790
1791
BOOL PASN_OctetString::DecodePER(PPER_Stream & strm)
1792
{
1793
  // X.691 Section 16
1794
1795
  unsigned nBytes;
1796
  if (ConstrainedLengthDecode(strm, nBytes) < 0)
1797
    return FALSE;
1798
1799
  value.SetSize(nBytes);   // 16.5
1800
1801
  unsigned theBits;
1802
  switch (nBytes) {
1803
    case 0 :
1804
      break;
1805
1806
    case 1 :  // 16.6
1807
      if (!strm.MultiBitDecode(8, theBits))
1808
        return FALSE;
1809
      value[0] = (BYTE)theBits;
1810
      break;
1811
1812
    case 2 :  // 16.6
1813
      if (!strm.MultiBitDecode(8, theBits))
1814
        return FALSE;
1815
      value[0] = (BYTE)theBits;
1816
      if (!strm.MultiBitDecode(8, theBits))
1817
        return FALSE;
1818
      value[1] = (BYTE)theBits;
1819
      break;
1820
1821
    default: // 16.7
1822
      return strm.BlockDecode(value.GetPointer(), nBytes) == nBytes;
1823
  }
1824
1825
  return TRUE;
1826
}
1827
1828
1829
void PASN_OctetString::EncodePER(PPER_Stream & strm) const
1830
{
1831
  // X.691 Section 16
1832
1833
  PINDEX nBytes = value.GetSize();
1834
  ConstrainedLengthEncode(strm, nBytes);
1835
1836
  switch (nBytes) {
1837
    case 0 :  // 16.5
1838
      break;
1839
1840
    case 1 :  // 16.6
1841
      strm.MultiBitEncode(value[0], 8);
1842
      break;
1843
1844
    case 2 :  // 16.6
1845
      strm.MultiBitEncode(value[0], 8);
1846
      strm.MultiBitEncode(value[1], 8);
1847
      break;
1848
1849
    default: // 16.7
1850
      strm.BlockEncode(value, nBytes);
1851
  }
1852
}
1853
1854
1855
BOOL PBER_Stream::OctetStringDecode(PASN_OctetString & value)
1856
{
1857
  unsigned len;
1858
  if (!HeaderDecode(value, len))
1859
    return FALSE;
1860
1861
  return BlockDecode(value.GetPointer(len), len) == len;
1862
}
1863
1864
1865
void PBER_Stream::OctetStringEncode(const PASN_OctetString & value)
1866
{
1867
  HeaderEncode(value);
1868
  BlockEncode(value, value.GetSize());
1869
}
1870
1871
1872
BOOL PPER_Stream::OctetStringDecode(PASN_OctetString & value)
1873
{
1874
  return value.DecodePER(*this);
1875
}
1876
1877
1878
void PPER_Stream::OctetStringEncode(const PASN_OctetString & value)
1879
{
1880
  value.EncodePER(*this);
1881
}
1882
1883
1884
BOOL PASN_OctetString::DecodeSubType(PASN_Object & obj)
1885
{
1886
  PPER_Stream stream = GetValue();
1887
  return obj.Decode(stream);
1888
}
1889
1890
1891
void PASN_OctetString::EncodeSubType(const PASN_Object & obj)
1892
{
1893
  PPER_Stream stream;
1894
  obj.Encode(stream);
1895
  stream.CompleteEncoding();
1896
  SetValue(stream);
1897
}
1898
1899
1900
///////////////////////////////////////////////////////////////////////
1901
1902
PASN_ConstrainedString::PASN_ConstrainedString(const char * canonical, PINDEX size,
1903
                                               unsigned tag, TagClass tagClass)
1904
  : PASN_ConstrainedObject(tag, tagClass)
1905
{
1906
  canonicalSet = canonical;
1907
  canonicalSetSize = size;
1908
  canonicalSetBits = CountBits(size);
1909
  SetCharacterSet(canonicalSet, canonicalSetSize, Unconstrained);
1910
}
1911
1912
1913
PASN_ConstrainedString & PASN_ConstrainedString::operator=(const char * str)
1914
{
1915
  if (str == NULL)
1916
    str = "";
1917
1918
  PStringStream newValue;
1919
1920
  PINDEX len = strlen(str);
1921
1922
  // Can't copy any more characters than the upper constraint
1923
  if ((unsigned)len > upperLimit)
1924
    len = upperLimit;
1925
1926
  // Now copy individual characters, if they are in character set constraint
1927
  for (PINDEX i = 0; i < len; i++) {
1928
    PINDEX sz = characterSet.GetSize();
1929
    if (sz == 0 || memchr(characterSet, str[i], sz) != NULL)
1930
      newValue << str[i];
1931
  }
1932
1933
  // Make sure string meets minimum length constraint
1934
  while ((int)len < lowerLimit) {
1935
    newValue << characterSet[0];
1936
    len++;
1937
  }
1938
1939
  value = newValue;
1940
  value.MakeMinimumSize();
1941
  return *this;
1942
}
1943
1944
1945
void PASN_ConstrainedString::SetCharacterSet(ConstraintType ctype, const char * set)
1946
{
1947
  SetCharacterSet(set, strlen(set), ctype);
1948
}
1949
1950
1951
void PASN_ConstrainedString::SetCharacterSet(ConstraintType ctype, unsigned firstChar, unsigned lastChar)
1952
{
1953
  char buffer[256];
1954
  for (unsigned i = firstChar; i < lastChar; i++)
1955
    buffer[i] = (char)i;
1956
  SetCharacterSet(buffer, lastChar - firstChar + 1, ctype);
1957
}
1958
1959
1960
void PASN_ConstrainedString::SetCharacterSet(const char * set, PINDEX setSize, ConstraintType ctype)
1961
{
1962
  if (ctype == Unconstrained) {
1963
    characterSet.SetSize(canonicalSetSize);
1964
    memcpy(characterSet.GetPointer(), canonicalSet, canonicalSetSize);
1965
  }
1966
  else {
1967
    characterSet.SetSize(setSize);
1968
    PINDEX count = 0;
1969
    for (PINDEX i = 0; i < canonicalSetSize; i++) {
1970
      if (memchr(set, canonicalSet[i], setSize) != NULL)
1971
        characterSet[count++] = canonicalSet[i];
1972
    }
1973
    PAssert(count > 0, PInvalidParameter);
1974
    characterSet.SetSize(count);
1975
  }
1976
1977
  charSetUnalignedBits = CountBits(characterSet.GetSize());
1978
1979
  charSetAlignedBits = 1;
1980
  while (charSetUnalignedBits > charSetAlignedBits)
1981
    charSetAlignedBits <<= 1;
1982
1983
  operator=((const char *)value);
1984
}
1985
1986
1987
PObject::Comparison PASN_ConstrainedString::Compare(const PObject & obj) const
1988
{
1989
  PAssert(obj.IsDescendant(PASN_ConstrainedString::Class()), PInvalidCast);
1990
  const PASN_ConstrainedString & other = (const PASN_ConstrainedString &)obj;
1991
  return value.Compare(other.value);
1992
}
1993
1994
1995
void PASN_ConstrainedString::PrintOn(ostream & strm) const
1996
{
1997
  strm << value.ToLiteral();
1998
}
1999
2000
2001
void PASN_ConstrainedString::SetConstraintBounds(ConstraintType type,
2002
                                                 int lower, unsigned upper)
2003
{
2004
  PAssert(lower >= 0, PInvalidParameter);
2005
  PASN_ConstrainedObject::SetConstraintBounds(type, lower, upper);
2006
  if (constraint != Unconstrained) {
2007
    if (value.GetSize() < (PINDEX)lowerLimit)
2008
      value.SetSize(lowerLimit);
2009
    else if ((unsigned)value.GetSize() > upperLimit)
2010
      value.SetSize(upperLimit);
2011
  }
2012
}
2013
2014
2015
PINDEX PASN_ConstrainedString::GetDataLength() const
2016
{
2017
  return value.GetSize()-1;
2018
}
2019
2020
2021
BOOL PASN_ConstrainedString::Decode(PASN_Stream & strm)
2022
{
2023
  return strm.ConstrainedStringDecode(*this);
2024
}
2025
2026
2027
void PASN_ConstrainedString::Encode(PASN_Stream & strm) const
2028
{
2029
  strm.ConstrainedStringEncode(*this);
2030
}
2031
2032
2033
BOOL PASN_ConstrainedString::DecodeBER(PBER_Stream & strm, unsigned len)
2034
{
2035
  return strm.BlockDecode((BYTE *)value.GetPointer(len+1), len) == len;
2036
}
2037
2038
2039
void PASN_ConstrainedString::EncodeBER(PBER_Stream & strm) const
2040
{
2041
  strm.BlockEncode(value, value.GetSize()-1);
2042
}
2043
2044
2045
BOOL PASN_ConstrainedString::DecodePER(PPER_Stream & strm)
2046
{
2047
  // X.691 Section 26
2048
2049
  unsigned len;
2050
  if (ConstrainedLengthDecode(strm, len) < 0)
2051
    return FALSE;
2052
2053
  unsigned nBits = strm.IsAligned() ? charSetAlignedBits : charSetUnalignedBits;
2054
  unsigned totalBits = upperLimit*nBits;
2055
2056
  if (constraint == Unconstrained ||
2057
            (lowerLimit == (int)upperLimit ? (totalBits > 16) : (totalBits >= 16))) {
2058
    if (nBits == 8)
2059
      return strm.BlockDecode((BYTE *)value.GetPointer(len+1), len) == len;
2060
    if (strm.IsAligned())
2061
      strm.ByteAlign();
2062
  }
2063
2064
  value.SetSize(len+1);
2065
2066
  PINDEX i;
2067
  for (i = 0; i < (PINDEX)len; i++) {
2068
    unsigned theBits;
2069
    if (!strm.MultiBitDecode(nBits, theBits))
2070
      return FALSE;
2071
    if (nBits >= canonicalSetBits && canonicalSetBits > 4)
2072
      value[i] = (char)theBits;
2073
    else
2074
      value[i] = characterSet[(PINDEX)theBits];
2075
  }
2076
  value[i] = '\0';
2077
2078
  return TRUE;
2079
}
2080
2081
2082
void PASN_ConstrainedString::EncodePER(PPER_Stream & strm) const
2083
{
2084
  // X.691 Section 26
2085
2086
  PINDEX len = value.GetSize()-1;
2087
  ConstrainedLengthEncode(strm, len);
2088
2089
  unsigned nBits = strm.IsAligned() ? charSetAlignedBits : charSetUnalignedBits;
2090
  unsigned totalBits = upperLimit*nBits;
2091
2092
  if (constraint == Unconstrained ||
2093
            (lowerLimit == (int)upperLimit ? (totalBits > 16) : (totalBits >= 16))) {
2094
    if (nBits == 8) {
2095
      strm.BlockEncode((const BYTE *)(const char *)value, len);
2096
      return;
2097
    }
2098
    if (strm.IsAligned())
2099
      strm.ByteAlign();
2100
  }
2101
2102
  for (PINDEX i = 0; i < len; i++) {
2103
    if (nBits >= canonicalSetBits && canonicalSetBits > 4)
2104
      strm.MultiBitEncode(value[i], nBits);
2105
    else {
2106
      const void * ptr = memchr(characterSet, value[i], characterSet.GetSize());
2107
      PINDEX pos = 0;
2108
      if (ptr != NULL)
2109
        pos = ((const char *)ptr - (const char *)characterSet);
2110
      strm.MultiBitEncode(pos, nBits);
2111
    }
2112
  }
2113
}
2114
2115
2116
BOOL PBER_Stream::ConstrainedStringDecode(PASN_ConstrainedString & value)
2117
{
2118
  unsigned len;
2119
  if (!HeaderDecode(value, len))
2120
    return FALSE;
2121
2122
  return value.DecodeBER(*this, len);
2123
}
2124
2125
2126
void PBER_Stream::ConstrainedStringEncode(const PASN_ConstrainedString & value)
2127
{
2128
  HeaderEncode(value);
2129
  value.Encode(*this);
2130
}
2131
2132
2133
BOOL PPER_Stream::ConstrainedStringDecode(PASN_ConstrainedString & value)
2134
{
2135
  return value.DecodePER(*this);
2136
}
2137
2138
2139
void PPER_Stream::ConstrainedStringEncode(const PASN_ConstrainedString & value)
2140
{
2141
  value.EncodePER(*this);
2142
}
2143
2144
2145
#define DEFINE_STRING_CLASS(name, set) \
2146
  static const char name##StringSet[] = set; \
2147
  PASN_##name##String::PASN_##name##String(const char * str) \
2148
    : PASN_ConstrainedString(name##StringSet, sizeof(name##StringSet)-1, \
2149
                             Universal##name##String, UniversalTagClass) \
2150
    { PASN_ConstrainedString::SetValue(str); } \
2151
  PASN_##name##String::PASN_##name##String(unsigned tag, TagClass tagClass) \
2152
    : PASN_ConstrainedString(name##StringSet, sizeof(name##StringSet)-1, tag, tagClass) \
2153
    { } \
2154
  PASN_##name##String & PASN_##name##String::operator=(const char * str) \
2155
    { PASN_ConstrainedString::SetValue(str); return *this; } \
2156
  PASN_##name##String & PASN_##name##String::operator=(const PString & str) \
2157
    { PASN_ConstrainedString::SetValue(str); return *this; } \
2158
  PObject * PASN_##name##String::Clone() const \
2159
    { PAssert(IsClass(PASN_##name##String::Class()), PInvalidCast); \
2160
      return new PASN_##name##String(*this); } \
2161
  PString PASN_##name##String::GetTypeAsString() const \
2162
    { return #name " String"; }
2163
2164
DEFINE_STRING_CLASS(Numeric,   " 0123456789")
2165
DEFINE_STRING_CLASS(Printable, " '()+,-./0123456789:=?"
2166
                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
2167
                               "abcdefghijklmnopqrstuvwxyz")
2168
DEFINE_STRING_CLASS(Visible,   " !\"#$%&'()*+,-./0123456789:;<=>?"
2169
                               "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
2170
                               "`abcdefghijklmnopqrstuvwxyz{|}~")
2171
DEFINE_STRING_CLASS(IA5,       "\000\001\002\003\004\005\006\007"
2172
                               "\010\011\012\013\014\015\016\017"
2173
                               "\020\021\022\023\024\025\026\027"
2174
                               "\030\031\032\033\034\035\036\037"
2175
                               " !\"#$%&'()*+,-./0123456789:;<=>?"
2176
                               "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
2177
                               "`abcdefghijklmnopqrstuvwxyz{|}~\177")
2178
DEFINE_STRING_CLASS(General,   "\000\001\002\003\004\005\006\007"
2179
                               "\010\011\012\013\014\015\016\017"
2180
                               "\020\021\022\023\024\025\026\027"
2181
                               "\030\031\032\033\034\035\036\037"
2182
                               " !\"#$%&'()*+,-./0123456789:;<=>?"
2183
                               "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
2184
                               "`abcdefghijklmnopqrstuvwxyz{|}~\177"
2185
                               "\200\201\202\203\204\205\206\207"
2186
                               "\210\211\212\213\214\215\216\217"
2187
                               "\220\221\222\223\224\225\226\227"
2188
                               "\230\231\232\233\234\235\236\237"
2189
                               "\240\241\242\243\244\245\246\247"
2190
                               "\250\251\252\253\254\255\256\257"
2191
                               "\260\261\262\263\264\265\266\267"
2192
                               "\270\271\272\273\274\275\276\277"
2193
                               "\300\301\302\303\304\305\306\307"
2194
                               "\310\311\312\313\314\315\316\317"
2195
                               "\320\321\322\323\324\325\326\327"
2196
                               "\330\331\332\333\334\335\336\337"
2197
                               "\340\341\342\343\344\345\346\347"
2198
                               "\350\351\352\353\354\355\356\357"
2199
                               "\360\361\362\363\364\365\366\367"
2200
                               "\370\371\372\373\374\375\376\377")
2201
2202
2203
///////////////////////////////////////////////////////////////////////
2204
2205
PASN_BMPString::PASN_BMPString(const char * str)
2206
  : PASN_ConstrainedObject(UniversalBMPString, UniversalTagClass)
2207
{
2208
  Construct();
2209
  if (str != NULL)
2210
    SetValue(str);
2211
}
2212
2213
2214
PASN_BMPString::PASN_BMPString(const PWORDArray & wstr)
2215
  : PASN_ConstrainedObject(UniversalBMPString, UniversalTagClass)
2216
{
2217
  Construct();
2218
  SetValue(wstr);
2219
}
2220
2221
2222
PASN_BMPString::PASN_BMPString(unsigned tag, TagClass tagClass)
2223
  : PASN_ConstrainedObject(tag, tagClass)
2224
{
2225
  Construct();
2226
}
2227
2228
2229
void PASN_BMPString::Construct()
2230
{
2231
  firstChar = 0;
2232
  lastChar = 0xffff;
2233
  charSetAlignedBits = 16;
2234
  charSetUnalignedBits = 16;
2235
}
2236
2237
2238
PASN_BMPString::PASN_BMPString(const PASN_BMPString & other)
2239
  : PASN_ConstrainedObject(other),
2240
    value(other.value, other.value.GetSize()),
2241
    characterSet(other.characterSet)
2242
{
2243
  firstChar = other.firstChar;
2244
  lastChar = other.lastChar;
2245
  charSetAlignedBits = other.charSetAlignedBits;
2246
  charSetUnalignedBits = other.charSetUnalignedBits;
2247
}
2248
2249
2250
PASN_BMPString & PASN_BMPString::operator=(const PASN_BMPString & other)
2251
{
2252
  PASN_ConstrainedObject::operator=(other);
2253
2254
  value = PWORDArray(other.value, other.value.GetSize());
2255
  characterSet = other.characterSet;
2256
  firstChar = other.firstChar;
2257
  lastChar = other.lastChar;
2258
  charSetAlignedBits = other.charSetAlignedBits;
2259
  charSetUnalignedBits = other.charSetUnalignedBits;
2260
2261
  return *this;
2262
}
2263
2264
2265
BOOL PASN_BMPString::IsLegalCharacter(WORD ch)
2266
{
2267
  if (ch < firstChar)
2268
    return FALSE;
2269
2270
  if (ch > lastChar)
2271
    return FALSE;
2272
2273
  if (characterSet.IsEmpty())
2274
    return TRUE;
2275
2276
  const WORD * wptr = characterSet;
2277
  PINDEX count = characterSet.GetSize();
2278
  while (count-- > 0) {
2279
    if (*wptr == ch)
2280
      return TRUE;
2281
    wptr++;
2282
  }
2283
2284
  return FALSE;
2285
}
2286
2287
2288
PASN_BMPString & PASN_BMPString::operator=(const char * str)
2289
{
2290
  // Must be at least this big for string conversion
2291
  value.SetSize(::strlen(str));
2292
2293
  // Convert string looking for "&#1234;" style characters for 16 bit stuff
2294
  PINDEX count = 0;
2295
  while (*str != '\0') {
2296
    WORD c = (BYTE)*str++;
2297
2298
    if (c == '&' && *str == '#') {
2299
      unsigned bigChar = 0;
2300
      const char * p = str+1;
2301
      while (isdigit(*p))
2302
        bigChar = bigChar*10 + *p++ - '0';
2303
      if (*p == ';' && bigChar < 65536) {
2304
        c = (WORD)bigChar;
2305
        str = p + 1;
2306
      }
2307
    }
2308
2309
    if (IsLegalCharacter(c))
2310
      value[count++] = c;
2311
  }
2312
2313
  // Can't have any more than the upper constraint
2314
  if ((unsigned)count > upperLimit)
2315
    count = upperLimit;
2316
2317
  // Number of bytes must be at least lhe lower constraint
2318
  PINDEX newSize = (int)count < lowerLimit ? lowerLimit : count;
2319
  value.SetSize(newSize);
2320
2321
  // Pad out with the first character till required size
2322
  while (count < newSize)
2323
    value[count++] = firstChar;
2324
2325
  return *this;
2326
}
2327
2328
2329
PASN_BMPString & PASN_BMPString::operator=(const PWORDArray & array)
2330
{
2331
  PINDEX paramSize = array.GetSize();
2332
2333
  // Can't copy any more than the upper constraint
2334
  if ((unsigned)paramSize > upperLimit)
2335
    paramSize = upperLimit;
2336
2337
  // Number of bytes must be at least lhe lower constraint
2338
  PINDEX newSize = (int)paramSize < lowerLimit ? lowerLimit : paramSize;
2339
  value.SetSize(newSize);
2340
2341
  PINDEX count = 0;
2342
  for (PINDEX i = 0; i < paramSize; i++) {
2343
    WORD c = array[i];
2344
    if (IsLegalCharacter(c))
2345
      value[count++] = c;
2346
  }
2347
2348
  // Pad out with the first character till required size
2349
  while (count < newSize)
2350
    value[count++] = firstChar;
2351
2352
  return *this;
2353
}
2354
2355
2356
PString PASN_BMPString::GetValue() const
2357
{
2358
  PString str;
2359
  for (PINDEX i = 0; i < value.GetSize(); i++) {
2360
    if (value[i] > 0 && value[i] < 256)
2361
      str += (char)value[i];
2362
    else
2363
      str.sprintf("&#%u;", value[i]);
2364
  }
2365
  return str;
2366
}
2367
2368
2369
void PASN_BMPString::SetCharacterSet(ConstraintType ctype, const char * charSet)
2370
{
2371
  PWORDArray array(strlen(charSet));
2372
2373
  PINDEX count = 0;
2374
  while (*charSet != '\0')
2375
    array[count++] = (BYTE)*charSet++;
2376
2377
  SetCharacterSet(ctype, array);
2378
}
2379
2380
2381
void PASN_BMPString::SetCharacterSet(ConstraintType ctype, const PWORDArray & charSet)
2382
{
2383
  if (ctype == Unconstrained) {
2384
    firstChar = 0;
2385
    lastChar = 0xffff;
2386
    characterSet.SetSize(0);
2387
  }
2388
  else {
2389
    characterSet = charSet;
2390
2391
    charSetUnalignedBits = CountBits(lastChar - firstChar + 1);
2392
    if (!charSet.IsEmpty()) {
2393
      unsigned count = 0;
2394
      for (PINDEX i = 0; i < charSet.GetSize(); i++) {
2395
        if (characterSet[i] >= firstChar && characterSet[i] <= lastChar)
2396
          count++;
2397
      }
2398
      count = CountBits(count);
2399
      if (charSetUnalignedBits > count)
2400
        charSetUnalignedBits = count;
2401
    }
2402
2403
    charSetAlignedBits = 1;
2404
    while (charSetUnalignedBits > charSetAlignedBits)
2405
      charSetAlignedBits <<= 1;
2406
2407
    SetValue(value);
2408
  }
2409
}
2410
2411
2412
void PASN_BMPString::SetCharacterSet(ConstraintType ctype, unsigned first, unsigned last)
2413
{
2414
  if (ctype != Unconstrained) {
2415
    PAssert(first < 0x10000 && last < 0x10000 && last > first, PInvalidParameter);
2416
    firstChar = (WORD)first;
2417
    lastChar = (WORD)last;
2418
  }
2419
  SetCharacterSet(ctype, characterSet);
2420
}
2421
2422
2423
PObject * PASN_BMPString::Clone() const
2424
{
2425
  PAssert(IsClass(PASN_BMPString::Class()), PInvalidCast);
2426
  return new PASN_BMPString(*this);
2427
}
2428
2429
2430
PObject::Comparison PASN_BMPString::Compare(const PObject & obj) const
2431
{
2432
  PAssert(obj.IsDescendant(PASN_BMPString::Class()), PInvalidCast);
2433
  const PASN_BMPString & other = (const PASN_BMPString &)obj;
2434
  return value.Compare(other.value);
2435
}
2436
2437
2438
void PASN_BMPString::PrintOn(ostream & strm) const
2439
{
2440
  int indent = strm.precision() + 2;
2441
  PINDEX sz = value.GetSize();
2442
  strm << ' ' << sz << " characters {\n";
2443
  PINDEX i = 0;
2444
  while (i < sz) {
2445
    strm << setw(indent) << " " << hex << setfill('0');
2446
    PINDEX j;
2447
    for (j = 0; j < 8; j++)
2448
      if (i+j < sz)
2449
        strm << setw(4) << value[i+j] << ' ';
2450
      else
2451
        strm << "     ";
2452
    strm << "  ";
2453
    for (j = 0; j < 8; j++) {
2454
      if (i+j < sz) {
2455
        WORD c = value[i+j];
2456
        if (c < 128 && isprint(c))
2457
          strm << (char)c;
2458
        else
2459
          strm << ' ';
2460
      }
2461
    }
2462
    strm << dec << setfill(' ') << '\n';
2463
    i += 8;
2464
  }
2465
  strm << setw(indent-1) << "}";
2466
}
2467
2468
2469
PString PASN_BMPString::GetTypeAsString() const
2470
{
2471
  return "BMP String";
2472
}
2473
2474
2475
PINDEX PASN_BMPString::GetDataLength() const
2476
{
2477
  return value.GetSize()*2;
2478
}
2479
2480
2481
BOOL PASN_BMPString::Decode(PASN_Stream & strm)
2482
{
2483
  return strm.BMPStringDecode(*this);
2484
}
2485
2486
2487
void PASN_BMPString::Encode(PASN_Stream & strm) const
2488
{
2489
  strm.BMPStringEncode(*this);
2490
}
2491
2492
2493
BOOL PASN_BMPString::DecodeBER(PBER_Stream & strm, unsigned len)
2494
{
2495
  value.SetSize(len/2);
2496
  return strm.BlockDecode((BYTE *)value.GetPointer(len), len) == len;
2497
}
2498
2499
2500
void PASN_BMPString::EncodeBER(PBER_Stream & strm) const
2501
{
2502
  strm.BlockEncode((const BYTE *)(const WORD *)value, value.GetSize()*2);
2503
}
2504
2505
2506
BOOL PASN_BMPString::DecodePER(PPER_Stream & strm)
2507
{
2508
  // X.691 Section 26
2509
2510
  unsigned len;
2511
  if (ConstrainedLengthDecode(strm, len) < 0)
2512
    return FALSE;
2513
2514
  value.SetSize(len);
2515
2516
  PINDEX nBits = strm.IsAligned() ? charSetAlignedBits : charSetUnalignedBits;
2517
2518
  if ((constraint == Unconstrained || upperLimit*nBits > 16) && strm.IsAligned())
2519
    strm.ByteAlign();
2520
2521
  for (PINDEX i = 0; i < (PINDEX)len; i++) {
2522
    unsigned theBits;
2523
    if (!strm.MultiBitDecode(nBits, theBits))
2524
      return FALSE;
2525
    if (characterSet.IsEmpty())
2526
      value[i] = (WORD)(theBits + firstChar);
2527
    else
2528
      value[i] = characterSet[(PINDEX)theBits];
2529
  }
2530
2531
  return TRUE;
2532
}
2533
2534
2535
void PASN_BMPString::EncodePER(PPER_Stream & strm) const
2536
{
2537
  // X.691 Section 26
2538
2539
  PINDEX len = value.GetSize();
2540
  ConstrainedLengthEncode(strm, len);
2541
2542
  PINDEX nBits = strm.IsAligned() ? charSetAlignedBits : charSetUnalignedBits;
2543
2544
  if ((constraint == Unconstrained || upperLimit*nBits > 16) && strm.IsAligned())
2545
    strm.ByteAlign();
2546
2547
  for (PINDEX i = 0; i < len; i++) {
2548
    if (characterSet.IsEmpty())
2549
      strm.MultiBitEncode(value[i] - firstChar, nBits);
2550
    else {
2551
      for (PINDEX pos = 0; pos < characterSet.GetSize(); pos++) {
2552
        if (characterSet[pos] == value[i]) {
2553
          strm.MultiBitEncode(pos, nBits);
2554
          break;
2555
        }
2556
      }
2557
    }
2558
  }
2559
}
2560
2561
2562
BOOL PBER_Stream::BMPStringDecode(PASN_BMPString & value)
2563
{
2564
  unsigned len;
2565
  if (!HeaderDecode(value, len))
2566
    return FALSE;
2567
2568
  return value.DecodeBER(*this, len);
2569
}
2570
2571
2572
void PBER_Stream::BMPStringEncode(const PASN_BMPString & value)
2573
{
2574
  HeaderEncode(value);
2575
  value.EncodeBER(*this);
2576
}
2577
2578
2579
BOOL PPER_Stream::BMPStringDecode(PASN_BMPString & value)
2580
{
2581
  return value.DecodePER(*this);
2582
}
2583
2584
2585
void PPER_Stream::BMPStringEncode(const PASN_BMPString & value)
2586
{
2587
  value.EncodePER(*this);
2588
}
2589
2590
2591
///////////////////////////////////////////////////////////////////////
2592
2593
PASN_GeneralisedTime & PASN_GeneralisedTime::operator=(const PTime & time)
2594
{
2595
  value = time.AsString("yyyyMMddhhmmss.uz");
2596
  value.Replace("GMT", "Z");
2597
  return *this;
2598
}
2599
2600
2601
PTime PASN_GeneralisedTime::GetValue() const
2602
{
2603
  int year = value(0,3).AsInteger();
2604
  int month = value(4,5).AsInteger();
2605
  int day = value(6,7).AsInteger();
2606
  int hour = value(8,9).AsInteger();
2607
  int minute = value(10,11).AsInteger();
2608
  int seconds = 0;
2609
  int zonePos = 12;
2610
2611
  if (isdigit(value[12])) {
2612
    seconds = value(12,13).AsInteger();
2613
    if (value[14] != '.')
2614
      zonePos = 14;
2615
    else {
2616
      zonePos = 15;
2617
      while (isdigit(value[zonePos]))
2618
        zonePos++;
2619
    }
2620
  }
2621
2622
  int zone = PTime::Local;
2623
  switch (value[zonePos]) {
2624
    case 'Z' :
2625
      zone = PTime::UTC;
2626
      break;
2627
    case '+' :
2628
    case '-' :
2629
      zone = value(zonePos+1,zonePos+2).AsInteger()*60 +
2630
             value(zonePos+3,zonePos+4).AsInteger();
2631
  }
2632
2633
  return PTime(seconds, minute, hour, day, month, year, zone);
2634
}
2635
2636
2637
///////////////////////////////////////////////////////////////////////
2638
2639
PASN_UniversalTime & PASN_UniversalTime::operator=(const PTime & time)
2640
{
2641
  value = time.AsString("yyMMddhhmmssz");
2642
  value.Replace("GMT", "Z");
2643
  return *this;
2644
}
2645
2646
2647
PTime PASN_UniversalTime::GetValue() const
2648
{
2649
  int year = value(0,1).AsInteger();
2650
  if (year < 36)
2651
    year += 2000;
2652
  else
2653
    year += 1900;
2654
2655
  int month = value(2,3).AsInteger();
2656
  int day = value(4,5).AsInteger();
2657
  int hour = value(6,7).AsInteger();
2658
  int minute = value(8,9).AsInteger();
2659
  int seconds = 0;
2660
  int zonePos = 10;
2661
2662
  if (isdigit(value[10])) {
2663
    seconds = value(10,11).AsInteger();
2664
    zonePos = 12;
2665
  }
2666
2667
  int zone = PTime::UTC;
2668
  if (value[zonePos] != 'Z')
2669
    zone = value(zonePos+1,zonePos+2).AsInteger()*60 +
2670
           value(zonePos+3,zonePos+4).AsInteger();
2671
2672
  return PTime(seconds, minute, hour, day, month, year, zone);
2673
}
2674
2675
2676
///////////////////////////////////////////////////////////////////////
2677
2678
PASN_Choice::PASN_Choice(unsigned nChoices, BOOL extend)
2679
  : PASN_Object(0, ApplicationTagClass, extend)
2680
{
2681
  numChoices = nChoices;
2682
  choice = NULL;
2683
}
2684
2685
2686
PASN_Choice::PASN_Choice(unsigned tag, TagClass tagClass,
2687
                         unsigned upper, BOOL extend)
2688
  : PASN_Object(tag, tagClass, extend)
2689
{
2690
  numChoices = upper;
2691
  choice = NULL;
2692
}
2693
2694
2695
PASN_Choice::PASN_Choice(unsigned tag, TagClass tagClass,
2696
                         unsigned upper, BOOL extend, const PString & nameSpec)
2697
  : PASN_Object(tag, tagClass, extend),
2698
    names(BuildNamesDict(nameSpec))
2699
{
2700
  numChoices = upper;
2701
  choice = NULL;
2702
}
2703
2704
2705
PASN_Choice::PASN_Choice(const PASN_Choice & other)
2706
  : PASN_Object(other),
2707
    names(other.names)
2708
{
2709
  numChoices = other.numChoices;
2710
2711
  if (other.CheckCreate())
2712
    choice = (PASN_Object *)other.choice->Clone();
2713
  else
2714
    choice = NULL;
2715
}
2716
2717
2718
PASN_Choice & PASN_Choice::operator=(const PASN_Choice & other)
2719
{
2720
  if (&other == this) // Assigning to ourself, just do nothing.
2721
    return *this;
2722
2723
  delete choice;
2724
2725
  PASN_Object::operator=(other);
2726
2727
  numChoices = other.numChoices;
2728
  names = other.names;
2729
2730
  if (other.CheckCreate())
2731
    choice = (PASN_Object *)other.choice->Clone();
2732
  else
2733
    choice = NULL;
2734
2735
  return *this;
2736
}
2737
2738
2739
PASN_Choice::~PASN_Choice()
2740
{
2741
  delete choice;
2742
}
2743
2744
2745
void PASN_Choice::SetTag(unsigned newTag, TagClass tagClass)
2746
{
2747
  PASN_Object::SetTag(newTag, tagClass);
2748
2749
  delete choice;
2750
2751
  if (CreateObject())
2752
    choice->SetTag(newTag, tagClass);
2753
}
2754
2755
2756
PString PASN_Choice::GetTagName() const
2757
{
2758
  if (names.Contains(tag))
2759
    return names[tag];
2760
2761
  if (CheckCreate() &&
2762
      choice->IsDescendant(PASN_Choice::Class()) &&
2763
      choice->GetTag() == tag &&
2764
      choice->GetTagClass() == tagClass)
2765
    return PString(choice->GetClass()) + "->" + ((PASN_Choice *)choice)->GetTagName();
2766
2767
  return psprintf("<%u>", tag);
2768
}
2769
2770
2771
BOOL PASN_Choice::CheckCreate() const
2772
{
2773
  if (choice != NULL)
2774
    return TRUE;
2775
2776
  return ((PASN_Choice *)this)->CreateObject();
2777
}
2778
2779
2780
PASN_Object & PASN_Choice::GetObject() const
2781
{
2782
  PAssert(CheckCreate(), "NULL Choice");
2783
  return *choice;
2784
}
2785
2786
2787
#if defined(__GNUC__) && __GNUC__ <= 2 && __GNUC_MINOR__ < 9
2788
2789
#define CHOICE_CAST_OPERATOR(cls) \
2790
  PASN_Choice::operator cls &() const \
2791
  { \
2792
    PAssert(CheckCreate(), "Cast of NULL choice"); \
2793
    PAssert(choice->IsDescendant(cls::Class()), PInvalidCast); \
2794
    return *(cls *)choice; \
2795
  } \
2796
2797
#else
2798
2799
#define CHOICE_CAST_OPERATOR(cls) \
2800
  PASN_Choice::operator cls &() \
2801
  { \
2802
    PAssert(CheckCreate(), "Cast of NULL choice"); \
2803
    PAssert(choice->IsDescendant(cls::Class()), PInvalidCast); \
2804
    return *(cls *)choice; \
2805
  } \
2806
  PASN_Choice::operator const cls &() const \
2807
  { \
2808
    PAssert(CheckCreate(), "Cast of NULL choice"); \
2809
    PAssert(choice->IsDescendant(cls::Class()), PInvalidCast); \
2810
    return *(const cls *)choice; \
2811
  } \
2812
2813
#endif
2814
2815
2816
CHOICE_CAST_OPERATOR(PASN_Null)
2817
CHOICE_CAST_OPERATOR(PASN_Boolean)
2818
CHOICE_CAST_OPERATOR(PASN_Integer)
2819
CHOICE_CAST_OPERATOR(PASN_Enumeration)
2820
CHOICE_CAST_OPERATOR(PASN_Real)
2821
CHOICE_CAST_OPERATOR(PASN_ObjectId)
2822
CHOICE_CAST_OPERATOR(PASN_BitString)
2823
CHOICE_CAST_OPERATOR(PASN_OctetString)
2824
CHOICE_CAST_OPERATOR(PASN_NumericString)
2825
CHOICE_CAST_OPERATOR(PASN_PrintableString)
2826
CHOICE_CAST_OPERATOR(PASN_VisibleString)
2827
CHOICE_CAST_OPERATOR(PASN_IA5String)
2828
CHOICE_CAST_OPERATOR(PASN_GeneralString)
2829
CHOICE_CAST_OPERATOR(PASN_BMPString)
2830
CHOICE_CAST_OPERATOR(PASN_Sequence)
2831
2832
2833
PObject::Comparison PASN_Choice::Compare(const PObject & obj) const
2834
{
2835
  PAssert(obj.IsDescendant(PASN_Choice::Class()), PInvalidCast);
2836
  const PASN_Choice & other = (const PASN_Choice &)obj;
2837
2838
  CheckCreate();
2839
  other.CheckCreate();
2840
2841
  if (choice == other.choice)
2842
    return EqualTo;
2843
2844
  if (choice == NULL)
2845
    return LessThan;
2846
2847
  if (other.choice == NULL)
2848
    return GreaterThan;
2849
2850
  if (tag < other.tag)
2851
    return LessThan;
2852
2853
  if (tag > other.tag)
2854
    return GreaterThan;
2855
2856
  return choice->Compare(*other.choice);
2857
}
2858
2859
2860
void PASN_Choice::PrintOn(ostream & strm) const
2861
{
2862
  strm << GetTagName();
2863
2864
  if (choice != NULL)
2865
    strm << ' ' << *choice;
2866
  else
2867
    strm << " (NULL)";
2868
}
2869
2870
2871
PString PASN_Choice::GetTypeAsString() const
2872
{
2873
  return "Choice";
2874
}
2875
2876
2877
PINDEX PASN_Choice::GetDataLength() const
2878
{
2879
  if (CheckCreate())
2880
    return choice->GetDataLength();
2881
2882
  return 0;
2883
}
2884
2885
2886
BOOL PASN_Choice::IsPrimitive() const
2887
{
2888
  if (CheckCreate())
2889
    return choice->IsPrimitive();
2890
  return FALSE;
2891
}
2892
2893
2894
BOOL PASN_Choice::Decode(PASN_Stream & strm)
2895
{
2896
  return strm.ChoiceDecode(*this);
2897
}
2898
2899
2900
void PASN_Choice::Encode(PASN_Stream & strm) const
2901
{
2902
  strm.ChoiceEncode(*this);
2903
}
2904
2905
2906
BOOL PASN_Choice::DecodePER(PPER_Stream & strm)
2907
{
2908
  // X.691 Section 22
2909
  delete choice;
2910
  choice = NULL;
2911
2912
  if (strm.IsAtEnd())
2913
    return FALSE;
2914
2915
  if (extendable) {
2916
    if (strm.SingleBitDecode()) {
2917
      if (!strm.SmallUnsignedDecode(tag))
2918
        return FALSE;
2919
2920
      tag += numChoices;
2921
2922
      unsigned len;
2923
      if (strm.LengthDecode(0, INT_MAX, len) != 0)
2924
        return FALSE;
2925
2926
      BOOL ok;
2927
      if (CreateObject()) {
2928
        PINDEX nextPos = strm.GetPosition() + len;
2929
        ok = choice->Decode(strm);
2930
        strm.SetPosition(nextPos);
2931
      }
2932
      else {
2933
        PASN_OctetString * open_type = new PASN_OctetString;
2934
        open_type->SetConstraints(PASN_ConstrainedObject::FixedConstraint, len);
2935
        ok = open_type->Decode(strm);
2936
        if (open_type->GetSize() > 0)
2937
          choice = open_type;
2938
        else {
2939
          delete open_type;
2940
          ok = FALSE;
2941
        }
2942
      }
2943
      return ok;
2944
    }
2945
  }
2946
2947
  if (numChoices < 2)
2948
    tag = 0;
2949
  else {
2950
    if (strm.UnsignedDecode(0, numChoices-1, tag) < 0)
2951
      return FALSE;
2952
  }
2953
2954
  return CreateObject() && choice->Decode(strm);
2955
}
2956
2957
2958
void PASN_Choice::EncodePER(PPER_Stream & strm) const
2959
{
2960
  PAssert(CheckCreate(), PLogicError);
2961
2962
  if (extendable) {
2963
    BOOL extended = tag >= numChoices;
2964
    strm.SingleBitEncode(extended);
2965
    if (extended) {
2966
      strm.SmallUnsignedEncode(tag - numChoices);
2967
      strm.AnyTypeEncode(choice);
2968
      return;
2969
    }
2970
  }
2971
2972
  if (numChoices > 1)
2973
    strm.UnsignedEncode(tag, 0, numChoices-1);
2974
2975
  choice->Encode(strm);
2976
}
2977
2978
2979
BOOL PBER_Stream::ChoiceDecode(PASN_Choice & value)
2980
{
2981
  PINDEX savedPosition = GetPosition();
2982
2983
  unsigned tag;
2984
  PASN_Object::TagClass tagClass;
2985
  BOOL primitive;
2986
  unsigned entryLen;
2987
  if (!HeaderDecode(tag, tagClass, primitive, entryLen))
2988
    return FALSE;
2989
2990
  SetPosition(savedPosition);
2991
2992
  value.SetTag(tag, tagClass);
2993
  if (value.IsValid())
2994
    return value.GetObject().Decode(*this);
2995
2996
  return TRUE;
2997
}
2998
2999
3000
void PBER_Stream::ChoiceEncode(const PASN_Choice & value)
3001
{
3002
  if (value.IsValid())
3003
    value.GetObject().Encode(*this);
3004
}
3005
3006
3007
BOOL PPER_Stream::ChoiceDecode(PASN_Choice & value)
3008
{
3009
  return value.DecodePER(*this);
3010
}
3011
3012
3013
void PPER_Stream::ChoiceEncode(const PASN_Choice & value)
3014
{
3015
  value.EncodePER(*this);
3016
}
3017
3018
3019
///////////////////////////////////////////////////////////////////////
3020
3021
PASN_Sequence::PASN_Sequence(unsigned tag, TagClass tagClass,
3022
                             unsigned nOpts, BOOL extend, unsigned nExtend)
3023
  : PASN_Object(tag, tagClass, extend)
3024
{
3025
  optionMap.SetConstraints(PASN_ConstrainedObject::FixedConstraint, nOpts);
3026
  knownExtensions = nExtend;
3027
  totalExtensions = 0;
3028
  endBasicEncoding = 0;
3029
}
3030
3031
3032
PASN_Sequence::PASN_Sequence(const PASN_Sequence & other)
3033
  : PASN_Object(other),
3034
    fields(other.fields.GetSize()),
3035
    optionMap(other.optionMap),
3036
    extensionMap(other.extensionMap)
3037
{
3038
  for (PINDEX i = 0; i < other.fields.GetSize(); i++)
3039
    fields.SetAt(i, other.fields[i].Clone());
3040
3041
  knownExtensions = other.knownExtensions;
3042
  totalExtensions = other.totalExtensions;
3043
  endBasicEncoding = 0;
3044
}
3045
3046
3047
PASN_Sequence & PASN_Sequence::operator=(const PASN_Sequence & other)
3048
{
3049
  PASN_Object::operator=(other);
3050
3051
  fields.SetSize(other.fields.GetSize());
3052
  for (PINDEX i = 0; i < other.fields.GetSize(); i++)
3053
    fields.SetAt(i, other.fields[i].Clone());
3054
3055
  optionMap = other.optionMap;
3056
  knownExtensions = other.knownExtensions;
3057
  totalExtensions = other.totalExtensions;
3058
  extensionMap = other.extensionMap;
3059
3060
  return *this;
3061
}
3062
3063
3064
BOOL PASN_Sequence::HasOptionalField(PINDEX opt) const
3065
{
3066
  if (opt < (PINDEX)optionMap.GetSize())
3067
    return optionMap[opt];
3068
  else
3069
    return extensionMap[opt - optionMap.GetSize()];
3070
}
3071
3072
3073
void PASN_Sequence::IncludeOptionalField(PINDEX opt)
3074
{
3075
  if (opt < (PINDEX)optionMap.GetSize())
3076
    optionMap.Set(opt);
3077
  else {
3078
    PAssert(extendable, "Must be extendable type");
3079
    opt -= optionMap.GetSize();
3080
    if (opt >= (PINDEX)extensionMap.GetSize())
3081
      extensionMap.SetSize(opt+1);
3082
    extensionMap.Set(opt);
3083
  }
3084
}
3085
3086
3087
void PASN_Sequence::RemoveOptionalField(PINDEX opt)
3088
{
3089
  if (opt < (PINDEX)optionMap.GetSize())
3090
    optionMap.Clear(opt);
3091
  else {
3092
    PAssert(extendable, "Must be extendable type");
3093
    opt -= optionMap.GetSize();
3094
    extensionMap.Clear(opt);
3095
  }
3096
}
3097
3098
3099
PObject::Comparison PASN_Sequence::Compare(const PObject & obj) const
3100
{
3101
  PAssert(obj.IsDescendant(PASN_Sequence::Class()), PInvalidCast);
3102
  const PASN_Sequence & other = (const PASN_Sequence &)obj;
3103
  return fields.Compare(other.fields);
3104
}
3105
3106
3107
PObject * PASN_Sequence::Clone() const
3108
{
3109
  PAssert(IsClass(PASN_Sequence::Class()), PInvalidCast);
3110
  return new PASN_Sequence(*this);
3111
}
3112
3113
3114
void PASN_Sequence::PrintOn(ostream & strm) const
3115
{
3116
  int indent = strm.precision() + 2;
3117
  strm << "{\n";
3118
  for (PINDEX i = 0; i < fields.GetSize(); i++) {
3119
    strm << setw(indent+6) << "field[" << i << "] <";
3120
    switch (fields[i].GetTagClass()) {
3121
      case UniversalTagClass :
3122
        strm << "Universal";
3123
        break;
3124
      case ApplicationTagClass :
3125
        strm << "Application";
3126
        break;
3127
      case ContextSpecificTagClass :
3128
        strm << "ContextSpecific";
3129
        break;
3130
      case PrivateTagClass :
3131
        strm << "Private";
3132
      default :
3133
        break;
3134
    }
3135
    strm << '-' << fields[i].GetTag() << '-'
3136
         << fields[i].GetTypeAsString() << "> = "
3137
         << fields[i] << '\n';
3138
  }
3139
  strm << setw(indent-1) << "}";
3140
}
3141
3142
3143
PString PASN_Sequence::GetTypeAsString() const
3144
{
3145
  return "Sequence";
3146
}
3147
3148
3149
PINDEX PASN_Sequence::GetDataLength() const
3150
{
3151
  PINDEX len = 0;
3152
  for (PINDEX i = 0; i < fields.GetSize(); i++)
3153
    len += fields[i].GetObjectLength();
3154
  return len;
3155
}
3156
3157
3158
BOOL PASN_Sequence::IsPrimitive() const
3159
{
3160
  return FALSE;
3161
}
3162
3163
3164
BOOL PASN_Sequence::Decode(PASN_Stream & strm)
3165
{
3166
  return PreambleDecode(strm) && UnknownExtensionsDecode(strm);
3167
}
3168
3169
3170
void PASN_Sequence::Encode(PASN_Stream & strm) const
3171
{
3172
  PreambleEncode(strm);
3173
  UnknownExtensionsEncode(strm);
3174
}
3175
3176
3177
BOOL PASN_Sequence::PreambleDecode(PASN_Stream & strm)
3178
{
3179
  return strm.SequencePreambleDecode(*this);
3180
}
3181
3182
3183
void PASN_Sequence::PreambleEncode(PASN_Stream & strm) const
3184
{
3185
  strm.SequencePreambleEncode(*this);
3186
}
3187
3188
3189
BOOL PASN_Sequence::KnownExtensionDecode(PASN_Stream & strm, PINDEX fld, PASN_Object & field)
3190
{
3191
  return strm.SequenceKnownDecode(*this, fld, field);
3192
}
3193
3194
3195
void PASN_Sequence::KnownExtensionEncode(PASN_Stream & strm, PINDEX fld, const PASN_Object & field) const
3196
{
3197
  strm.SequenceKnownEncode(*this, fld, field);
3198
}
3199
3200
3201
BOOL PASN_Sequence::UnknownExtensionsDecode(PASN_Stream & strm)
3202
{
3203
  return strm.SequenceUnknownDecode(*this);
3204
}
3205
3206
3207
void PASN_Sequence::UnknownExtensionsEncode(PASN_Stream & strm) const
3208
{
3209
  strm.SequenceUnknownEncode(*this);
3210
}
3211
3212
3213
BOOL PASN_Sequence::PreambleDecodeBER(PBER_Stream & strm)
3214
{
3215
  fields.RemoveAll();
3216
3217
  unsigned len;
3218
  if (!strm.HeaderDecode(*this, len))
3219
    return FALSE;
3220
3221
  endBasicEncoding = strm.GetPosition() + len;
3222
  return !strm.IsAtEnd();
3223
}
3224
3225
3226
void PASN_Sequence::PreambleEncodeBER(PBER_Stream & strm) const
3227
{
3228
  strm.HeaderEncode(*this);
3229
}
3230
3231
3232
BOOL PASN_Sequence::KnownExtensionDecodeBER(PBER_Stream & strm, PINDEX, PASN_Object & field)
3233
{
3234
  if (strm.GetPosition() >= endBasicEncoding)
3235
    return FALSE;
3236
3237
  return field.Decode(strm);
3238
}
3239
3240
3241
void PASN_Sequence::KnownExtensionEncodeBER(PBER_Stream & strm, PINDEX, const PASN_Object & field) const
3242
{
3243
  field.Encode(strm);
3244
}
3245
3246
3247
BOOL PASN_Sequence::UnknownExtensionsDecodeBER(PBER_Stream & strm)
3248
{
3249
  while (strm.GetPosition() < endBasicEncoding) {
3250
    PINDEX savedPosition = strm.GetPosition();
3251
3252
    unsigned tag;
3253
    PASN_Object::TagClass tagClass;
3254
    BOOL primitive;
3255
    unsigned entryLen;
3256
    if (!strm.HeaderDecode(tag, tagClass, primitive, entryLen))
3257
      return FALSE;
3258
3259
    PINDEX nextEntryPosition = strm.GetPosition() + entryLen;
3260
    strm.SetPosition(savedPosition);
3261
3262
    PASN_Object * obj = strm.CreateObject(tag, tagClass, primitive);
3263
    if (obj == NULL)
3264
      strm.SetPosition(nextEntryPosition);
3265
    else {
3266
      if (!obj->Decode(strm))
3267
        return FALSE;
3268
3269
      fields.Append(obj);
3270
    }
3271
  }
3272
3273
  return TRUE;
3274
}
3275
3276
3277
void PASN_Sequence::UnknownExtensionsEncodeBER(PBER_Stream & strm) const
3278
{
3279
  for (PINDEX i = 0; i < fields.GetSize(); i++)
3280
    fields[i].Encode(strm);
3281
}
3282
3283
3284
BOOL PASN_Sequence::PreambleDecodePER(PPER_Stream & strm)
3285
{
3286
  // X.691 Section 18
3287
3288
  if (extendable) {
3289
    if (strm.IsAtEnd())
3290
      return FALSE;
3291
    totalExtensions = strm.SingleBitDecode() ? -1 : 0;  // 18.1
3292
  }
3293
  else
3294
    totalExtensions = 0;
3295
  return optionMap.Decode(strm);  // 18.2
3296
}
3297
3298
3299
void PASN_Sequence::PreambleEncodePER(PPER_Stream & strm) const
3300
{
3301
  // X.691 Section 18
3302
3303
  if (extendable) {
3304
    BOOL hasExtensions = FALSE;
3305
    for (unsigned i = 0; i < extensionMap.GetSize(); i++) {
3306
      if (extensionMap[i]) {
3307
        hasExtensions = TRUE;
3308
        break;
3309
      }
3310
    }
3311
    strm.SingleBitEncode(hasExtensions);  // 18.1
3312
    ((PASN_Sequence*)this)->totalExtensions = hasExtensions ? -1 : 0;
3313
  }
3314
  optionMap.Encode(strm);  // 18.2
3315
}
3316
3317
3318
BOOL PASN_Sequence::NoExtensionsToDecode(PPER_Stream & strm)
3319
{
3320
  if (totalExtensions == 0)
3321
    return TRUE;
3322
3323
  if (totalExtensions < 0) {
3324
    if (!extensionMap.DecodeSequenceExtensionBitmap(strm))
3325
      return FALSE;
3326
    totalExtensions = extensionMap.GetSize();
3327
  }
3328
3329
  return FALSE;
3330
}
3331
3332
3333
BOOL PASN_Sequence::NoExtensionsToEncode(PPER_Stream & strm)
3334
{
3335
  if (totalExtensions == 0)
3336
    return TRUE;
3337
3338
  if (totalExtensions < 0) {
3339
    totalExtensions = extensionMap.GetSize();
3340
    extensionMap.EncodeSequenceExtensionBitmap(strm);
3341
  }
3342
3343
  return FALSE;
3344
}
3345
3346
3347
BOOL PASN_Sequence::KnownExtensionDecodePER(PPER_Stream & strm, PINDEX fld, PASN_Object & field)
3348
{
3349
  if (NoExtensionsToDecode(strm))
3350
    return TRUE;
3351
3352
  if (!extensionMap[fld-optionMap.GetSize()])
3353
    return TRUE;
3354
3355
  unsigned len;
3356
  if (strm.LengthDecode(0, INT_MAX, len) != 0)
3357
    return FALSE;
3358
3359
  PINDEX nextExtensionPosition = strm.GetPosition() + len;
3360
  BOOL ok = field.Decode(strm);
3361
  strm.SetPosition(nextExtensionPosition);
3362
  return ok;
3363
}
3364
3365
3366
void PASN_Sequence::KnownExtensionEncodePER(PPER_Stream & strm, PINDEX fld, const PASN_Object & field) const
3367
{
3368
  if (((PASN_Sequence*)this)->NoExtensionsToEncode(strm))
3369
    return;
3370
3371
  if (!extensionMap[fld-optionMap.GetSize()])
3372
    return;
3373
3374
  strm.AnyTypeEncode(&field);
3375
}
3376
3377
3378
BOOL PASN_Sequence::UnknownExtensionsDecodePER(PPER_Stream & strm)
3379
{
3380
  if (NoExtensionsToDecode(strm))
3381
    return TRUE;
3382
3383
  if (totalExtensions <= knownExtensions)
3384
    return TRUE;  // Already read them
3385
3386
  PINDEX unknownCount = totalExtensions - knownExtensions;
3387
  if (fields.GetSize() >= unknownCount)
3388
    return TRUE;  // Already read them
3389
3390
  fields.SetSize(unknownCount);
3391
3392
  PINDEX i;
3393
  for (i = 0; i < fields.GetSize(); i++)
3394
    fields.SetAt(i, new PASN_OctetString);
3395
3396
  for (i = knownExtensions; i < (PINDEX)extensionMap.GetSize(); i++) {
3397
    if (extensionMap[i])
3398
      if (!fields[i-knownExtensions].Decode(strm))
3399
        return FALSE;
3400
  }
3401
3402
  return TRUE;
3403
}
3404
3405
3406
void PASN_Sequence::UnknownExtensionsEncodePER(PPER_Stream & strm) const
3407
{
3408
  if (((PASN_Sequence*)this)->NoExtensionsToEncode(strm))
3409
    return;
3410
3411
  int i;
3412
  for (i = knownExtensions; i < totalExtensions; i++) {
3413
    if (extensionMap[i])
3414
      fields[i-knownExtensions].Encode(strm);
3415
  }
3416
}
3417
3418
3419
BOOL PBER_Stream::SequencePreambleDecode(PASN_Sequence & seq)
3420
{
3421
  return seq.PreambleDecodeBER(*this);
3422
}
3423
3424
3425
void PBER_Stream::SequencePreambleEncode(const PASN_Sequence & seq)
3426
{
3427
  seq.PreambleEncodeBER(*this);
3428
}
3429
3430
3431
BOOL PBER_Stream::SequenceKnownDecode(PASN_Sequence & seq, PINDEX fld, PASN_Object & field)
3432
{
3433
  return seq.KnownExtensionDecodeBER(*this, fld, field);
3434
}
3435
3436
3437
void PBER_Stream::SequenceKnownEncode(const PASN_Sequence & seq, PINDEX fld, const PASN_Object & field)
3438
{
3439
  seq.KnownExtensionEncodeBER(*this, fld, field);
3440
}
3441
3442
3443
BOOL PBER_Stream::SequenceUnknownDecode(PASN_Sequence & seq)
3444
{
3445
  return seq.UnknownExtensionsDecodeBER(*this);
3446
}
3447
3448
3449
void PBER_Stream::SequenceUnknownEncode(const PASN_Sequence & seq)
3450
{
3451
  seq.UnknownExtensionsEncodeBER(*this);
3452
}
3453
3454
3455
BOOL PPER_Stream::SequencePreambleDecode(PASN_Sequence & seq)
3456
{
3457
  return seq.PreambleDecodePER(*this);
3458
}
3459
3460
3461
void PPER_Stream::SequencePreambleEncode(const PASN_Sequence & seq)
3462
{
3463
  seq.PreambleEncodePER(*this);
3464
}
3465
3466
3467
BOOL PPER_Stream::SequenceKnownDecode(PASN_Sequence & seq, PINDEX fld, PASN_Object & field)
3468
{
3469
  return seq.KnownExtensionDecodePER(*this, fld, field);
3470
}
3471
3472
3473
void PPER_Stream::SequenceKnownEncode(const PASN_Sequence & seq, PINDEX fld, const PASN_Object & field)
3474
{
3475
  seq.KnownExtensionEncodePER(*this, fld, field);
3476
}
3477
3478
3479
BOOL PPER_Stream::SequenceUnknownDecode(PASN_Sequence & seq)
3480
{
3481
  return seq.UnknownExtensionsDecodePER(*this);
3482
}
3483
3484
3485
void PPER_Stream::SequenceUnknownEncode(const PASN_Sequence & seq)
3486
{
3487
  seq.UnknownExtensionsEncodePER(*this);
3488
}
3489
3490
3491
///////////////////////////////////////////////////////////////////////
3492
3493
PASN_Set::PASN_Set(unsigned tag, TagClass tagClass,
3494
                   unsigned nOpts, BOOL extend, unsigned nExtend)
3495
  : PASN_Sequence(tag, tagClass, nOpts, extend, nExtend)
3496
{
3497
}
3498
3499
3500
PObject * PASN_Set::Clone() const
3501
{
3502
  PAssert(IsClass(PASN_Set::Class()), PInvalidCast);
3503
  return new PASN_Set(*this);
3504
}
3505
3506
3507
PString PASN_Set::GetTypeAsString() const
3508
{
3509
  return "Set";
3510
}
3511
3512
3513
///////////////////////////////////////////////////////////////////////
3514
3515
PASN_Array::PASN_Array(unsigned tag, TagClass tagClass)
3516
  : PASN_ConstrainedObject(tag, tagClass)
3517
{
3518
}
3519
3520
3521
PASN_Array::PASN_Array(const PASN_Array & other)
3522
  : PASN_ConstrainedObject(other),
3523
    array(other.array.GetSize())
3524
{
3525
  for (PINDEX i = 0; i < other.array.GetSize(); i++)
3526
    array.SetAt(i, other.array[i].Clone());
3527
}
3528
3529
3530
PASN_Array & PASN_Array::operator=(const PASN_Array & other)
3531
{
3532
  PASN_ConstrainedObject::operator=(other);
3533
3534
  array.SetSize(other.array.GetSize());
3535
  for (PINDEX i = 0; i < other.array.GetSize(); i++)
3536
    array.SetAt(i, other.array[i].Clone());
3537
3538
  return *this;
3539
}
3540
3541
3542
void PASN_Array::SetSize(PINDEX newSize)
3543
{
3544
  PINDEX originalSize = array.GetSize();
3545
  array.SetSize(newSize);
3546
  for (PINDEX i = originalSize; i < newSize; i++)
3547
    array.SetAt(i, CreateObject());
3548
}
3549
3550
3551
PObject::Comparison PASN_Array::Compare(const PObject & obj) const
3552
{
3553
  PAssert(obj.IsDescendant(PASN_Array::Class()), PInvalidCast);
3554
  const PASN_Array & other = (const PASN_Array &)obj;
3555
  return array.Compare(other.array);
3556
}
3557
3558
3559
void PASN_Array::PrintOn(ostream & strm) const
3560
{
3561
  int indent = strm.precision() + 2;
3562
  strm << array.GetSize() << " entries {\n";
3563
  for (PINDEX i = 0; i < array.GetSize(); i++)
3564
    strm << setw(indent+1) << "[" << i << "]=" << setprecision(indent) << array[i] << '\n';
3565
  strm << setw(indent-1) << "}";
3566
}
3567
3568
3569
void PASN_Array::SetConstraintBounds(ConstraintType type, int lower, unsigned upper)
3570
{
3571
  PAssert(lower >= 0, PInvalidParameter);
3572
  PASN_ConstrainedObject::SetConstraintBounds(type, lower, upper);
3573
  if (constraint != Unconstrained) {
3574
    if (GetSize() < (PINDEX)lowerLimit)
3575
      SetSize(lowerLimit);
3576
    else if (GetSize() > (PINDEX)upperLimit)
3577
      SetSize(upperLimit);
3578
  }
3579
}
3580
3581
3582
PString PASN_Array::GetTypeAsString() const
3583
{
3584
  return "Array";
3585
}
3586
3587
3588
PINDEX PASN_Array::GetDataLength() const
3589
{
3590
  PINDEX len = 0;
3591
  for (PINDEX i = 0; i < array.GetSize(); i++)
3592
    len += array[i].GetObjectLength();
3593
  return len;
3594
}
3595
3596
3597
BOOL PASN_Array::IsPrimitive() const
3598
{
3599
  return FALSE;
3600
}
3601
3602
3603
BOOL PASN_Array::Decode(PASN_Stream & strm)
3604
{
3605
  return strm.ArrayDecode(*this);
3606
}
3607
3608
3609
void PASN_Array::Encode(PASN_Stream & strm) const
3610
{
3611
  strm.ArrayEncode(*this);
3612
}
3613
3614
3615
BOOL PBER_Stream::ArrayDecode(PASN_Array & array)
3616
{
3617
  array.RemoveAll();
3618
3619
  unsigned len;
3620
  if (!HeaderDecode(array, len))
3621
    return FALSE;
3622
3623
  PINDEX endOffset = byteOffset + len;
3624
  PINDEX count = 0;
3625
  while (byteOffset < endOffset) {
3626
    array.SetSize(count+1);
3627
    if (!array[count].Decode(*this))
3628
      return FALSE;
3629
    count++;
3630
  }
3631
3632
  byteOffset = endOffset;
3633
3634
  return TRUE;
3635
}
3636
3637
3638
void PBER_Stream::ArrayEncode(const PASN_Array & array)
3639
{
3640
  HeaderEncode(array);
3641
  for (PINDEX i = 0; i < array.GetSize(); i++)
3642
    array[i].Encode(*this);
3643
}
3644
3645
3646
BOOL PPER_Stream::ArrayDecode(PASN_Array & array)
3647
{
3648
  array.RemoveAll();
3649
3650
  unsigned size;
3651
  if (array.ConstrainedLengthDecode(*this, size) < 0)
3652
    return FALSE;
3653
3654
  array.SetSize(size);
3655
3656
  for (PINDEX i = 0; i < (PINDEX)size; i++) {
3657
    if (!array[i].Decode(*this))
3658
      return FALSE;
3659
  }
3660
3661
  return TRUE;
3662
}
3663
3664
3665
void PPER_Stream::ArrayEncode(const PASN_Array & array)
3666
{
3667
  PINDEX size = array.GetSize();
3668
  array.ConstrainedLengthEncode(*this, size);
3669
  for (PINDEX i = 0; i < size; i++)
3670
    array[i].Encode(*this);
3671
}
3672
3673
3674
///////////////////////////////////////////////////////////////////////
3675
3676
PASN_Stream::PASN_Stream()
3677
{
3678
  Construct();
3679
}
3680
3681
3682
PASN_Stream::PASN_Stream(const PBYTEArray & bytes)
3683
  : PBYTEArray(bytes)
3684
{
3685
  Construct();
3686
}
3687
3688
3689
PASN_Stream::PASN_Stream(const BYTE * buf, PINDEX size)
3690
  : PBYTEArray(buf, size)
3691
{
3692
  Construct();
3693
}
3694
3695
3696
void PASN_Stream::Construct()
3697
{
3698
  byteOffset = 0;
3699
  bitOffset = 8;
3700
}
3701
3702
3703
void PASN_Stream::PrintOn(ostream & strm) const
3704
{
3705
  int indent = strm.precision() + 2;
3706
  strm << " size=" << GetSize()
3707
       << " pos=" << byteOffset << '.' << (8-bitOffset)
3708
       << " {\n";
3709
  PINDEX i = 0;
3710
  while (i < GetSize()) {
3711
    strm << setw(indent) << " " << hex << setfill('0');
3712
    PINDEX j;
3713
    for (j = 0; j < 16; j++)
3714
      if (i+j < GetSize())
3715
        strm << setw(2) << (unsigned)(BYTE)theArray[i+j] << ' ';
3716
      else
3717
        strm << "   ";
3718
    strm << "  ";
3719
    for (j = 0; j < 16; j++) {
3720
      if (i+j < GetSize()) {
3721
        if (isprint(theArray[i+j]))
3722
          strm << theArray[i+j];
3723
        else
3724
          strm << ' ';
3725
      }
3726
    }
3727
    strm << dec << setfill(' ') << '\n';
3728
    i += 16;
3729
  }
3730
  strm << setw(indent-1) << "}";
3731
}
3732
3733
3734
void PASN_Stream::SetPosition(PINDEX newPos)
3735
{
3736
  PAssert(byteOffset != P_MAX_INDEX, PLogicError);
3737
3738
  if (newPos > GetSize())
3739
    byteOffset = GetSize();
3740
  else
3741
    byteOffset = newPos;
3742
  bitOffset = 8;
3743
}
3744
3745
3746
void PASN_Stream::ResetDecoder()
3747
{
3748
  byteOffset = 0;
3749
  bitOffset = 8;
3750
}
3751
3752
3753
void PASN_Stream::BeginEncoding()
3754
{
3755
  bitOffset = 8;
3756
  byteOffset = 0;
3757
  PBYTEArray::operator=(PBYTEArray(20));
3758
}
3759
3760
3761
void PASN_Stream::CompleteEncoding()
3762
{
3763
  if (byteOffset != P_MAX_INDEX) {
3764
    if (bitOffset != 8) {
3765
      bitOffset = 8;
3766
      byteOffset++;
3767
    }
3768
    SetSize(byteOffset);
3769
    byteOffset = P_MAX_INDEX;
3770
  }
3771
}
3772
3773
3774
BYTE PASN_Stream::ByteDecode()
3775
{
3776
  if (byteOffset >= GetSize())
3777
    return 0;
3778
3779
  bitOffset = 8;
3780
  return theArray[byteOffset++];
3781
}
3782
3783
3784
void PASN_Stream::ByteEncode(unsigned value)
3785
{
3786
  PAssert(byteOffset != P_MAX_INDEX, PLogicError);
3787
3788
  if (bitOffset != 8) {
3789
    bitOffset = 8;
3790
    byteOffset++;
3791
  }
3792
  if (byteOffset >= GetSize())
3793
    SetSize(byteOffset+10);
3794
  theArray[byteOffset++] = (BYTE)value;
3795
}
3796
3797
3798
unsigned PASN_Stream::BlockDecode(BYTE * bufptr, unsigned nBytes)
3799
{
3800
  if (nBytes == 0)
3801
    return 0;
3802
3803
  ByteAlign();
3804
3805
  if (byteOffset+nBytes > (unsigned)GetSize()) {
3806
    nBytes = GetSize() - byteOffset;
3807
    if (nBytes == 0)
3808
      return 0;
3809
  }
3810
3811
  memcpy(bufptr, &theArray[byteOffset], nBytes);
3812
  byteOffset += nBytes;
3813
  return nBytes;
3814
}
3815
3816
3817
void PASN_Stream::BlockEncode(const BYTE * bufptr, PINDEX nBytes)
3818
{
3819
  PAssert(byteOffset != P_MAX_INDEX, PLogicError);
3820
3821
  if (nBytes == 0)
3822
    return;
3823
3824
  ByteAlign();
3825
3826
  if (byteOffset+nBytes >= GetSize())
3827
    SetSize(byteOffset+nBytes+10);
3828
3829
  memcpy(theArray+byteOffset, bufptr, nBytes);
3830
  byteOffset += nBytes;
3831
}
3832
3833
3834
void PASN_Stream::ByteAlign()
3835
{
3836
  PAssert(byteOffset != P_MAX_INDEX, PLogicError);
3837
3838
  if (bitOffset != 8) {
3839
    bitOffset = 8;
3840
    byteOffset++;
3841
  }
3842
}
3843
3844
3845
///////////////////////////////////////////////////////////////////////
3846
3847
PBER_Stream::PBER_Stream()
3848
{
3849
}
3850
3851
3852
PBER_Stream::PBER_Stream(const PBYTEArray & bytes)
3853
  : PASN_Stream(bytes)
3854
{
3855
}
3856
3857
3858
PBER_Stream::PBER_Stream(const BYTE * buf, PINDEX size)
3859
  : PASN_Stream(buf, size)
3860
{
3861
}
3862
3863
3864
PBER_Stream & PBER_Stream::operator=(const PBYTEArray & bytes)
3865
{
3866
  PBYTEArray::operator=(bytes);
3867
  ResetDecoder();
3868
  return *this;
3869
}
3870
3871
3872
BOOL PBER_Stream::Read(PChannel & chan)
3873
{
3874
  SetSize(0);
3875
  PINDEX offset = 0;
3876
3877
  // read the sequence header
3878
  int b;
3879
  if ((b = chan.ReadChar()) < 0)
3880
    return FALSE;
3881
3882
  SetAt(offset++, (char)b);
3883
3884
  // only support direct read of simple sequences
3885
  if ((b&0x1f) == 0x1f) {
3886
    do {
3887
      if ((b = chan.ReadChar()) < 0)
3888
        return FALSE;
3889
      SetAt(offset++, (char)b);
3890
    } while ((b & 0x80) != 0);
3891
  }
3892
3893
  // read the first byte of the ASN length
3894
  if ((b = chan.ReadChar()) < 0)
3895
    return FALSE;
3896
3897
  SetAt(offset++, (char)b);
3898
3899
  // determine how many bytes in the length
3900
  PINDEX dataLen = 0;
3901
  if ((b & 0x80) == 0)
3902
    dataLen = b;
3903
  else {
3904
    PINDEX lenLen = b&0x7f;
3905
    SetSize(lenLen+2);
3906
    while (lenLen-- > 0) {
3907
      // read the length
3908
      if ((b = chan.ReadChar()) < 0)
3909
        return FALSE;
3910
      dataLen = (dataLen << 8) | b;
3911
      SetAt(offset++, (char)b);
3912
    }
3913
  }
3914
3915
  // read the data, all of it
3916
  BYTE * bufptr = GetPointer(dataLen+offset) + offset;
3917
  while (dataLen > 0) {
3918
    if (!chan.Read(bufptr, dataLen))
3919
      return FALSE;
3920
    PINDEX readbytes = chan.GetLastReadCount();
3921
    bufptr += readbytes;
3922
    dataLen -= readbytes;
3923
  }
3924
  return TRUE;
3925
}
3926
3927
3928
BOOL PBER_Stream::Write(PChannel & chan)
3929
{
3930
  CompleteEncoding();
3931
  return chan.Write(theArray, GetSize());
3932
}
3933
3934
3935
PASN_Object * PBER_Stream::CreateObject(unsigned tag,
3936
                                        PASN_Object::TagClass tagClass,
3937
                                        BOOL primitive) const
3938
{
3939
  if (tagClass == PASN_Object::UniversalTagClass) {
3940
    switch (tag) {
3941
      case PASN_Object::UniversalBoolean :
3942
        return new PASN_Boolean();
3943
3944
      case PASN_Object::UniversalInteger :
3945
        return new PASN_Integer();
3946
3947
      case PASN_Object::UniversalBitString :
3948
        return new PASN_BitString();
3949
3950
      case PASN_Object::UniversalOctetString :
3951
        return new PASN_OctetString();
3952
3953
      case PASN_Object::UniversalNull :
3954
        return new PASN_Null();
3955
3956
      case PASN_Object::UniversalObjectId :
3957
        return new PASN_ObjectId();
3958
3959
      case PASN_Object::UniversalReal :
3960
        return new PASN_Real();
3961
3962
      case PASN_Object::UniversalEnumeration :
3963
        return new PASN_Enumeration();
3964
3965
      case PASN_Object::UniversalSequence :
3966
        return new PASN_Sequence();
3967
3968
      case PASN_Object::UniversalSet :
3969
        return new PASN_Set();
3970
3971
      case PASN_Object::UniversalNumericString :
3972
        return new PASN_NumericString();
3973
3974
      case PASN_Object::UniversalPrintableString :
3975
        return new PASN_PrintableString();
3976
3977
      case PASN_Object::UniversalIA5String :
3978
        return new PASN_IA5String();
3979
3980
      case PASN_Object::UniversalVisibleString :
3981
        return new PASN_VisibleString();
3982
3983
      case PASN_Object::UniversalGeneralString :
3984
        return new PASN_GeneralString();
3985
3986
      case PASN_Object::UniversalBMPString :
3987
        return new PASN_BMPString();
3988
    }
3989
  }
3990
3991
  if (primitive)
3992
    return new PASN_OctetString(tag, tagClass);
3993
  else
3994
    return new PASN_Sequence(tag, tagClass, 0, FALSE, 0);
3995
}
3996
3997
3998
BOOL PBER_Stream::HeaderDecode(unsigned & tagVal,
3999
                               PASN_Object::TagClass & tagClass,
4000
                               BOOL & primitive,
4001
                               unsigned & len)
4002
{
4003
  BYTE ident = ByteDecode();
4004
  tagClass = (PASN_Object::TagClass)(ident>>6);
4005
  primitive = (ident&0x20) == 0;
4006
  tagVal = ident&31;
4007
  if (tagVal == 31) {
4008
    BYTE b;
4009
    tagVal = 0;
4010
    do {
4011
      if (IsAtEnd())
4012
        return FALSE;
4013
4014
      b = ByteDecode();
4015
      tagVal = (tagVal << 7) | (b&0x7f);
4016
    } while ((b&0x80) != 0);
4017
  }
4018
4019
  if (IsAtEnd())
4020
    return FALSE;
4021
4022
  BYTE len_len = ByteDecode();
4023
  if ((len_len & 0x80) == 0) {
4024
    len = len_len;
4025
    return TRUE;
4026
  }
4027
4028
  len_len &= 0x7f;
4029
4030
  len = 0;
4031
  while (len_len-- > 0) {
4032
    if (IsAtEnd())
4033
      return FALSE;
4034
4035
    len = (len << 8) | ByteDecode();
4036
  }
4037
4038
  return TRUE;
4039
}
4040
4041
4042
BOOL PBER_Stream::HeaderDecode(PASN_Object & obj, unsigned & len)
4043
{
4044
  PINDEX pos = byteOffset;
4045
4046
  unsigned tagVal;
4047
  PASN_Object::TagClass tagClass;
4048
  BOOL primitive;
4049
  if (HeaderDecode(tagVal, tagClass, primitive, len) &&
4050
              tagVal == obj.GetTag() && tagClass == obj.GetTagClass())
4051
    return TRUE;
4052
4053
  byteOffset = pos;
4054
  return FALSE;
4055
}
4056
4057
4058
void PBER_Stream::HeaderEncode(const PASN_Object & obj)
4059
{
4060
  BYTE ident = (BYTE)(obj.GetTagClass() << 6);
4061
  if (!obj.IsPrimitive())
4062
    ident |= 0x20;
4063
  unsigned tag = obj.GetTag();
4064
  if (tag < 31)
4065
    ByteEncode(ident|tag);
4066
  else {
4067
    ByteEncode(ident|31);
4068
    unsigned count = (CountBits(tag)+6)/7;
4069
    while (count-- > 1)
4070
      ByteEncode((tag >> (count*7))&0x7f);
4071
    ByteEncode(tag&0x7f);
4072
  }
4073
4074
  PINDEX len = obj.GetDataLength();
4075
  if (len < 128)
4076
    ByteEncode(len);
4077
  else {
4078
    PINDEX count = (CountBits(len+1)+7)/8;
4079
    ByteEncode(count|0x80);
4080
    while (count-- > 0)
4081
      ByteEncode(len >> (count*8));
4082
  }
4083
}
4084
4085
4086
4087
///////////////////////////////////////////////////////////////////////
4088
4089
PPER_Stream::PPER_Stream(BOOL alignment)
4090
{
4091
  aligned = alignment;
4092
}
4093
4094
4095
PPER_Stream::PPER_Stream(const PBYTEArray & bytes, BOOL alignment)
4096
  : PASN_Stream(bytes)
4097
{
4098
  aligned = alignment;
4099
}
4100
4101
4102
PPER_Stream::PPER_Stream(const BYTE * buf, PINDEX size, BOOL alignment)
4103
  : PASN_Stream(buf, size)
4104
{
4105
  aligned = alignment;
4106
}
4107
4108
4109
PPER_Stream & PPER_Stream::operator=(const PBYTEArray & bytes)
4110
{
4111
  PBYTEArray::operator=(bytes);
4112
  ResetDecoder();
4113
  aligned = TRUE;
4114
  return *this;
4115
}
4116
4117
4118
unsigned PPER_Stream::GetBitsLeft() const
4119
{
4120
  return (GetSize() - byteOffset)*8 - (8 - bitOffset);
4121
}
4122
4123
4124
BOOL PPER_Stream::Read(PChannel & chan)
4125
{
4126
  ResetDecoder();
4127
  SetSize(0);
4128
4129
  // Get RFC1006 TPKT length
4130
  BYTE tpkt[4];
4131
  if (!chan.ReadBlock(tpkt, sizeof(tpkt)))
4132
    return FALSE;
4133
4134
  if (tpkt[0] != 3) // Only support version 3
4135
    return TRUE;
4136
4137
  PINDEX data_len = ((tpkt[2] << 8)|tpkt[3]) - 4;
4138
4139
  return chan.ReadBlock(GetPointer(data_len), data_len);
4140
}
4141
4142
4143
BOOL PPER_Stream::Write(PChannel & chan)
4144
{
4145
  CompleteEncoding();
4146
4147
  PINDEX size = GetSize();
4148
4149
  // Put RFC1006 TPKT length
4150
  BYTE tpkt[4];
4151
  tpkt[0] = 3;  // Version 3
4152
  tpkt[1] = 0;
4153
4154
  PINDEX len = size + sizeof(tpkt);
4155
  tpkt[2] = (BYTE)(len >> 8);
4156
  tpkt[3] = (BYTE)len;
4157
4158
  return chan.Write(tpkt, sizeof(tpkt)) && chan.Write(theArray, size);
4159
}
4160
4161
4162
BOOL PPER_Stream::SingleBitDecode()
4163
{
4164
  if ((GetSize() - byteOffset)*8 - (8 - bitOffset) == 0)
4165
    return FALSE;
4166
4167
  bitOffset--;
4168
  BOOL value = (theArray[byteOffset] & (1 << bitOffset)) != 0;
4169
4170
  if (bitOffset == 0) {
4171
    bitOffset = 8;
4172
    byteOffset++;
4173
  }
4174
4175
  return value;
4176
}
4177
4178
4179
void PPER_Stream::SingleBitEncode(BOOL value)
4180
{
4181
  PAssert(byteOffset != P_MAX_INDEX, PLogicError);
4182
4183
  if (byteOffset >= GetSize())
4184
    SetSize(byteOffset+10);
4185
4186
  bitOffset--;
4187
4188
  if (value)
4189
    theArray[byteOffset] |= 1 << bitOffset;
4190
4191
  if (bitOffset == 0)
4192
    ByteAlign();
4193
}
4194
4195
4196
BOOL PPER_Stream::MultiBitDecode(unsigned nBits, unsigned & value)
4197
{
4198
  if (nBits > sizeof(value)*8)
4199
    return FALSE;
4200
4201
  unsigned bitsLeft = (GetSize() - byteOffset)*8 - (8 - bitOffset);
4202
  if (nBits > bitsLeft)
4203
    return FALSE;
4204
4205
  if (nBits == 0) {
4206
    value = 0;
4207
    return TRUE;
4208
  }
4209
4210
  if (nBits < bitOffset) {
4211
    bitOffset -= nBits;
4212
    value = (theArray[byteOffset] >> bitOffset) & ((1 << nBits) - 1);
4213
    return TRUE;
4214
  }
4215
4216
  value = theArray[byteOffset] & ((1 << bitOffset) - 1);
4217
  nBits -= bitOffset;
4218
  bitOffset = 8;
4219
  byteOffset++;
4220
4221
  while (nBits >= 8) {
4222
    value = (value << 8) | (BYTE)theArray[byteOffset];
4223
    byteOffset++;
4224
    nBits -= 8;
4225
  }
4226
4227
  if (nBits > 0) {
4228
    bitOffset = 8 - nBits;
4229
    value = (value << nBits) | ((BYTE)theArray[byteOffset] >> bitOffset);
4230
  }
4231
4232
  return TRUE;
4233
}
4234
4235
4236
void PPER_Stream::MultiBitEncode(unsigned value, unsigned nBits)
4237
{
4238
  PAssert(byteOffset != P_MAX_INDEX, PLogicError);
4239
4240
  if (nBits == 0)
4241
    return;
4242
4243
  if (byteOffset+nBits/8+1 >= (unsigned)GetSize())
4244
    SetSize(byteOffset+10);
4245
4246
  // Make sure value is in bounds of bit available.
4247
  if (nBits < sizeof(int)*8)
4248
    value &= ((1 << nBits) - 1);
4249
4250
  if (nBits < bitOffset) {
4251
    bitOffset -= nBits;
4252
    theArray[byteOffset] |= value << bitOffset;
4253
    return;
4254
  }
4255
4256
  nBits -= bitOffset;
4257
  theArray[byteOffset] |= (BYTE)(value >> nBits);
4258
  bitOffset = 8;
4259
  byteOffset++;
4260
4261
  while (nBits >= 8) {
4262
    nBits -= 8;
4263
    theArray[byteOffset] = (BYTE)(value >> nBits);
4264
    byteOffset++;
4265
  }
4266
4267
  if (nBits > 0) {
4268
    bitOffset = 8 - nBits;
4269
    theArray[byteOffset] |= (BYTE)((value & ((1 << nBits)-1)) << bitOffset);
4270
  }
4271
}
4272
4273
4274
BOOL PPER_Stream::SmallUnsignedDecode(unsigned & value)
4275
{
4276
  // X.691 Section 10.6
4277
4278
  if (!SingleBitDecode())
4279
    return MultiBitDecode(6, value);      // 10.6.1
4280
4281
  unsigned len;
4282
  if (LengthDecode(0, INT_MAX, len) != 0)  // 10.6.2
4283
    return FALSE;
4284
4285
  ByteAlign();
4286
  return MultiBitDecode(len*8, value);
4287
}
4288
4289
4290
void PPER_Stream::SmallUnsignedEncode(unsigned value)
4291
{
4292
  if (value < 64) {
4293
    MultiBitEncode(value, 7);
4294
    return;
4295
  }
4296
4297
  SingleBitEncode(1);  // 10.6.2
4298
4299
  PINDEX len = 4;
4300
  if (value < 256)
4301
    len = 1;
4302
  else if (value < 65536)
4303
    len = 2;
4304
  else if (value < 0x1000000)
4305
    len = 3;
4306
  LengthEncode(len, 0, INT_MAX);  // 10.9
4307
  ByteAlign();
4308
  MultiBitEncode(value, len*8);
4309
}
4310
4311
4312
int PPER_Stream::UnsignedDecode(unsigned lower, unsigned upper, unsigned & value)
4313
{
4314
  // X.691 section 10.5
4315
4316
  if (lower == upper) { // 10.5.4
4317
    value = lower;
4318
    return 0;
4319
  }
4320
4321
  if (IsAtEnd())
4322
    return -1;
4323
4324
  unsigned range = (upper - lower) + 1;
4325
  unsigned nBits = CountBits(range);
4326
4327
  if (aligned && (range == 0 || range > 255)) { // not 10.5.6 and not 10.5.7.1
4328
    if (nBits > 16) {                           // not 10.5.7.4
4329
      LengthDecode(1, (nBits+7)/8, nBits);      // 12.2.6
4330
      nBits *= 8;
4331
    }
4332
    else if (nBits > 8)    // not 10.5.7.2
4333
      nBits = 16;          // 10.5.7.3
4334
    ByteAlign();           // 10.7.5.2 - 10.7.5.4
4335
  }
4336
4337
  if (!MultiBitDecode(nBits, value))
4338
    return -1;
4339
4340
  value += lower;
4341
  return 0;
4342
}
4343
4344
4345
void PPER_Stream::UnsignedEncode(int value, unsigned lower, unsigned upper)
4346
{
4347
  // X.691 section 10.5
4348
4349
  if (lower == upper) // 10.5.4
4350
    return;
4351
4352
  unsigned range = (upper - lower) + 1;
4353
  PINDEX nBits = CountBits(range);
4354
4355
  if (aligned && (range == 0 || range > 255)) { // not 10.5.6 and not 10.5.7.1
4356
    if (nBits > 16) {                           // not 10.5.7.4
4357
      int numBytes = value == 0 ? 1 : (((CountBits(value - lower + 1))+7)/8);
4358
      LengthEncode(numBytes, 1, (nBits+7)/8);    // 12.2.6
4359
      nBits = numBytes*8;
4360
    }
4361
    else if (nBits > 8)      // not 10.5.7.2
4362
      nBits = 16;            // 10.5.7.3
4363
    ByteAlign();             // 10.7.5.2 - 10.7.5.4
4364
  }
4365
4366
  MultiBitEncode(value - lower, nBits);
4367
}
4368
4369
4370
int PPER_Stream::LengthDecode(unsigned lower, unsigned upper, unsigned & len)
4371
{
4372
  // X.691 section 10.9
4373
4374
  if (upper != INT_MAX && !aligned) {
4375
    if (upper - lower > 0xffff)
4376
      return -1; // 10.9.4.2 unsupported
4377
    unsigned base;
4378
    if (!MultiBitDecode(CountBits(upper - lower + 1), base))
4379
      return -1;
4380
    return lower + base;   // 10.9.4.1
4381
  }
4382
4383
  if (upper < 65536)  // 10.9.3.3
4384
    return UnsignedDecode(lower, upper, len);
4385
4386
  // 10.9.3.5
4387
  ByteAlign();
4388
  if (IsAtEnd())
4389
    return -1;
4390
4391
  if (SingleBitDecode() == 0)
4392
    return MultiBitDecode(7, len) ? 0 : -1;   // 10.9.3.6
4393
4394
  if (SingleBitDecode() == 0)
4395
    return MultiBitDecode(14, len) ? 0 : -1;    // 10.9.3.7
4396
4397
  return -1;  // 10.9.3.8 unsupported
4398
}
4399
4400
4401
void PPER_Stream::LengthEncode(unsigned len, unsigned lower, unsigned upper)
4402
{
4403
  // X.691 section 10.9
4404
4405
  if (upper != INT_MAX && !aligned) {
4406
    PAssert(upper - lower < 0x10000, PUnimplementedFunction);  // 10.9.4.2 unsupperted
4407
    MultiBitEncode(len - lower, CountBits(upper - lower + 1));   // 10.9.4.1
4408
    return;
4409
  }
4410
4411
  if (upper < 65536) { // 10.9.3.3
4412
    UnsignedEncode(len, lower, upper);
4413
    return;
4414
  }
4415
4416
  ByteAlign();
4417
4418
  if (len < 128) {
4419
    MultiBitEncode(len, 8);   // 10.9.3.6
4420
    return;
4421
  }
4422
4423
  SingleBitEncode(TRUE);
4424
4425
  if (len < 0x2000) {
4426
    MultiBitEncode(len, 15);    // 10.9.3.7
4427
    return;
4428
  }
4429
4430
  SingleBitEncode(TRUE);
4431
  PAssert(len < 0x2000, PUnimplementedFunction);  // 10.9.3.8 unsupported
4432
}
4433
4434
4435
void PPER_Stream::AnyTypeEncode(const PASN_Object * value)
4436
{
4437
  PPER_Stream substream;
4438
4439
  if (value != NULL)
4440
    value->Encode(substream);
4441
4442
  if (substream.GetPosition() == 0)   // Make sure extension has at least one
4443
    substream.SingleBitEncode(FALSE); // byte in its ANY type encoding.
4444
4445
  substream.CompleteEncoding();
4446
4447
  PINDEX nBytes = substream.GetSize();
4448
  LengthEncode(nBytes, 0, INT_MAX);
4449
  BlockEncode(substream.GetPointer(), nBytes);
4450
}
4451
4452
4453
// PERASN.CXX
4454
++ pwlib-1.2.5/src/ptlib/common/contain.cxx
Lines 2091-2097 Link Here
2091
}
2091
}
2092
2092
2093
streampos PStringStream::Buffer::seekoff(streamoff off,
2093
streampos PStringStream::Buffer::seekoff(streamoff off,
2094
#ifdef __MWERKS__
2094
#if defined(__MWERKS__) || defined(GCC3)
2095
                                 ios::seekdir dir, ios::openmode mode)
2095
                                 ios::seekdir dir, ios::openmode mode)
2096
#else
2096
#else
2097
                                 ios::seek_dir dir, int mode)
2097
                                 ios::seek_dir dir, int mode)
Lines 2153-2172 Link Here
2153
2153
2154
2154
2155
PStringStream::PStringStream()
2155
PStringStream::PStringStream()
2156
    : iostream(cout.rdbuf())
2156
{
2157
{
2157
  init(new PStringStream::Buffer(this));
2158
  init(new PStringStream::Buffer(this));
2158
}
2159
}
2159
2160
2160
2161
2161
PStringStream::PStringStream(const PString & str)
2162
PStringStream::PStringStream(const PString & str)
2162
  : PString(str)
2163
    : PString(str), iostream(cout.rdbuf())
2163
{
2164
{
2164
  init(new PStringStream::Buffer(this));
2165
  init(new PStringStream::Buffer(this));
2165
}
2166
}
2166
2167
2167
2168
2168
PStringStream::PStringStream(const char * cstr)
2169
PStringStream::PStringStream(const char * cstr)
2169
  : PString(cstr)
2170
  : PString(cstr), iostream(cout.rdbuf())
2170
{
2171
{
2171
  init(new PStringStream::Buffer(this));
2172
  init(new PStringStream::Buffer(this));
2172
}
2173
}
2173
-- pwlib-1.2.5.orig/src/ptlib/common/getdate.y
2174
++ pwlib-1.2.5/src/ptlib/common/getdate.y
Lines 22-27 Link Here
22
#include <string.h>
22
#include <string.h>
23
#include <ctype.h>
23
#include <ctype.h>
24
#include <stdlib.h>
24
#include <stdlib.h>
25
#include <stdio.h>
25
26
26
27
27
#ifdef _MSC_VER
28
#ifdef _MSC_VER
28
-- pwlib-1.2.5.orig/src/ptlib/common/osutils.cxx
29
++ pwlib-1.2.5/src/ptlib/common/osutils.cxx
Lines 809-820 Link Here
809
     stderr is used the unitbuf flag causes the out_waiting() not to work so we 
809
     stderr is used the unitbuf flag causes the out_waiting() not to work so we 
810
     must suffer with blank lines in that case.
810
     must suffer with blank lines in that case.
811
   */
811
   */
812
  if ((s.flags()&ios::unitbuf) != 0 || s.rdbuf()->out_waiting() > 0) {
812
//    if ((s.flags()&ios::unitbuf) != 0 || s.rdbuf()->out_waiting() > 0) {
813
    if ((PTraceOptions&SystemLogStream) != 0)
813
    if ((PTraceOptions&SystemLogStream) != 0)
814
      s.flush();
814
      s.flush();
815
    else
815
    else
816
      s << endl;
816
      s << endl;
817
  }
817
//  }
818
818
819
  PTraceMutex->Signal();
819
  PTraceMutex->Signal();
820
820
821
-- pwlib-1.2.5.orig/src/ptlib/common/pchannel.cxx
821
++ pwlib-1.2.5/src/ptlib/common/pchannel.cxx
Lines 163-169 Link Here
163
163
164
164
165
streampos PChannelStreamBuffer::seekoff(streamoff off,
165
streampos PChannelStreamBuffer::seekoff(streamoff off,
166
#ifdef __MWERKS__
166
#if defined(__MWERKS__) || defined(GCC3)
167
                                        ios::seekdir dir, ios::openmode)
167
                                        ios::seekdir dir, ios::openmode)
168
#else
168
#else
169
                                        ios::seek_dir dir, int)
169
                                        ios::seek_dir dir, int)
Lines 178-184 Link Here
178
178
179
179
180
PChannel::PChannel()
180
PChannel::PChannel()
181
  : readTimeout(PMaxTimeInterval), writeTimeout(PMaxTimeInterval)
181
  : iostream(cout.rdbuf()),
182
    readTimeout(PMaxTimeInterval), writeTimeout(PMaxTimeInterval)
182
{
183
{
183
  os_handle = -1;
184
  os_handle = -1;
184
  memset(lastErrorCode, 0, sizeof(lastErrorCode));
185
  memset(lastErrorCode, 0, sizeof(lastErrorCode));
185
-- pwlib-1.2.5.orig/src/ptlib/common/sockets.cxx
186
++ pwlib-1.2.5/src/ptlib/common/sockets.cxx
Lines 778-783 Link Here
778
778
779
PSocket::PSocket()
779
PSocket::PSocket()
780
{
780
{
781
  SetReadTimeout(10000);
782
  SetWriteTimeout(10000);
781
  port = 0;
783
  port = 0;
782
}
784
}
783
785
784
-- pwlib-1.2.5.orig/src/ptlib/unix/channel.cxx
786
++ pwlib-1.2.5/src/ptlib/unix/channel.cxx
Lines 152-162 Link Here
152
#endif
152
#endif
153
153
154
154
155
/*
155
ios::ios(const ios &)
156
ios::ios(const ios &)
156
{
157
{
157
  PAssertAlways("Cannot copy ios");
158
  PAssertAlways("Cannot copy ios");
158
}
159
}
159
160
*/
160
161
161
void PChannel::Construct()
162
void PChannel::Construct()
162
{
163
{
163
-- pwlib-1.2.5.orig/src/ptlib/unix/oss.cxx
164
++ pwlib-1.2.5/src/ptlib/unix/oss.cxx
Lines 383-390 Link Here
383
      if (devdir.GetInfo(info) &&info.type == PFileInfo::CharDevice) {
383
      if (devdir.GetInfo(info) &&info.type == PFileInfo::CharDevice) {
384
        struct stat s;
384
        struct stat s;
385
        if (lstat(devname, &s) == 0) {
385
        if (lstat(devname, &s) == 0) {
386
          // OSS compatible audio major device numbers (OSS, ALSA, SAM9407, etc)
386
          // OSS compatible audio major device numbers (OSS, SAM9407, etc)
387
          static const unsigned deviceNumbers[] = { 14, 116, 145 };
387
          static const unsigned deviceNumbers[] = { 14, 145 };
388
          for (PINDEX i = 0; i < PARRAYSIZE(deviceNumbers); i++) {
388
          for (PINDEX i = 0; i < PARRAYSIZE(deviceNumbers); i++) {
389
            if ((s.st_rdev >> 8) == deviceNumbers[i]) {
389
            if ((s.st_rdev >> 8) == deviceNumbers[i]) {
390
              PINDEX cardnum = (s.st_rdev >> 4) & 15;
390
              PINDEX cardnum = (s.st_rdev >> 4) & 15;
391
-- pwlib-1.2.5.orig/src/ptlib/unix/osutil.cxx
391
++ pwlib-1.2.5/src/ptlib/unix/osutil.cxx
Lines 174-180 Link Here
174
174
175
#define P_HAS_READDIR_R
175
#define P_HAS_READDIR_R
176
176
177
#if (__GNUC_MINOR__ < 7)
177
#if (__GNUC_MINOR__ < 7 && __GNUC__ < 3)
178
#include <localeinfo.h>
178
#include <localeinfo.h>
179
#else
179
#else
180
#define P_USE_LANGINFO
180
#define P_USE_LANGINFO
181
-- pwlib-1.2.5.orig/src/ptlib/unix/video4linux.cxx
181
++ pwlib-1.2.5/src/ptlib/unix/video4linux.cxx
Lines 100-105 Link Here
100
#include <ptlib/vconvert.h>
100
#include <ptlib/vconvert.h>
101
101
102
#include <sys/mman.h>
102
#include <sys/mman.h>
103
#include <sys/time.h>
103
104
104
105
105
///////////////////////////////////////////////////////////////////////////////
106
///////////////////////////////////////////////////////////////////////////////
Lines 269-274 Link Here
269
  if (GetHue() < 0)
270
  if (GetHue() < 0)
270
    goto errorOpenVideoInputDevice;
271
    goto errorOpenVideoInputDevice;
271
272
273
  // Init audio
274
275
  struct video_audio videoAudio;
276
277
  if (::ioctl(videoFd, VIDIOCGAUDIO, &videoAudio) >= 0 &&
278
      videoAudio.flags & VIDEO_AUDIO_MUTABLE) {
279
        videoAudio.flags&=~VIDEO_AUDIO_MUTE;
280
        videoAudio.mode=VIDEO_SOUND_MONO;
281
        ::ioctl(videoFd, VIDIOCSAUDIO, &videoAudio);
282
  }
283
272
  return TRUE;
284
  return TRUE;
273
285
274
 errorOpenVideoInputDevice:
286
 errorOpenVideoInputDevice:
Lines 289-294 Link Here
289
  if (!IsOpen())
301
  if (!IsOpen())
290
    return FALSE;
302
    return FALSE;
291
303
304
  // Mute audio
305
306
  struct video_audio videoAudio;
307
308
  if ((::ioctl(videoFd, VIDIOCGAUDIO, &videoAudio) >= 0) &&
309
      (videoAudio.flags & VIDEO_AUDIO_MUTABLE)) {
310
        videoAudio.flags|=VIDEO_AUDIO_MUTE;
311
        ::ioctl(videoFd, VIDIOCSAUDIO, &videoAudio);
312
  }
313
292
  ClearMapping();
314
  ClearMapping();
293
  ::close(videoFd);
315
  ::close(videoFd);
294
  videoFd = -1;
316
  videoFd = -1;
Lines 559-564 Link Here
559
581
560
BOOL PVideoInputDevice::GetFrameData(BYTE * buffer, PINDEX * bytesReturned)
582
BOOL PVideoInputDevice::GetFrameData(BYTE * buffer, PINDEX * bytesReturned)
561
{
583
{
584
  if (frameRate > 0) {
585
    int frameInterval = 1000000 / frameRate; // frameRate < 1000000 fps
586
    timeval now;
587
    struct timezone tz = {0, 0}; // Not used
588
    timespec ntime = {0, 0};
589
    gettimeofday (&now, &tz);
590
    int sleepytime = frameInterval - (now.tv_usec % frameInterval);
591
    if (sleepytime == 1000000) // frameRate == 1 and bad luck
592
      ntime.tv_sec = 1;
593
    else
594
      ntime.tv_nsec = 1000 * sleepytime;
595
    nanosleep (&ntime, 0);
596
  }
597
562
  if (canMap < 0) {
598
  if (canMap < 0) {
563
599
564
    if (::ioctl(videoFd, VIDIOCGMBUF, &frame) < 0)
600
    if (::ioctl(videoFd, VIDIOCGMBUF, &frame) < 0)
565
-- pwlib-1.2.5.orig/make/gcc_filter.awk
601
++ pwlib-1.2.5/make/gcc_filter.awk
Lines 1-4 Link Here
1
#!/usr/bin/gawk -f
1
#!/usr/bin/awk -f
2
2
3
/^In file included from/ {
3
/^In file included from/ {
4
  l1 = $0;
4
  l1 = $0;
5
-- pwlib-1.2.5.orig/make/lib.mak
5
++ pwlib-1.2.5/make/lib.mak
Lines 79-85 Link Here
79
EXTLIBS = $(SYSLIBS) -lstdc++.r4
79
EXTLIBS = $(SYSLIBS) -lstdc++.r4
80
else
80
else
81
LDSOOPTS = -shared
81
LDSOOPTS = -shared
82
EXTLIBS =
82
endif
83
84
ifdef P_PTHREADS
85
EXTLIBS += -lpthread
86
endif
87
88
ifneq (,$(wildcard /usr/include/openssl))
89
EXTLIBS += -lssl
83
endif
90
endif
84
91
85
$(LIBDIR)/$(LIB_BASENAME): $(LIBDIR)/$(LIBNAME_PAT)
92
$(LIBDIR)/$(LIB_BASENAME): $(LIBDIR)/$(LIBNAME_PAT)
Lines 93-101 Link Here
93
100
94
install: $(LIBDIR)/$(LIBNAME_PAT)
101
install: $(LIBDIR)/$(LIBNAME_PAT)
95
	$(INSTALL) $(LIBDIR)/$(LIBNAME_PAT) $(INSTALLLIB_DIR)/$(LIBNAME_PAT)
102
	$(INSTALL) $(LIBDIR)/$(LIBNAME_PAT) $(INSTALLLIB_DIR)/$(LIBNAME_PAT)
96
	ln -s $(INSTALLLIB_DIR)/$(LIBNAME_PAT) $(INSTALLLIB_DIR)/$(LIB_BASENAME)
103
	ln -s $(LIBNAME_PAT) $(INSTALLLIB_DIR)/$(LIB_BASENAME)
97
	ln -s $(INSTALLLIB_DIR)/$(LIBNAME_PAT) $(INSTALLLIB_DIR)/$(LIBNAME_MAJ)
104
	ln -s $(LIBNAME_PAT) $(INSTALLLIB_DIR)/$(LIBNAME_MAJ)
98
	ln -s $(INSTALLLIB_DIR)/$(LIBNAME_PAT) $(INSTALLLIB_DIR)/$(LIBNAME_MIN)
105
	ln -s $(LIBNAME_PAT) $(INSTALLLIB_DIR)/$(LIBNAME_MIN)
99
106
100
else
107
else
101
108
102
-- pwlib-1.2.5.orig/make/unix.mak
109
++ pwlib-1.2.5/make/unix.mak
Lines 481-486 Link Here
481
endif
481
endif
482
endif
482
endif
483
483
484
# We want to be GCC 3.0 compatible
485
STDCCFLAGS	+= -DGCC3 -D__USE_STL__
486
484
487
485
# i486 Linux for x86, using gcc 2.7.2
488
# i486 Linux for x86, using gcc 2.7.2
486
STDCCFLAGS	+= -DP_LINUX
489
STDCCFLAGS	+= -DP_LINUX
Lines 999-1005 Link Here
999
PW_LIBDIR	= $(PWLIBDIR)/lib
1002
PW_LIBDIR	= $(PWLIBDIR)/lib
1000
1003
1001
# set name of the PT library
1004
# set name of the PT library
1002
PTLIB_BASE	= pt_$(PLATFORM_TYPE)_$(OBJ_SUFFIX)
1005
ifeq ($(findstring $(OBJ_SUFFIX),d),)
1006
ifeq ($(LIB_SUFFIX),a)
1007
PTLIB_BASE	= pt
1008
else
1009
PTLIB_BASE	= pt$(LIBPTCOMPAT)
1010
endif
1011
LIB_TYPE	=
1012
else
1013
PTLIB_BASE	= pt_$(OBJ_SUFFIX)
1014
endif
1003
PTLIB_FILE	= lib$(PTLIB_BASE)$(LIB_TYPE).$(LIB_SUFFIX)
1015
PTLIB_FILE	= lib$(PTLIB_BASE)$(LIB_TYPE).$(LIB_SUFFIX)
1004
PT_OBJBASE	= obj_$(PLATFORM_TYPE)_$(OBJDIR_SUFFIX)
1016
PT_OBJBASE	= obj_$(PLATFORM_TYPE)_$(OBJDIR_SUFFIX)
1005
PT_OBJDIR	= $(PW_LIBDIR)/$(PT_OBJBASE)
1017
PT_OBJDIR	= $(PW_LIBDIR)/$(PT_OBJBASE)
1006
-- pwlib-1.2.5.orig/debian/asnparser.dirs
1018
++ pwlib-1.2.5/debian/asnparser.dirs
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/control
1
usr/bin
2
++ pwlib-1.2.5/debian/control
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/changelog
1
Source: pwlib
2
Section: non-US
3
Priority: optional
4
Maintainer: Santiago Garcia Mantinan <manty@debian.org>
5
Build-Depends: debhelper (>=3.0.0), bison, flex, libssl-dev
6
Standards-Version: 3.2.1
7
8
Package: libpt-1.2.0
9
Section: non-US
10
Architecture: any
11
Depends: ${shlibs:Depends}
12
Description: Portable Windows Library
13
 PWLib is a moderately large class library that has its genesis many years
14
 ago as a method to product applications to run on both Microsoft Windows
15
 and Unix X-Window systems.
16
 .
17
 For more information on PWLib visit the development homepage
18
 http://www.openh323.org/
19
20
Package: asnparser
21
Section: non-US
22
Architecture: any
23
Depends: ${shlibs:Depends}
24
Description: ASN.1 to C/C++ converter
25
 This console application helps to convert your ASN.1
26
 description files to C/C++ applications.
27
 .
28
 For more information on asnparser visit the development homepage
29
 http://www.openh323.org/
30
31
Package: libpt-dev
32
Section: non-US
33
Architecture: any
34
Depends: libpt-1.2.0 (= ${Source-Version}), libc6-dev, libssl-dev, asnparser
35
Description: Portable Windows Library development files
36
 PWLib is a moderately large class library that has its genesis many years
37
 ago as a method to product applications to run on both Microsoft Windows
38
 and Unix X-Window systems.
39
 .
40
 For more information on PWLib visit the development homepage
41
 http://www.openh323.org/
42
43
Package: libpt-dbg
44
Section: non-US
45
Priority: extra
46
Architecture: any
47
Depends: libpt-dev (= ${Source-Version})
48
Description: Portable Windows Library development debug files
49
 PWLib is a moderately large class library that has its genesis many years
50
 ago as a method to product applications to run on both Microsoft Windows
51
 and Unix X-Window systems.
52
 .
53
 For more information on PWLib visit the development homepage
54
 http://www.openh323.org/
55
++ pwlib-1.2.5/debian/changelog
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/copyright
1
pwlib (1.2.5-5woody1) stable-security; urgency=high
2
3
  * Non-maintainer upload by the Security Team
4
  * Fix mutiple vulnerabilities in ASN.1 parser (CAN-2004-0097)
5
    [src/ptclib/asner.cxx]
6
7
 -- Matt Zimmerman <mdz@debian.org>  Fri, 20 Feb 2004 09:40:13 -0800
8
9
pwlib (1.2.5-5) unstable; urgency=low
10
11
  * Fix the problem on getdate.y with new bison not finding EOF,
12
    now it compiles again. Thanks to migras and the others for their
13
    help and support, today was a really hard day for me :-(
14
15
 -- Santiago Garcia Mantinan <manty@debian.org>  Tue, 12 Feb 2002 20:37:21 +0100
16
17
pwlib (1.2.5-4) unstable; urgency=high
18
19
  * Patch to remove ALSA devices from the list of OSS compatibles.
20
    Fixes a bug on some ALSA systems, they need OSS compatibility
21
    modules to be OSS compatible, that way they will work with pwlib.
22
23
 -- Santiago Garcia Mantinan <manty@debian.org>  Tue,  8 Jan 2002 21:51:33 +0100
24
25
pwlib (1.2.5-3) unstable; urgency=high
26
27
  * Patch for Framerate limit to work, thanks to Miguel Rodriguez.
28
  * Lowered timeouts for sockets to 10 seconds, also thanks to Miguel.
29
  * Compile with -O0 for alpha, sugested by mhp, thanks.
30
31
 -- Santiago Garcia Mantinan <manty@debian.org>  Wed, 28 Nov 2001 21:00:38 +0100
32
33
pwlib (1.2.5-2) unstable; urgency=low
34
35
  * Patched to enable audio output on tv cards.
36
37
 -- Santiago Garcia Mantinan <manty@debian.org>  Sun, 25 Nov 2001 16:44:28 +0100
38
39
pwlib (1.2.5-1) unstable; urgency=low
40
41
  * New upstream version.
42
  * Heavily rewritten, we now allow several versions of the libs to
43
    be installed and I'll try to guess compatibility info and try to
44
    state that in the version numbering and shlibs of the package.
45
  * Reworked the -dbg package, it now has a shared version of the
46
    debug libs instead of two static identic ones. Fixed some bugs
47
    that could break compiling with debug activated.
48
49
 -- Santiago Garcia Mantinan <manty@debian.org>  Wed, 21 Nov 2001 21:39:18 +0100
50
51
pwlib (1.1.36-4) unstable; urgency=high
52
53
  * Upgraded oss.cxx to fix loopback.
54
55
 -- Santiago Garcia Mantinan <manty@debian.org>  Tue,  4 Sep 2001 17:35:28 +0200
56
57
pwlib (1.1.36-3) unstable; urgency=low
58
59
  * Add -dbg package with debug version of the libs. Closes #108168.
60
  * Removed README.Debian explaining how to build the debug version.
61
  * Added more audio devices for the GnomeMeeting new features ;-)
62
  * Upgraded vconvert.cxx and video4linux.cxx to cvs to fix video
63
    problems on some webcams. This will require some modifications
64
    on programs using video.
65
  * Upgraded shlib depends.
66
67
 -- Santiago Garcia Mantinan <manty@debian.org>  Tue, 28 Aug 2001 18:21:53 +0200
68
69
pwlib (1.1.36-2) unstable; urgency=low
70
71
  * Use DEB_BUILD_OPTIONS for getting the debug version compiled.
72
  * Create versioned shlibs.
73
74
 -- Santiago Garcia Mantinan <manty@debian.org>  Tue, 21 Aug 2001 22:16:44 +0200
75
76
pwlib (1.1.36-1) unstable; urgency=low
77
78
  * New upstream version.
79
  * Moved it to non-US. Closes: #108645.
80
  * Provide a way to build debug version, explained on README.Debian.
81
    Closes: #108168.
82
83
 -- Santiago Garcia Mantinan <manty@debian.org>  Mon, 13 Aug 2001 21:27:56 +0200
84
85
pwlib (1.1.34-2) unstable; urgency=low
86
87
  * Changed the way on wich the source code is compiled. This results
88
    on asnparser being dynamically linked and thus much smaller now.
89
  * Compiled asnparser without -fPIC, this was what was breaking hppa.
90
91
 -- Santiago Garcia Mantinan <manty@debian.org>  Tue,  7 Aug 2001 15:57:28 +0200
92
93
pwlib (1.1.34-1) unstable; urgency=low
94
95
  * Patched to compile on gcc 3.0 (thanks to Artis Kugevics). Now it
96
    builds on hppa. Closes: #104666.
97
  * Added libssl-dev build dependency.
98
  * Added a small man page for ansparser.
99
  * Added upstream doc to libpt1 package.
100
  * New upstream version. Closes: #96523, #105408.
101
  * New maintainer.
102
103
 -- Santiago Garcia Mantinan <manty@debian.org>  Mon,  6 Aug 2001 11:27:08 +0200
104
105
pwlib (1.1pl19-1.2) unstable; urgency=low
106
107
  * NMU with permission of Raphael Bossek.
108
  * Added the missing build dependency on flex. (closes: #94962)
109
110
 -- Adrian Bunk <bunk@fs.tum.de>  Tue, 15 May 2001 01:25:01 +0200
111
112
pwlib (1.1pl19-1.1) unstable; urgency=low
113
114
  * NMU
115
  * Added build dependencies. (closes: #89173, #92381)
116
117
 -- Adrian Bunk <bunk@fs.tum.de>  Sat, 14 Apr 2001 23:10:26 +0200
118
119
pwlib (1.1pl19-1) unstable; urgency=low
120
121
  * New upstream version. (closes: #81509)
122
  * Overtake maintainership from Thomas.
123
124
 -- Raphael Bossek <bossekr@debian.org>  Sun,  4 Feb 2001 18:43:53 +0100
125
126
pwlib (1.1pl18-1) unstable; urgency=low
127
128
  * Initial Release.
129
130
 -- Thomas Bushnell, BSG <tb@debian.org>  Mon, 13 Nov 2000 23:04:02 -0800
131
132
Local variables:
133
mode: debian-changelog
134
End:
135
++ pwlib-1.2.5/debian/copyright
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/rules
1
This is the Debian GNU/Linux packaged version of PWLib.
2
3
The author of this software is Equivalence Pty. Ltd.
4
5
Original packaging for Debian by
6
	Raphael Bossek <bossekr@debian.org> 
7
Heavily modified and now maintained by
8
	Santiago Garcia Mantinan <manty@debian.org>
9
10
The sources where downloaded from:
11
12
  http://www.openh323.org/bin/
13
14
Copyright:
15
16
This software is released under the terms of the MPL (Mozilla Public license).
17
18
                           MOZILLA PUBLIC LICENSE
19
                                Version 1.0
20
                               ______________
21
   
22
   1. Definitions.
23
   1.1. ``Contributor'' means each entity that creates or contributes to
24
       the creation of Modifications.
25
       1.2. ``Contributor Version'' means the combination of the Original
26
       Code, prior Modifications used by a Contributor, and the
27
       Modifications made by that particular Contributor.
28
       1.3. ``Covered Code'' means the Original Code or Modifications or
29
       the combination of the Original Code and Modifications, in each
30
       case including portions thereof.
31
       1.4. ``Electronic Distribution Mechanism'' means a mechanism
32
       generally accepted in the software development community for the
33
       electronic transfer of data.
34
       1.5. ``Executable'' means Covered Code in any form other than
35
       Source Code.
36
       1.6. ``Initial Developer'' means the individual or entity
37
       identified as the Initial Developer in the Source Code notice
38
       required by Exhibit A.
39
       1.7. ``Larger Work'' means a work which combines Covered Code or
40
       portions thereof with code not governed by the terms of this
41
       License.
42
       1.8. ``License'' means this document.
43
       1.9. ``Modifications'' means any addition to or deletion from the
44
       substance or structure of either the Original Code or any previous
45
       Modifications. When Covered Code is released as a series of files,
46
       a Modification is:
47
       
48
   A. Any addition to or deletion from the contents of a file containing
49
       Original Code or previous Modifications.
50
       B. Any new file that contains any part of the Original Code or
51
       previous Modifications.
52
       
53
   1.10. ``Original Code'' means Source Code of computer software code
54
   which is described in the Source Code notice required by Exhibit A as
55
   Original Code, and which, at the time of its release under this
56
   License is not already Covered Code governed by this License.
57
   
58
   1.11. ``Source Code'' means the preferred form of the Covered Code for
59
   making modifications to it, including all modules it contains, plus
60
   any associated interface definition files, scripts used to control
61
   compilation and installation of an Executable, or a list of source
62
   code differential comparisons against either the Original Code or
63
   another well known, available Covered Code of the Contributor's
64
   choice. The Source Code can be in a compressed or archival form,
65
   provided the appropriate decompression or de-archiving software is
66
   widely available for no charge.
67
   
68
   1.12. ``You'' means an individual or a legal entity exercising rights
69
   under, and complying with all of the terms of, this License or a
70
   future version of this License issued under Section 6.1. For legal
71
   entities, ``You'' includes any entity which controls, is controlled
72
   by, or is under common control with You. For purposes of this
73
   definition, ``control'' means (a) the power, direct or indirect, to
74
   cause the direction or management of such entity, whether by contract
75
   or otherwise, or (b) ownership of fifty percent (50%) or more of the
76
   outstanding shares or beneficial ownership of such entity.
77
   2. Source Code License.
78
   2.1. The Initial Developer Grant.
79
       The Initial Developer hereby grants You a world-wide,
80
       royalty-free, non-exclusive license, subject to third party
81
       intellectual property claims:
82
       
83
       (a) to use, reproduce, modify, display, perform, sublicense and
84
       distribute the Original Code (or portions thereof) with or without
85
       Modifications, or as part of a Larger Work; and
86
       (b) under patents now or hereafter owned or controlled by Initial
87
       Developer, to make, have made, use and sell (``Utilize'') the
88
       Original Code (or portions thereof), but solely to the extent that
89
       any such patent is reasonably necessary to enable You to Utilize
90
       the Original Code (or portions thereof) and not to any greater
91
       extent that may be necessary to Utilize further Modifications or
92
       combinations.
93
       
94
   2.2. Contributor Grant.
95
   Each Contributor hereby grants You a world-wide, royalty-free,
96
   non-exclusive license, subject to third party intellectual property
97
   claims:
98
   (a) to use, reproduce, modify, display, perform, sublicense and
99
       distribute the Modifications created by such Contributor (or
100
       portions thereof) either on an unmodified basis, with other
101
       Modifications, as Covered Code or as part of a Larger Work; and
102
       (b) under patents now or hereafter owned or controlled by
103
       Contributor, to Utilize the Contributor Version (or portions
104
       thereof), but solely to the extent that any such patent is
105
       reasonably necessary to enable You to Utilize the Contributor
106
       Version (or portions thereof), and not to any greater extent that
107
       may be necessary to Utilize further Modifications or combinations.
108
       
109
   3. Distribution Obligations.
110
   3.1. Application of License.
111
       The Modifications which You create or to which You contribute are
112
       governed by the terms of this License, including without
113
       limitation Section 2.2. The Source Code version of Covered Code
114
       may be distributed only under the terms of this License or a
115
       future version of this License released under Section 6.1, and You
116
       must include a copy of this License with every copy of the Source
117
       Code You distribute. You may not offer or impose any terms on any
118
       Source Code version that alters or restricts the applicable
119
       version of this License or the recipients' rights hereunder.
120
       However, You may include an additional document offering the
121
       additional rights described in Section 3.5.
122
       3.2. Availability of Source Code.
123
       Any Modification which You create or to which You contribute must
124
       be made available in Source Code form under the terms of this
125
       License either on the same media as an Executable version or via
126
       an accepted Electronic Distribution Mechanism to anyone to whom
127
       you made an Executable version available; and if made available
128
       via Electronic Distribution Mechanism, must remain available for
129
       at least twelve (12) months after the date it initially became
130
       available, or at least six (6) months after a subsequent version
131
       of that particular Modification has been made available to such
132
       recipients. You are responsible for ensuring that the Source Code
133
       version remains available even if the Electronic Distribution
134
       Mechanism is maintained by a third party.
135
       3.3. Description of Modifications.
136
       You must cause all Covered Code to which you contribute to contain
137
       a file documenting the changes You made to create that Covered
138
       Code and the date of any change. You must include a prominent
139
       statement that the Modification is derived, directly or
140
       indirectly, from Original Code provided by the Initial Developer
141
       and including the name of the Initial Developer in (a) the Source
142
       Code, and (b) in any notice in an Executable version or related
143
       documentation in which You describe the origin or ownership of the
144
       Covered Code.
145
       3.4. Intellectual Property Matters
146
       
147
   (a) Third Party Claims.
148
       If You have knowledge that a party claims an intellectual property
149
       right in particular functionality or code (or its utilization
150
       under this License), you must include a text file with the source
151
       code distribution titled ``LEGAL'' which describes the claim and
152
       the party making the claim in sufficient detail that a recipient
153
       will know whom to contact. If you obtain such knowledge after You
154
       make Your Modification available as described in Section 3.2, You
155
       shall promptly modify the LEGAL file in all copies You make
156
       available thereafter and shall take other steps (such as notifying
157
       appropriate mailing lists or newsgroups) reasonably calculated to
158
       inform those who received the Covered Code that new knowledge has
159
       been obtained.
160
       (b) Contributor APIs.
161
       If Your Modification is an application programming interface and
162
       You own or control patents which are reasonably necessary to
163
       implement that API, you must also include this information in the
164
       LEGAL file.
165
       
166
   3.5. Required Notices.
167
   You must duplicate the notice in Exhibit A in each file of the Source
168
   Code, and this License in any documentation for the Source Code, where
169
   You describe recipients' rights relating to Covered Code. If You
170
   created one or more Modification(s), You may add your name as a
171
   Contributor to the notice described in Exhibit A. If it is not
172
   possible to put such notice in a particular Source Code file due to
173
   its structure, then you must include such notice in a location (such
174
   as a relevant directory file) where a user would be likely to look for
175
   such a notice. You may choose to offer, and to charge a fee for,
176
   warranty, support, indemnity or liability obligations to one or more
177
   recipients of Covered Code. However, You may do so only on Your own
178
   behalf, and not on behalf of the Initial Developer or any Contributor.
179
   You must make it absolutely clear than any such warranty, support,
180
   indemnity or liability obligation is offered by You alone, and You
181
   hereby agree to indemnify the Initial Developer and every Contributor
182
   for any liability incurred by the Initial Developer or such
183
   Contributor as a result of warranty, support, indemnity or liability
184
   terms You offer.
185
   
186
   3.6. Distribution of Executable Versions.
187
   You may distribute Covered Code in Executable form only if the
188
   requirements of Section 3.1-3.5 have been met for that Covered Code,
189
   and if You include a notice stating that the Source Code version of
190
   the Covered Code is available under the terms of this License,
191
   including a description of how and where You have fulfilled the
192
   obligations of Section 3.2. The notice must be conspicuously included
193
   in any notice in an Executable version, related documentation or
194
   collateral in which You describe recipients' rights relating to the
195
   Covered Code. You may distribute the Executable version of Covered
196
   Code under a license of Your choice, which may contain terms different
197
   from this License, provided that You are in compliance with the terms
198
   of this License and that the license for the Executable version does
199
   not attempt to limit or alter the recipient's rights in the Source
200
   Code version from the rights set forth in this License. If You
201
   distribute the Executable version under a different license You must
202
   make it absolutely clear that any terms which differ from this License
203
   are offered by You alone, not by the Initial Developer or any
204
   Contributor. You hereby agree to indemnify the Initial Developer and
205
   every Contributor for any liability incurred by the Initial Developer
206
   or such Contributor as a result of any such terms You offer.
207
   
208
   3.7. Larger Works.
209
   You may create a Larger Work by combining Covered Code with other code
210
   not governed by the terms of this License and distribute the Larger
211
   Work as a single product. In such a case, You must make sure the
212
   requirements of this License are fulfilled for the Covered Code.
213
   4. Inability to Comply Due to Statute or Regulation.
214
       If it is impossible for You to comply with any of the terms of
215
       this License with respect to some or all of the Covered Code due
216
       to statute or regulation then You must: (a) comply with the terms
217
       of this License to the maximum extent possible; and (b) describe
218
       the limitations and the code they affect. Such description must be
219
       included in the LEGAL file described in Section 3.4 and must be
220
       included with all distributions of the Source Code. Except to the
221
       extent prohibited by statute or regulation, such description must
222
       be sufficiently detailed for a recipient of ordinary skill to be
223
       able to understand it.
224
       
225
   5. Application of this License.
226
   This License applies to code to which the Initial Developer has
227
       attached the notice in Exhibit A, and to related Covered Code.
228
       
229
   6. Versions of the License.
230
   6.1. New Versions.
231
       Netscape Communications Corporation (``Netscape'') may publish
232
       revised and/or new versions of the License from time to time. Each
233
       version will be given a distinguishing version number.
234
       6.2. Effect of New Versions.
235
       Once Covered Code has been published under a particular version of
236
       the License, You may always continue to use it under the terms of
237
       that version. You may also choose to use such Covered Code under
238
       the terms of any subsequent version of the License published by
239
       Netscape. No one other than Netscape has the right to modify the
240
       terms applicable to Covered Code created under this License.
241
       6.3. Derivative Works.
242
       If you create or use a modified version of this License (which you
243
       may only do in order to apply it to code which is not already
244
       Covered Code governed by this License), you must (a) rename Your
245
       license so that the phrases ``Mozilla'', ``MOZILLAPL'', ``MOZPL'',
246
       ``Netscape'', ``NPL'' or any confusingly similar phrase do not
247
       appear anywhere in your license and (b) otherwise make it clear
248
       that your version of the license contains terms which differ from
249
       the Mozilla Public License and Netscape Public License. (Filling
250
       in the name of the Initial Developer, Original Code or Contributor
251
       in the notice described in Exhibit A shall not of themselves be
252
       deemed to be modifications of this License.)
253
       
254
   7. DISCLAIMER OF WARRANTY.
255
   COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN ``AS IS'' BASIS,
256
       WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
257
       INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS
258
       FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR
259
       NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
260
       OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE
261
       DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY
262
       OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING,
263
       REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN
264
       ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS
265
       AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
266
       
267
   8. TERMINATION.
268
   This License and the rights granted hereunder will terminate
269
       automatically if You fail to comply with terms herein and fail to
270
       cure such breach within 30 days of becoming aware of the breach.
271
       All sublicenses to the Covered Code which are properly granted
272
       shall survive any termination of this License. Provisions which,
273
       by their nature, must remain in effect beyond the termination of
274
       this License shall survive.
275
       
276
   9. LIMITATION OF LIABILITY.
277
   UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
278
       (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL
279
       DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED
280
       CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO YOU OR
281
       ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
282
       CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
283
       LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER
284
       FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR
285
       LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE
286
       POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL
287
       NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM
288
       SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS
289
       SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR
290
       LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT
291
       EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
292
       
293
   10. U.S. GOVERNMENT END USERS.
294
   The Covered Code is a ``commercial item,'' as that term is defined in
295
       48 C.F.R. 2.101 (Oct. 1995), consisting of ``commercial computer
296
       software'' and ``commercial computer software documentation,'' as
297
       such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent
298
       with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4
299
       (June 1995), all U.S. Government End Users acquire Covered Code
300
       with only those rights set forth herein.
301
       
302
   11. MISCELLANEOUS.
303
   This License represents the complete agreement concerning subject
304
       matter hereof. If any provision of this License is held to be
305
       unenforceable, such provision shall be reformed only to the extent
306
       necessary to make it enforceable. This License shall be governed
307
       by California law provisions (except to the extent applicable law,
308
       if any, provides otherwise), excluding its conflict-of-law
309
       provisions. With respect to disputes in which at least one party
310
       is a citizen of, or an entity chartered or registered to do
311
       business in, the United States of America: (a) unless otherwise
312
       agreed in writing, all disputes relating to this License
313
       (excepting any dispute relating to intellectual property rights)
314
       shall be subject to final and binding arbitration, with the losing
315
       party paying all costs of arbitration; (b) any arbitration
316
       relating to this Agreement shall be held in Santa Clara County,
317
       California, under the auspices of JAMS/EndDispute; and (c) any
318
       litigation relating to this Agreement shall be subject to the
319
       jurisdiction of the Federal Courts of the Northern District of
320
       California, with venue lying in Santa Clara County, California,
321
       with the losing party responsible for costs, including without
322
       limitation, court costs and reasonable attorneys fees and
323
       expenses. The application of the United Nations Convention on
324
       Contracts for the International Sale of Goods is expressly
325
       excluded. Any law or regulation which provides that the language
326
       of a contract shall be construed against the drafter shall not
327
       apply to this License.
328
       
329
   12. RESPONSIBILITY FOR CLAIMS.
330
   Except in cases where another Contributor has failed to comply with
331
       Section 3.4, You are responsible for damages arising, directly or
332
       indirectly, out of Your utilization of rights under this License,
333
       based on the number of copies of Covered Code you made available,
334
       the revenues you received from utilizing such rights, and other
335
       relevant factors. You agree to work with affected parties to
336
       distribute responsibility on an equitable basis.
337
       
338
   EXHIBIT A.
339
   ``The contents of this file are subject to the Mozilla Public License
340
       Version 1.0 (the "License"); you may not use this file except in
341
       compliance with the License. You may obtain a copy of the License
342
       at http://www.mozilla.org/MPL/
343
       Software distributed under the License is distributed on an "AS
344
       IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
345
       implied. See the License for the specific language governing
346
       rights and limitations under the License.
347
       The Original Code is ______________________________________.
348
       The Initial Developer of the Original Code is
349
       ________________________. Portions created by
350
       ______________________ are Copyright (C) ______
351
       _______________________. All Rights Reserved.
352
       Contributor(s): ______________________________________.''
353
++ pwlib-1.2.5/debian/rules
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/dirs
1
#!/usr/bin/make -f
2
3
export DH_COMPAT=3
4
5
export DH_OPTIONS
6
7
export LIBPTCOMPAT=-1.2.0
8
PACKAGE=libpt$(LIBPTCOMPAT)
9
SHLIBSVER=1.2.5-3
10
11
# version=$(shell expr `pwd` : '.*-\([0-9.]*\)')
12
# version_major=$(shell expr `pwd` : '.*-\([0-9]*\).[0-9.]*')
13
14
ifeq ($(findstring $(DEB_BUILD_ARCH),alpha),)
15
OPTN=-O2
16
else
17
OPTN=-O0
18
endif
19
20
build:
21
	# Compile it all, first static and then shared, so we get shared bins
22
	$(MAKE) CFLAGS="$(OPTN) -fPIC -DPIC -pipe" PWLIBDIR=$(PWD) debugnoshared debugshared optnoshared optshared
23
	
24
	# This dirty stuff is done to compile simple with apropiate options
25
	$(MAKE) CFLAGS="$(OPTN) -pipe" PWLIBDIR=$(PWD) -C tools/asnparser clean opt
26
27
	touch build
28
29
clean:
30
	$(checkdir)
31
	-rm -f build
32
	-$(MAKE) PWLIBDIR=$(PWD) clean
33
	-rm -f `find . -name "*~"`
34
	-rm -rf `find debian/* -type d ! -name CVS` debian/files* core
35
	-rm -f debian/*substvars
36
	-rm -f debian/*.debhelper
37
	-rm -rf lib
38
	-rm -f debian/$(PACKAGE).docs
39
40
binary-indep: build
41
# There are no architecture-independent files to be uploaded
42
# generated by this package.  If there were any they would be
43
# made here.
44
45
binary-arch: build
46
	-rm -rf `find debian/* -type d`
47
#	Initialize the building procedure
48
	dh_testdir
49
	dh_clean
50
	dh_installdirs
51
52
53
	$(MAKE) -C src/ptlib/unix install PWLIBDIR=$(PWD) INSTALL_DIR=`pwd`/debian/$(PACKAGE)/usr
54
55
#	libpt-dev
56
	dh_movefiles -plibpt-dev --sourcedir=debian/$(PACKAGE) `cd debian/$(PACKAGE); ls -1 usr/lib/*.so`
57
	ln -s `cd debian/$(PACKAGE)/usr/lib; ls -1 *.so.*.*.*` debian/libpt-dev/usr/lib/libpt.so
58
	cp -vr include/pt* `pwd`/debian/libpt-dev/usr/include
59
	cp -vr make `pwd`/debian/libpt-dev/usr/share/pwlib
60
	-rm -f `pwd`/debian/libpt-dev/usr/share/pwlib/make/unix.mak
61
	sed -e 's/$$(PWLIBDIR)\/include\/ptlib\/unix/\/usr\/include\/ptlib\/unix/g' -e 's/$$(PWLIBDIR)\/lib/\/usr\/lib/g' -e 's/-fPIC/$(OPTN) -fPIC -DPIC -pipe/g' make/unix.mak > `pwd`/debian/libpt-dev/usr/share/pwlib/make/unix.mak
62
	cp lib/*.a `pwd`/debian/libpt-dev/usr/lib
63
64
#	libpt-dbg
65
	dh_movefiles -plibpt-dbg --sourcedir=debian/libpt-dev `cd debian/libpt-dev; ls -1 usr/lib/libpt*_d*.a`
66
# Temporary solution to avoid having the same library twice, this libs stink
67
	ln -s libpt_d_s.a debian/libpt-dbg/usr/lib/libpt_d.a
68
	cp -vr lib/libpt*_d.so* `pwd`/debian/libpt-dbg/usr/lib
69
70
#	asnparser
71
	$(MAKE) -C tools/asnparser install PWLIBDIR=$(PWD) INSTALL_DIR=`pwd`/debian/asnparser/usr
72
73
#	Remove all CVS sub-directories
74
	find debian -name "CVS" -type d|xargs rm -rf
75
	cp debian/libpt.docs debian/$(PACKAGE).docs
76
77
#	Install the other (Debian) stuff
78
#	dh_testversion
79
	dh_testroot
80
	dh_installdebconf
81
	dh_installdocs
82
#	dh_installexamples
83
#	dh_installmenu
84
#	dh_installemacsen
85
	dh_installinit
86
#	dh_installcron
87
	dh_installman -p asnparser debian/asnparser.1
88
	dh_undocumented
89
	dh_installchangelogs
90
	dh_strip
91
	dh_compress
92
	dh_fixperms
93
	dh_makeshlibs -V "$(PACKAGE) (>= $(SHLIBSVER))"
94
	dh_installdeb
95
	dh_shlibdeps
96
	dh_gencontrol
97
	dh_md5sums
98
	dh_builddeb
99
100
binary: binary-indep binary-arch
101
102
.PHONY: binary binary-arch binary-indep clean checkroot
103
++ pwlib-1.2.5/debian/dirs
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/asnparser.1
1
usr/lib
2
++ pwlib-1.2.5/debian/asnparser.1
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/libpt-dev.dirs
1
'\" t
2
.\" Man page for asnparser
3
.\" Santiago Garcia Mantinan (manty) 18 Jul 2001
4
.\"
5
.TH asnparser 1 "18 Jul 2001"
6
.LO 1
7
.SH NAME
8
asnparser \- ASN.1 to C/C++ converter
9
.SH SYNOPSIS
10
.B asnparser
11
[\fIoptions\fR]... \fIasnfile\fR
12
.SH DESCRIPTION
13
.PP
14
.B asnparser
15
is a command line application that helps to convert ASN.1 description files
16
to C/C++ applications.
17
18
.SH OPTIONS
19
.PP
20
All of the command line options to
21
.B asnparser
22
can be specified in long form, and the most commonly used options also have
23
single character equivalents.
24
25
.TP
26
\fB\-c\fR, \fB\-\-c++\fR
27
Generate C++ files.
28
29
.TP
30
\fB\-d\fR, \fB\-\-debug\fR
31
Output a copious debug info on stderr.
32
33
.TP
34
\fB\-e\fR, \fB\-\-echo\fR
35
Echo input file on stdout.
36
37
.TP
38
\fB\-i\fR, \fB\-\-inlines\fR
39
Use C++ inlines.
40
41
.TP
42
\fB\-m\fR, \fB\-\-module\fR \fIname\fR
43
Sets the module name prefix/namespace to \fIname\fR.
44
45
.TP
46
\fB\-n\fR, \fB\-\-namespace\fR
47
Use C++ namespace.
48
49
.TP
50
\fB\-o\fR, \fB\-\-output\fR \fIfile\fR
51
Sets the output filename or directory to \fIname\fR.
52
53
.TP
54
\fB\-r\fR, \fB\-\-rename\fR \fIfrom=to\fR
55
Rename import module from \fIfrom\fR to \fIto\fR.
56
57
.TP
58
\fB\-s\fR[n], \fB\-\-split\fR[n]
59
Split output into n files (n defaults to 2).
60
61
.TP
62
\fB\-v\fR, \fB\-\-verbose\fR
63
Verbose output, using this option multiple times will give even more verbose
64
output.
65
66
.TP
67
\fB\-V\fR, \fB\-\-version\fR
68
Display program version and exit.
69
70
.SH EXAMPLES
71
.PP
72
73
.TP
74
asnparser -m H225 -r MULTIMEDIA-SYSTEM-CONTROL=H245 -c h225.asn
75
76
.TP
77
asnparser -s3 -m H245 -c h245.asn
78
79
.SH "SEE ALSO"
80
None
81
++ pwlib-1.2.5/debian/libpt-dev.dirs
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/libpt.docs
1
usr/include
2
usr/lib
3
usr/share/pwlib
4
++ pwlib-1.2.5/debian/libpt.docs
Line 0 Link Here
0
-- pwlib-1.2.5.orig/debian/libpt-dbg.dirs
1
History.txt
2
++ pwlib-1.2.5/debian/libpt-dbg.dirs
Line 0 Link Here
1
usr/lib

Return to bug 49881