All files / lib/deserialize/address ipv6StringFromBuffer.ts

100% Statements 31/31
100% Branches 16/16
100% Functions 4/4
100% Lines 27/27

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67                            1x 15x 15x   15x       15x 15x 15x 120x 120x 120x   15x       120x       15x 15x 15x   120x     96x 12x 12x 6x 12x       84x 7x 7x       77x       15x   15x    
/**
 * Converts a buffer containing an IPv6 address into string notation.
 * String notation consists of 8 sets of 16-bits each. Each group is
 * written as four hexadecimal values separated by colons (:).  This method
 * follows RFC 5952 shortening.
 *
 * @remarks
 * RFC 5952 https://tools.ietf.org/html/rfc5952
 *
 * The following shortening rules are applied:
 *   1. Leading zeros are shorted as much as possible
 *   2. Zero compression is from left to right and
 *   3. Addresses are returned in lowercase.
 */
export function ipv6StringFromBuffer(buffer: Buffer): string {
  const sections = getHexSections(buffer);
  const result = sectionsToString(sections);
 
  return result;
}
 
function getHexSections(buffer: Buffer): string[] {
  const bytesPerSection = 2;
  const sections: string[] = [];
  for (let i = 0; i < buffer.length; i += bytesPerSection) {
    let section = buffer.slice(i, i + bytesPerSection).toString('hex');
    section = discardLeadingZeros(section);
    sections.push(section);
  }
  return sections;
}
 
function discardLeadingZeros(section: string): string {
  return section.replace(/^0+/g, '');
}
 
function sectionsToString(sections: string[]): string {
  let result = '';
  let hasCollapsed = false;
  for (const s of sections) {
    // alrerady in collapse state, no-op
    if (result.endsWith('::') && s === '') continue;
 
    // collapse zero section
    if (s === '' && !hasCollapsed) {
      hasCollapsed = true;
      if (result === '') result += '::';
      else result += ':';
      continue;
    }
 
    // we have a zero, but already collapsed so we need to mark as zero
    if (hasCollapsed && s === '') {
      result += '0:';
      continue;
    }
 
    // normal condition
    result += s + ':';
  }
 
  // remove trailing except with ending with ::;
  if (!result.endsWith('::')) result = result.slice(0, -1);
 
  return result;
}