1 /******************************************************************************
3 * Copyright (c) 2003 Novell Inc. www.novell.com
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the Software), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 *******************************************************************************/
24 // Novell.Directory.Ldap.LdapAttribute.cs
27 // Sunil Kumar (Sunilk@novell.com)
29 // (C) 2003 Novell, Inc (http://www.novell.com)
33 using ArrayEnumeration = Novell.Directory.Ldap.Utilclass.ArrayEnumeration;
34 using Base64 = Novell.Directory.Ldap.Utilclass.Base64;
36 namespace Novell.Directory.Ldap
38 /// <summary> The name and values of one attribute of a directory entry.
40 /// LdapAttribute objects are used when searching for, adding,
41 /// modifying, and deleting attributes from the directory.
42 /// LdapAttributes are often used in conjunction with an
43 /// {@link LdapAttributeSet} when retrieving or adding multiple
44 /// attributes to an entry.
49 /// <seealso cref="LdapEntry">
51 /// <seealso cref="LdapAttributeSet">
53 /// <seealso cref="LdapModification">
56 public class LdapAttribute : System.ICloneable, System.IComparable
60 private void InitBlock(LdapAttribute enclosingInstance)
62 this.enclosingInstance = enclosingInstance;
64 private LdapAttribute enclosingInstance;
65 public LdapAttribute Enclosing_Instance
69 return enclosingInstance;
75 public URLData(LdapAttribute enclosingInstance, sbyte[] data, int length)
77 InitBlock(enclosingInstance);
82 public int getLength()
86 public sbyte[] getData()
91 /// <summary> Returns an enumerator for the values of the attribute in byte format.
94 /// <returns> The values of the attribute in byte format.
95 /// Note: All string values will be UTF-8 encoded. To decode use the
96 /// String constructor. Example: new String( byteArray, "UTF-8" );
98 virtual public System.Collections.IEnumerator ByteValues
102 return new ArrayEnumeration(ByteValueArray);
106 /// <summary> Returns an enumerator for the string values of an attribute.
109 /// <returns> The string values of an attribute.
111 virtual public System.Collections.IEnumerator StringValues
115 return new ArrayEnumeration(StringValueArray);
119 /// <summary> Returns the values of the attribute as an array of bytes.
122 /// <returns> The values as an array of bytes or an empty array if there are
125 [CLSCompliantAttribute(false)]
126 virtual public sbyte[][] ByteValueArray
130 if (null == this.values)
131 return new sbyte[0][];
132 int size = this.values.Length;
133 sbyte[][] bva = new sbyte[size][];
134 // Deep copy so application cannot change values
135 for (int i = 0, u = size; i < u; i++)
137 bva[i] = new sbyte[((sbyte[]) values[i]).Length];
138 Array.Copy((System.Array) this.values[i], 0, (System.Array) bva[i], 0, bva[i].Length);
144 /// <summary> Returns the values of the attribute as an array of strings.
147 /// <returns> The values as an array of strings or an empty array if there are
150 virtual public System.String[] StringValueArray
154 if (null == this.values)
155 return new System.String[0];
156 int size = values.Length;
157 System.String[] sva = new System.String[size];
158 for (int j = 0; j < size; j++)
162 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
163 char[] dchar = encoder.GetChars(SupportClass.ToByteArray((sbyte[])values[j]));
164 // char[] dchar = encoder.GetChars((byte[])values[j]);
165 sva[j] = new String(dchar);
166 // sva[j] = new String((sbyte[]) values[j], "UTF-8");
168 catch (System.IO.IOException uee)
170 // Exception should NEVER get thrown but just in case it does ...
171 throw new System.SystemException(uee.ToString());
178 /// <summary> Returns the the first value of the attribute as a <code>String</code>.
181 /// <returns> The UTF-8 encoded<code>String</code> value of the attribute's
182 /// value. If the value wasn't a UTF-8 encoded <code>String</code>
183 /// to begin with the value of the returned <code>String</code> is
184 /// non deterministic.
186 /// If <code>this</code> attribute has more than one value the
187 /// first value is converted to a UTF-8 encoded <code>String</code>
188 /// and returned. It should be noted, that the directory may
189 /// return attribute values in any order, so that the first
190 /// value may vary from one call to another.
192 /// If the attribute has no values <code>null</code> is returned
194 virtual public System.String StringValue
198 System.String rval = null;
199 if (this.values != null)
203 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
204 char[] dchar = encoder.GetChars(SupportClass.ToByteArray((sbyte[])this.values[0]));
205 // char[] dchar = encoder.GetChars((byte[]) this.values[0]);
206 rval = new String(dchar);
208 catch (System.IO.IOException use)
210 throw new System.SystemException(use.ToString());
217 /// <summary> Returns the the first value of the attribute as a byte array.
220 /// <returns> The binary value of <code>this</code> attribute or
221 /// <code>null</code> if <code>this</code> attribute doesn't have a value.
223 /// If the attribute has no values <code>null</code> is returned
225 [CLSCompliantAttribute(false)]
226 virtual public sbyte[] ByteValue
231 if (this.values != null)
233 // Deep copy so app can't change the value
234 bva = new sbyte[((sbyte[]) values[0]).Length];
235 Array.Copy((System.Array) this.values[0], 0, (System.Array) bva, 0, bva.Length);
241 /// <summary> Returns the language subtype of the attribute, if any.
243 /// For example, if the attribute name is cn;lang-ja;phonetic,
244 /// this method returns the string, lang-ja.
247 /// <returns> The language subtype of the attribute or null if the attribute
250 virtual public System.String LangSubtype
254 if (subTypes != null)
256 for (int i = 0; i < subTypes.Length; i++)
258 if (subTypes[i].StartsWith("lang-"))
268 /// <summary> Returns the name of the attribute.
271 /// <returns> The name of the attribute.
273 virtual public System.String Name
281 /// <summary> Replaces all values with the specified value. This protected method is
282 /// used by sub-classes of LdapSchemaElement because the value cannot be set
283 /// with a contructor.
285 virtual protected internal System.String Value
292 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
293 byte[] ibytes = encoder.GetBytes(value);
294 sbyte[] sbytes=SupportClass.ToSByteArray(ibytes);
298 catch (System.IO.IOException ue)
300 throw new System.SystemException(ue.ToString());
306 private System.String name; // full attribute name
307 private System.String baseName; // cn of cn;lang-ja;phonetic
308 private System.String[] subTypes = null; // lang-ja of cn;lang-ja
309 private System.Object[] values = null; // Array of byte[] attribute values
311 /// <summary> Constructs an attribute with copies of all values of the input
315 /// <param name="attr"> An LdapAttribute to use as a template.
317 /// @throws IllegalArgumentException if attr is null
319 public LdapAttribute(LdapAttribute attr)
323 throw new System.ArgumentException("LdapAttribute class cannot be null");
325 // Do a deep copy of the LdapAttribute template
326 this.name = attr.name;
327 this.baseName = attr.baseName;
328 if (null != attr.subTypes)
330 this.subTypes = new System.String[attr.subTypes.Length];
331 Array.Copy((System.Array) attr.subTypes, 0, (System.Array) this.subTypes, 0, this.subTypes.Length);
333 // OK to just copy attributes, as the app only sees a deep copy of them
334 if (null != attr.values)
336 this.values = new System.Object[attr.values.Length];
337 Array.Copy((System.Array) attr.values, 0, (System.Array) this.values, 0, this.values.Length);
342 /// <summary> Constructs an attribute with no values.
345 /// <param name="attrName">Name of the attribute.
347 /// @throws IllegalArgumentException if attrName is null
349 public LdapAttribute(System.String attrName)
351 if ((System.Object) attrName == null)
353 throw new System.ArgumentException("Attribute name cannot be null");
355 this.name = attrName;
356 this.baseName = LdapAttribute.getBaseName(attrName);
357 this.subTypes = LdapAttribute.getSubtypes(attrName);
361 /// <summary> Constructs an attribute with a byte-formatted value.
364 /// <param name="attrName">Name of the attribute.
366 /// <param name="attrBytes">Value of the attribute as raw bytes.
368 /// Note: If attrBytes represents a string it should be UTF-8 encoded.
370 /// @throws IllegalArgumentException if attrName or attrBytes is null
372 [CLSCompliantAttribute(false)]
373 public LdapAttribute(System.String attrName, sbyte[] attrBytes):this(attrName)
375 if (attrBytes == null)
377 throw new System.ArgumentException("Attribute value cannot be null");
379 // Make our own copy of the byte array to prevent app from changing it
380 sbyte[] tmp = new sbyte[attrBytes.Length];
381 Array.Copy((System.Array) attrBytes, 0, (System.Array)tmp, 0, attrBytes.Length);
386 /// <summary> Constructs an attribute with a single string value.
389 /// <param name="attrName">Name of the attribute.
391 /// <param name="attrString">Value of the attribute as a string.
393 /// @throws IllegalArgumentException if attrName or attrString is null
395 public LdapAttribute(System.String attrName, System.String attrString):this(attrName)
397 if ((System.Object) attrString == null)
399 throw new System.ArgumentException("Attribute value cannot be null");
403 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
404 byte[] ibytes = encoder.GetBytes(attrString);
405 sbyte[] sbytes=SupportClass.ToSByteArray(ibytes);
409 catch (System.IO.IOException e)
411 throw new System.SystemException(e.ToString());
416 /// <summary> Constructs an attribute with an array of string values.
419 /// <param name="attrName">Name of the attribute.
421 /// <param name="attrStrings">Array of values as strings.
423 /// @throws IllegalArgumentException if attrName, attrStrings, or a member
424 /// of attrStrings is null
426 public LdapAttribute(System.String attrName, System.String[] attrStrings):this(attrName)
428 if (attrStrings == null)
430 throw new System.ArgumentException("Attribute values array cannot be null");
432 for (int i = 0, u = attrStrings.Length; i < u; i++)
436 if ((System.Object) attrStrings[i] == null)
438 throw new System.ArgumentException("Attribute value " + "at array index " + i + " cannot be null");
440 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
441 byte[] ibytes = encoder.GetBytes(attrStrings[i]);
442 sbyte[] sbytes=SupportClass.ToSByteArray(ibytes);
444 // this.add(attrStrings[i].getBytes("UTF-8"));
446 catch (System.IO.IOException e)
448 throw new System.SystemException(e.ToString());
454 /// <summary> Returns a clone of this LdapAttribute.
457 /// <returns> clone of this LdapAttribute.
459 public System.Object Clone()
463 System.Object newObj = base.MemberwiseClone();
466 Array.Copy((System.Array) this.values, 0, (System.Array) ((LdapAttribute) newObj).values, 0, this.values.Length);
470 catch (System.Exception ce)
472 throw new System.SystemException("Internal error, cannot create clone");
476 /// <summary> Adds a string value to the attribute.
479 /// <param name="attrString">Value of the attribute as a String.
481 /// @throws IllegalArgumentException if attrString is null
483 public virtual void addValue(System.String attrString)
485 if ((System.Object) attrString == null)
487 throw new System.ArgumentException("Attribute value cannot be null");
491 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
492 byte[] ibytes = encoder.GetBytes(attrString);
493 sbyte[] sbytes=SupportClass.ToSByteArray(ibytes);
495 // this.add(attrString.getBytes("UTF-8"));
497 catch (System.IO.IOException ue)
499 throw new System.SystemException(ue.ToString());
504 /// <summary> Adds a byte-formatted value to the attribute.
507 /// <param name="attrBytes">Value of the attribute as raw bytes.
509 /// Note: If attrBytes represents a string it should be UTF-8 encoded.
511 /// @throws IllegalArgumentException if attrBytes is null
513 [CLSCompliantAttribute(false)]
514 public virtual void addValue(sbyte[] attrBytes)
516 if (attrBytes == null)
518 throw new System.ArgumentException("Attribute value cannot be null");
524 /// <summary> Adds a base64 encoded value to the attribute.
525 /// The value will be decoded and stored as bytes. String
526 /// data encoded as a base64 value must be UTF-8 characters.
529 /// <param name="attrString">The base64 value of the attribute as a String.
531 /// @throws IllegalArgumentException if attrString is null
533 public virtual void addBase64Value(System.String attrString)
535 if ((System.Object) attrString == null)
537 throw new System.ArgumentException("Attribute value cannot be null");
540 this.add(Base64.decode(attrString));
544 /// <summary> Adds a base64 encoded value to the attribute.
545 /// The value will be decoded and stored as bytes. Character
546 /// data encoded as a base64 value must be UTF-8 characters.
549 /// <param name="attrString">The base64 value of the attribute as a StringBuffer.
551 /// <param name="start"> The start index of base64 encoded part, inclusive.
553 /// <param name="end"> The end index of base encoded part, exclusive.
555 /// @throws IllegalArgumentException if attrString is null
557 public virtual void addBase64Value(System.Text.StringBuilder attrString, int start, int end)
559 if (attrString == null)
561 throw new System.ArgumentException("Attribute value cannot be null");
564 this.add(Base64.decode(attrString, start, end));
569 /// <summary> Adds a base64 encoded value to the attribute.
570 /// The value will be decoded and stored as bytes. Character
571 /// data encoded as a base64 value must be UTF-8 characters.
574 /// <param name="attrChars">The base64 value of the attribute as an array of
577 /// @throws IllegalArgumentException if attrString is null
579 public virtual void addBase64Value(char[] attrChars)
581 if (attrChars == null)
583 throw new System.ArgumentException("Attribute value cannot be null");
586 this.add(Base64.decode(attrChars));
590 /// <summary> Adds a URL, indicating a file or other resource that contains
591 /// the value of the attribute.
594 /// <param name="url">String value of a URL pointing to the resource containing
595 /// the value of the attribute.
597 /// @throws IllegalArgumentException if url is null
599 public virtual void addURLValue(System.String url)
601 if ((System.Object) url == null)
603 throw new System.ArgumentException("Attribute URL cannot be null");
605 addURLValue(new System.Uri(url));
609 /// <summary> Adds a URL, indicating a file or other resource that contains
610 /// the value of the attribute.
613 /// <param name="url">A URL class pointing to the resource containing the value
614 /// of the attribute.
616 /// @throws IllegalArgumentException if url is null
618 public virtual void addURLValue(System.Uri url)
620 // Class to encapsulate the data bytes and the length
623 throw new System.ArgumentException("Attribute URL cannot be null");
627 // Get InputStream from the URL
628 System.IO.Stream in_Renamed = System.Net.WebRequest.Create(url).GetResponse().GetResponseStream();
629 // Read the bytes into buffers and store the them in an arraylist
630 System.Collections.ArrayList bufs = new System.Collections.ArrayList();
631 sbyte[] buf = new sbyte[4096];
632 int len, totalLength = 0;
633 while ((len = SupportClass.ReadInput(in_Renamed, ref buf, 0, 4096)) != - 1)
635 bufs.Add(new URLData(this, buf, len));
636 buf = new sbyte[4096];
640 * Now that the length is known, allocate an array to hold all
641 * the bytes of data and copy the data to that array, store
642 * it in this LdapAttribute
644 sbyte[] data = new sbyte[totalLength];
646 for (int i = 0; i < bufs.Count; i++)
648 URLData b = (URLData) bufs[i];
650 Array.Copy((System.Array) b.getData(), 0, (System.Array) data, offset, len);
655 catch (System.IO.IOException ue)
657 throw new System.SystemException(ue.ToString());
662 /// <summary> Returns the base name of the attribute.
664 /// For example, if the attribute name is cn;lang-ja;phonetic,
665 /// this method returns cn.
668 /// <returns> The base name of the attribute.
670 public virtual System.String getBaseName()
675 /// <summary> Returns the base name of the specified attribute name.
677 /// For example, if the attribute name is cn;lang-ja;phonetic,
678 /// this method returns cn.
681 /// <param name="attrName">Name of the attribute from which to extract the
685 /// <returns> The base name of the attribute.
687 /// @throws IllegalArgumentException if attrName is null
689 public static System.String getBaseName(System.String attrName)
691 if ((System.Object) attrName == null)
693 throw new System.ArgumentException("Attribute name cannot be null");
695 int idx = attrName.IndexOf((System.Char) ';');
700 return attrName.Substring(0, (idx) - (0));
703 /// <summary> Extracts the subtypes from the attribute name.
705 /// For example, if the attribute name is cn;lang-ja;phonetic,
706 /// this method returns an array containing lang-ja and phonetic.
709 /// <returns> An array subtypes or null if the attribute has none.
711 public virtual System.String[] getSubtypes()
716 /// <summary> Extracts the subtypes from the specified attribute name.
718 /// For example, if the attribute name is cn;lang-ja;phonetic,
719 /// this method returns an array containing lang-ja and phonetic.
722 /// <param name="attrName"> Name of the attribute from which to extract
726 /// <returns> An array subtypes or null if the attribute has none.
728 /// @throws IllegalArgumentException if attrName is null
730 public static System.String[] getSubtypes(System.String attrName)
732 if ((System.Object) attrName == null)
734 throw new System.ArgumentException("Attribute name cannot be null");
736 SupportClass.Tokenizer st = new SupportClass.Tokenizer(attrName, ";");
737 System.String[] subTypes = null;
741 st.NextToken(); // skip over basename
742 subTypes = new System.String[cnt - 1];
744 while (st.HasMoreTokens())
746 subTypes[i++] = st.NextToken();
752 /// <summary> Reports if the attribute name contains the specified subtype.
754 /// For example, if you check for the subtype lang-en and the
755 /// attribute name is cn;lang-en, this method returns true.
758 /// <param name="subtype"> The single subtype to check for.
761 /// <returns> True, if the attribute has the specified subtype;
762 /// false, if it doesn't.
764 /// @throws IllegalArgumentException if subtype is null
766 public virtual bool hasSubtype(System.String subtype)
768 if ((System.Object) subtype == null)
770 throw new System.ArgumentException("subtype cannot be null");
772 if (null != this.subTypes)
774 for (int i = 0; i < subTypes.Length; i++)
776 if (subTypes[i].ToUpper().Equals(subtype.ToUpper()))
783 /// <summary> Reports if the attribute name contains all the specified subtypes.
785 /// For example, if you check for the subtypes lang-en and phonetic
786 /// and if the attribute name is cn;lang-en;phonetic, this method
787 /// returns true. If the attribute name is cn;phonetic or cn;lang-en,
788 /// this method returns false.
791 /// <param name="subtypes"> An array of subtypes to check for.
794 /// <returns> True, if the attribute has all the specified subtypes;
795 /// false, if it doesn't have all the subtypes.
797 /// @throws IllegalArgumentException if subtypes is null or if array member
800 public virtual bool hasSubtypes(System.String[] subtypes)
802 if (subtypes == null)
804 throw new System.ArgumentException("subtypes cannot be null");
806 for (int i = 0; i < subtypes.Length; i++)
808 for (int j = 0; j < subTypes.Length; j++)
810 if ((System.Object) subTypes[j] == null)
812 throw new System.ArgumentException("subtype " + "at array index " + i + " cannot be null");
814 if (subTypes[j].ToUpper().Equals(subtypes[i].ToUpper()))
825 /// <summary> Removes a string value from the attribute.
828 /// <param name="attrString"> Value of the attribute as a string.
830 /// Note: Removing a value which is not present in the attribute has
833 /// @throws IllegalArgumentException if attrString is null
835 public virtual void removeValue(System.String attrString)
837 if (null == (System.Object) attrString)
839 throw new System.ArgumentException("Attribute value cannot be null");
843 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
844 byte[] ibytes = encoder.GetBytes(attrString);
845 sbyte[] sbytes=SupportClass.ToSByteArray(ibytes);
846 this.removeValue(sbytes);
847 // this.removeValue(attrString.getBytes("UTF-8"));
849 catch (System.IO.IOException uee)
851 // This should NEVER happen but just in case ...
852 throw new System.SystemException(uee.ToString());
857 /// <summary> Removes a byte-formatted value from the attribute.
860 /// <param name="attrBytes"> Value of the attribute as raw bytes.
861 /// Note: If attrBytes represents a string it should be UTF-8 encoded.
862 /// Example: <code>String.getBytes("UTF-8");</code>
864 /// Note: Removing a value which is not present in the attribute has
867 /// @throws IllegalArgumentException if attrBytes is null
869 [CLSCompliantAttribute(false)]
870 public virtual void removeValue(sbyte[] attrBytes)
872 if (null == attrBytes)
874 throw new System.ArgumentException("Attribute value cannot be null");
876 for (int i = 0; i < this.values.Length; i++)
878 if (equals(attrBytes, (sbyte[]) this.values[i]))
880 if (0 == i && 1 == this.values.Length)
882 // Optimize if first element of a single valued attr
886 if (this.values.Length == 1)
892 int moved = this.values.Length - i - 1;
893 System.Object[] tmp = new System.Object[this.values.Length - 1];
896 Array.Copy((System.Array) values, 0, (System.Array) tmp, 0, i);
900 Array.Copy((System.Array) values, i + 1, (System.Array) tmp, i, moved);
911 /// <summary> Returns the number of values in the attribute.
914 /// <returns> The number of values in the attribute.
916 public virtual int size()
918 return null == this.values?0:this.values.Length;
921 /// <summary> Compares this object with the specified object for order.
923 /// Ordering is determined by comparing attribute names (see
924 /// {@link #getName() }) using the method compareTo() of the String class.
928 /// <param name="attribute"> The LdapAttribute to be compared to this object.
931 /// <returns> Returns a negative integer, zero, or a positive
932 /// integer as this object is less than, equal to, or greater than the
933 /// specified object.
935 public virtual int CompareTo(System.Object attribute)
938 return name.CompareTo(((LdapAttribute) attribute).name);
941 /// <summary> Adds an object to <code>this</code> object's list of attribute values
944 /// <param name="bytes"> Ultimately all of this attribute's values are treated
945 /// as binary data so we simplify the process by requiring
946 /// that all data added to our list is in binary form.
948 /// Note: If attrBytes represents a string it should be UTF-8 encoded.
950 private void add(sbyte[] bytes)
952 if (null == this.values)
954 this.values = new System.Object[]{bytes};
958 // Duplicate attribute values not allowed
959 for (int i = 0; i < this.values.Length; i++)
961 if (equals(bytes, (sbyte[]) this.values[i]))
963 return ; // Duplicate, don't add
966 System.Object[] tmp = new System.Object[this.values.Length + 1];
967 Array.Copy((System.Array) this.values, 0, (System.Array) tmp, 0, this.values.Length);
968 tmp[this.values.Length] = bytes;
975 /// <summary> Returns true if the two specified arrays of bytes are equal to each
976 /// another. Matches the logic of Arrays.equals which is not available
980 /// <param name="e1">the first array to be tested
982 /// <param name="e2">the second array to be tested
984 /// <returns> true if the two arrays are equal
986 private bool equals(sbyte[] e1, sbyte[] e2)
988 // If same object, they compare true
992 // If either but not both are null, they compare false
993 if (e1 == null || e2 == null)
996 // If arrays have different length, they compare false
997 int length = e1.Length;
998 if (e2.Length != length)
1001 // If any of the bytes are different, they compare false
1002 for (int i = 0; i < length; i++)
1011 /// <summary> Returns a string representation of this LdapAttribute
1014 /// <returns> a string representation of this LdapAttribute
1016 public override System.String ToString()
1018 System.Text.StringBuilder result = new System.Text.StringBuilder("LdapAttribute: ");
1021 result.Append("{type='" + name + "'");
1024 result.Append(", ");
1025 if (values.Length == 1)
1027 result.Append("value='");
1031 result.Append("values='");
1033 for (int i = 0; i < values.Length; i++)
1037 result.Append("','");
1039 if (((sbyte[]) values[i]).Length == 0)
1043 System.Text.Encoding encoder = System.Text.Encoding.GetEncoding("utf-8");
1044 // char[] dchar = encoder.GetChars((byte[]) values[i]);
1045 char[] dchar = encoder.GetChars(SupportClass.ToByteArray((sbyte[])values[i]));
1046 System.String sval = new String(dchar);
1048 // System.String sval = new String((sbyte[]) values[i], "UTF-8");
1049 if (sval.Length == 0)
1051 // didn't decode well, must be binary
1052 result.Append("<binary value, length:" + sval.Length);
1055 result.Append(sval);
1061 catch (System.Exception e)
1063 throw new System.SystemException(e.ToString());
1065 return result.ToString();