| import * as v6 from './constants'; |
| import { sprintf } from 'sprintf-js'; |
| |
| export function groupPossibilities(possibilities: string[]): string { |
| return sprintf('(%s)', possibilities.join('|')); |
| } |
| |
| export function padGroup(group: string): string { |
| if (group.length < 4) { |
| return sprintf('0{0,%d}%s', 4 - group.length, group); |
| } |
| |
| return group; |
| } |
| |
| export const ADDRESS_BOUNDARY = '[^A-Fa-f0-9:]'; |
| |
| export function simpleRegularExpression(groups: string[]) { |
| const zeroIndexes: number[] = []; |
| |
| groups.forEach((group, i) => { |
| const groupInteger = parseInt(group, 16); |
| |
| if (groupInteger === 0) { |
| zeroIndexes.push(i); |
| } |
| }); |
| |
| // You can technically elide a single 0, this creates the regular expressions |
| // to match that eventuality |
| const possibilities = zeroIndexes.map((zeroIndex) => |
| groups |
| .map((group, i) => { |
| if (i === zeroIndex) { |
| const elision = i === 0 || i === v6.GROUPS - 1 ? ':' : ''; |
| |
| return groupPossibilities([padGroup(group), elision]); |
| } |
| |
| return padGroup(group); |
| }) |
| .join(':') |
| ); |
| |
| // The simplest case |
| possibilities.push(groups.map(padGroup).join(':')); |
| |
| return groupPossibilities(possibilities); |
| } |
| |
| export function possibleElisions( |
| elidedGroups: number, |
| moreLeft?: boolean, |
| moreRight?: boolean |
| ): string { |
| const left = moreLeft ? '' : ':'; |
| const right = moreRight ? '' : ':'; |
| |
| const possibilities = []; |
| |
| // 1. elision of everything (::) |
| if (!moreLeft && !moreRight) { |
| possibilities.push('::'); |
| } |
| |
| // 2. complete elision of the middle |
| if (moreLeft && moreRight) { |
| possibilities.push(''); |
| } |
| |
| if ((moreRight && !moreLeft) || (!moreRight && moreLeft)) { |
| // 3. complete elision of one side |
| possibilities.push(':'); |
| } |
| |
| // 4. elision from the left side |
| possibilities.push(sprintf('%s(:0{1,4}){1,%d}', left, elidedGroups - 1)); |
| |
| // 5. elision from the right side |
| possibilities.push(sprintf('(0{1,4}:){1,%d}%s', elidedGroups - 1, right)); |
| |
| // 6. no elision |
| possibilities.push(sprintf('(0{1,4}:){%d}0{1,4}', elidedGroups - 1)); |
| |
| // 7. elision (including sloppy elision) from the middle |
| for (let groups = 1; groups < elidedGroups - 1; groups++) { |
| for (let position = 1; position < elidedGroups - groups; position++) { |
| possibilities.push( |
| sprintf( |
| '(0{1,4}:){%d}:(0{1,4}:){%d}0{1,4}', |
| position, |
| elidedGroups - position - groups - 1 |
| ) |
| ); |
| } |
| } |
| |
| return groupPossibilities(possibilities); |
| } |