# class ActiveLdap::DistinguishedName::Parser

### Constants

ATTRIBUTE_TYPE_RE
HEX_PAIR
HEX_STRING_RE
PAIR_RE
STRING_CHARS_RE

### Attributes

dn[R]

### Public Class Methods

new(source) click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 11
    def initialize(source)
      @dn = nil
      source = source.to_s if source.is_a?(DN)
      unless source.is_a?(String)
        raise DistinguishedNameInputInvalid.new(source)
      end
      @source = source
    end

### Public Instance Methods

parse() click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 20
    def parse
      return @dn if @dn

      rdns = []
      scanner = StringScanner.new(@source)

      scanner.scan(/\s*/)
      raise rdn_is_missing if scanner.scan(/\s*\+\s*/)
      raise name_component_is_missing if scanner.scan(/\s*,\s*/)

      rdn = {}
      until scanner.eos?
        type = scan_attribute_type(scanner)
        skip_attribute_type_and_value_separator(scanner)
        value = scan_attribute_value(scanner)
        rdn[type] = value
        if scanner.scan(/\s*\+\s*/)
          raise rdn_is_missing if scanner.eos?
        elsif scanner.scan(/\s*\,\s*/)
          rdns << rdn
          rdn = {}
          raise name_component_is_missing if scanner.eos?
        else
          scanner.scan(/\s*/)
          rdns << rdn if scanner.eos?
        end
      end

      @dn = DN.new(*rdns)
      @dn
    end

### Private Instance Methods

attribute_type_is_missing() click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 143
    def attribute_type_is_missing
      invalid_dn(_("attribute type is missing"))
    end

attribute_value_is_missing() click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 147
    def attribute_value_is_missing
      invalid_dn(_("attribute value is missing"))
    end

collect_pairs(scanner) click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 118
    def collect_pairs(scanner)
      result = ""
      while scanner.scan(PAIR_RE)
        if scanner[2]
          result << [scanner[2].hex].pack("C*")
        else
          result << scanner[1]
        end
      end
      result.force_encoding("utf-8") if result.respond_to?(:force_encoding)
      result
    end

found_unmatched_quotation() click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 151
    def found_unmatched_quotation
      invalid_dn(_("found unmatched quotation"))
    end

invalid_dn(reason) click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 131
    def invalid_dn(reason)
      DistinguishedNameInvalid.new(@source, reason)
    end

name_component_is_missing() click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 135
    def name_component_is_missing
      invalid_dn(_("name component is missing"))
    end

rdn_is_missing() click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 139
    def rdn_is_missing
      invalid_dn(_("relative distinguished name (RDN) is missing"))
    end

scan_attribute_type(scanner) click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 54
    def scan_attribute_type(scanner)
      raise attribute_type_is_missing unless scanner.scan(ATTRIBUTE_TYPE_RE)
      scanner[1]
    end

scan_attribute_value(scanner) click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 67
    def scan_attribute_value(scanner)
      if scanner.scan(HEX_STRING_RE)
        value = scanner[1].scan(/../).collect do |hex_pair|
          hex_pair.hex
        end.pack("C*")
      elsif scanner.scan(/\"/)
        value = scan_quoted_attribute_value(scanner)
      else
        value = scan_not_quoted_attribute_value(scanner)
      end
      raise attribute_value_is_missing if value.blank?

      value
    end

scan_not_quoted_attribute_value(scanner) click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 99
    def scan_not_quoted_attribute_value(scanner)
      result = ""
      until scanner.eos?
        prev_size = result.size
        pairs = collect_pairs(scanner)
        strings = scanner.scan(STRING_CHARS_RE)
        result << pairs if !pairs.nil? and !pairs.empty?
        unless strings.nil?
          if scanner.peek(1) == ","
            result << strings.rstrip
          else
            result << strings
          end
        end
        break if prev_size == result.size
      end
      result
    end

scan_quoted_attribute_value(scanner) click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 82
    def scan_quoted_attribute_value(scanner)
      result = ""
      until scanner.scan(/\"/)
        scanner.scan(/([^\\"]*)/)
        quoted_strings = scanner[1]
        pairs = collect_pairs(scanner)

        if scanner.eos? or (quoted_strings.empty? and pairs.empty?)
          raise found_unmatched_quotation
        end

        result << quoted_strings
        result << pairs
      end
      result
    end

skip_attribute_type_and_value_separator(scanner) click to toggle source

    # File lib/active_ldap/distinguished_name.rb, line 59
    def skip_attribute_type_and_value_separator(scanner)
      raise attribute_value_is_missing unless scanner.scan(/\s*=\s*/)
    end