diff --git a/macho/architecture.test.ts b/macho/architecture.test.ts index c33f499..655f5bf 100644 --- a/macho/architecture.test.ts +++ b/macho/architecture.test.ts @@ -1,4 +1,11 @@ import { assertEquals } from '@std/assert'; +import { + CPU_SUBTYPE_LIB64, + CPU_SUBTYPE_MULTIPLE, + CPU_SUBTYPE_X86_64_H, + CPU_TYPE_I386, + CPU_TYPE_X86_64, +} from '../const.ts'; import { FatArch } from '../mach/fatarch.ts'; import { FatArch64 } from '../mach/fatarch64.ts'; import { Architecture } from './architecture.ts'; @@ -43,3 +50,66 @@ Deno.test('constructor(archInFile: FatArch64)', () => { assertEquals(a.cpuSubType(), 0x456789); assertEquals(a.cpuSubtypeFull(), 0x23456789); }); + +Deno.test('bool', () => { + assertEquals(new Architecture(0, 0).bool(), false); + assertEquals(new Architecture(0, 1).bool(), false); + assertEquals(new Architecture(1, 0).bool(), true); + assertEquals(new Architecture(1, 1).bool(), true); +}); + +Deno.test('equals', () => { + assertEquals(new Architecture(1, 2).equals(new Architecture(1, 2)), true); + assertEquals(new Architecture(1, 2).equals(new Architecture(1, 3)), false); + assertEquals(new Architecture(2, 2).equals(new Architecture(1, 2)), false); +}); + +Deno.test('lessThan', () => { + assertEquals( + new Architecture(1, 2).lessThan(new Architecture(2, 2)), + true, + ); + assertEquals( + new Architecture(1, 2).lessThan(new Architecture(1, 3)), + true, + ); + assertEquals( + new Architecture(1, 2).lessThan(new Architecture(1, 2)), + false, + ); + assertEquals( + new Architecture(2, 2).lessThan(new Architecture(1, 2)), + false, + ); + assertEquals( + new Architecture(1, 2).lessThan(new Architecture(1, 2)), + false, + ); +}); + +Deno.test('matches', () => { + { + const arch = new Architecture(CPU_TYPE_X86_64, CPU_SUBTYPE_MULTIPLE); + const tmpl = new Architecture(CPU_TYPE_I386, CPU_SUBTYPE_MULTIPLE); + assertEquals(arch.matches(tmpl), false); + } + { + const arch = new Architecture(CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_H); + const tmpl = new Architecture(CPU_TYPE_X86_64, CPU_SUBTYPE_MULTIPLE); + assertEquals(arch.matches(tmpl), true); + + // Not symmetric. + assertEquals(tmpl.matches(arch), false); + } + { + const arch = new Architecture( + CPU_TYPE_X86_64, + CPU_SUBTYPE_X86_64_H | CPU_SUBTYPE_LIB64, + ); + const tmpl = new Architecture( + CPU_TYPE_X86_64, + CPU_SUBTYPE_X86_64_H, + ); + assertEquals(arch.matches(tmpl), true); + } +}); diff --git a/macho/architecture.ts b/macho/architecture.ts index abccac6..d7adfe4 100644 --- a/macho/architecture.ts +++ b/macho/architecture.ts @@ -87,4 +87,51 @@ export class Architecture { public cpuSubtypeFull(): number { return this.second; } + + /** + * Is architecture valid. + * + * @returns Is valid. + */ + public bool(): boolean { + return !!this.first; + } + + /** + * If architectures are equal. + * + * @param arch Architecture to compare. + * @returns Is equal. + */ + public equals(arch: Const): boolean { + return this.first === arch.first && this.second === arch.second; + } + + /** + * If architecture is less than another. + * + * @param arch Architecture to compare. + * @returns Is less than. + */ + public lessThan(arch: Const): boolean { + const x = this.first; + const y = arch.first; + return x < y || (!(y < x) && this.second < arch.second); + } + + /** + * Check is architecture matches template, asymmetric comparison. + * + * @param templ Template architecture. + * @returns Matches template. + */ + public matches(templ: Const): boolean { + if (this.first !== templ.first) { + return false; + } + if (templ.second === CPU_SUBTYPE_MULTIPLE) { + return true; + } + return !((this.second ^ templ.second) & ~CPU_SUBTYPE_MASK); + } }