//+-------------------------------------------------------------------------------+
//| Copyright (c) 2003 Liping Dai. All rights reserved. |
//| Web: www.lipingshare.com |
//| Email: lipingshare@yahoo.com |
//| |
//| Copyright and Permission Details: |
//| ================================= |
//| Permission is hereby granted, free of charge, to any person obtaining a copy |
//| of this software and associated documentation files (the "Software"), to deal |
//| in the Software without restriction, including without limitation the rights |
//| to use, copy, modify, merge, publish, distribute, and/or sell copies of the |
//| Software, subject to the following conditions: |
//| |
//| 1. Redistributions of source code must retain the above copyright notice, this|
//| list of conditions and the following disclaimer. |
//| |
//| 2. Redistributions in binary form must reproduce the above copyright notice, |
//| this list of conditions and the following disclaimer in the documentation |
//| and/or other materials provided with the distribution. |
//| |
//| THE SOFTWARE PRODUCT IS PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, |
//| EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
//| WARRANTIES OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR |
//| A PARTICULAR PURPOSE. |
//+-------------------------------------------------------------------------------+
using System;
using System.IO;
using System.Collections.Specialized;
namespace LipingShare.LCLib.Asn1Processor
{
///
/// Summary description for OID.
/// This class is used to encode and decode OID strings.
///
internal class Oid
{
///
/// Retrieve OID name by OID string.
///
/// source OID string.
/// OID name.
public string GetOidName(string inOidStr)
{
if (oidDictionary == null) //Initialize oidDictionary:
{
oidDictionary = new StringDictionary();
// string oidStr = "";
// string oidDesc = "";
// bool loadOidError = false;
// int dbCounter = 0;
}
return oidDictionary[inOidStr];
}
///
/// Encode OID string to byte array.
///
/// source string.
/// encoded array.
public byte[] Encode(string oidStr)
{
MemoryStream ms = new MemoryStream();
Encode(ms, oidStr);
ms.Position = 0;
byte[] retval = new byte[ms.Length];
ms.Read(retval, 0, retval.Length);
ms.Close();
return retval;
}
///
/// Decode OID byte array to OID string.
///
/// source byte array.
/// result OID string.
public string Decode(byte[] data)
{
MemoryStream ms = new MemoryStream(data);
ms.Position = 0;
string retval = Decode(ms);
ms.Close();
return retval;
}
///
/// Encode OID string and put result into
///
/// output stream.
/// source OID string.
public virtual void Encode(Stream bt, string oidStr) //TODO
{
string[] oidList = oidStr.Split('.');
if (oidList.Length < 2) throw new Exception("Invalid OID string.");
ulong[] values = new ulong[oidList.Length];
for (int i = 0; i < oidList.Length; i++)
{
values[i] = Convert.ToUInt64(oidList[i]);
}
bt.WriteByte((byte)(values[0] * 40 + values[1]));
for (int i = 2; i < values.Length; i++)
EncodeValue(bt, values[i]);
}
///
/// Decode OID and return OID string.
///
/// source stream.
/// result OID string.
public virtual string Decode(Stream bt)
{
string retval = "";
byte b;
ulong v = 0;
b = (byte)bt.ReadByte();
retval += Convert.ToString(b / 40);
retval += "." + Convert.ToString(b % 40);
while (bt.Position < bt.Length)
{
try
{
DecodeValue(bt, ref v);
retval += "." + v.ToString();
}
catch (Exception e)
{
throw new Exception("Failed to decode OID value: " + e.Message);
}
}
return retval;
}
///
/// OID dictionary.
///
private static StringDictionary oidDictionary = null;
///
/// Default constructor
///
public Oid()
{
}
///
/// Encode single OID value.
///
/// output stream.
/// source value.
protected void EncodeValue(Stream bt, ulong v)
{
for (int i = (Asn1Util.BitPrecision(v) - 1) / 7; i > 0; i--)
{
bt.WriteByte((byte)(0x80 | ((v >> (i * 7)) & 0x7f)));
}
bt.WriteByte((byte)(v & 0x7f));
}
///
/// Decode single OID value.
///
/// source stream.
/// output value
/// OID value bytes.
protected int DecodeValue(Stream bt, ref ulong v)
{
byte b;
int i = 0;
v = 0;
while (true)
{
b = (byte)bt.ReadByte();
i++;
v <<= 7;
v += (ulong)(b & 0x7f);
if ((b & 0x80) == 0)
return i;
}
}
}
}