jspurefix
Version:
pure node js fix engine
146 lines (136 loc) • 5.12 kB
text/typescript
import { INumericKeyed } from '../../collections/collection'
import { ContainedField } from './contained-field'
import { ContainedSimpleField } from './contained-simple-field'
import { ElasticBuffer } from '../../buffer/elastic-buffer'
import { ContainedSetType } from '../contained-set-type'
import { IContainedSet } from './contained-set'
export abstract class ContainedFieldSet implements IContainedSet {
/**
* index of name to any group that may be present within the field list
*/
public readonly groups: Map<string, IContainedSet> = new Map<string, IContainedSet>()
/**
* index of name to any component that may be present within the field list
*/
public readonly components: Map<string, IContainedSet> = new Map<string, IContainedSet>()
/**
* index of name to any simple field that may be present within the field list
*/
public readonly simple: Map<string, ContainedSimpleField> = new Map<string, ContainedSimpleField>()
/**
* sequence of fields representing this type - can be simple, group or component
*/
public readonly fields: ContainedField[] = []
/**
* any tag at any level i.e. does this set contain a tag
*/
public readonly containedTag: INumericKeyed<boolean> = {}
/**
* any tag at any level ordered i.e. all tags flattened to list
*/
public readonly flattenedTag: number[] = []
/**
* any data tags contained length within this set.
*/
public readonly containedLength: INumericKeyed<boolean> = {}
/**
* tags only in repository at this level, not from any at deeper levels
*/
public readonly localTag: INumericKeyed<ContainedSimpleField> = {}
/**
* tags marked required at this level only
*/
public readonly localRequired: INumericKeyed<ContainedSimpleField> = {}
/**
* all tags contained within this field set flattened from all levels
*/
public readonly tagToSimple: INumericKeyed<ContainedSimpleField> = {}
/**
* direct any tag contained within this set to field one level down where it belongs.
*/
public readonly tagToField: INumericKeyed<ContainedField> = {}
/**
* only repository directly in this set indexed by name
*/
public readonly localNameToField: Map<string, ContainedField> = new Map<string, ContainedField>()
/**
* for FixMl notation this set of fields appear as attributes i.e. <Pty ID="323" R="38">
*/
public readonly nameToLocalAttribute: Map<string, ContainedSimpleField> = new Map<string, ContainedSimpleField>()
/**
* all attributes in order of being declared
*/
public readonly localAttribute: ContainedSimpleField[] = []
/**
* at any level on this set, first declared simple field
*/
public firstSimple: (ContainedSimpleField | null)
/**
* parser needs to know about raw fields, any present in this set?
*/
public containsRaw: boolean = false
protected constructor (public readonly type: ContainedSetType,
public readonly name: string,
public readonly category: string | null,
public readonly abbreviation: string | null,
public readonly description: string | null) {
}
/**
* not for generral usage, this partially resets the set such it can be used on a second
* pass of the xml parser
*/
public reset (): void {
this.groups.clear()
this.components.clear()
this.simple.clear()
this.empty(this.fields)
this.empty(this.flattenedTag)
this.empty(this.localAttribute)
this.localNameToField.clear()
}
private empty<T> (arr: T[]): void {
while (arr.length > 0) {
arr.pop()
}
}
public toString (): string {
const buffer = new ElasticBuffer(2 * 1024)
const fields = this.fields
buffer.writeString(`Set: ${this.name}(${this.getPrefix()}) fields [${fields.length}]: `)
const set: string[] = fields.map((f: ContainedField) => f.toString())
const s = set.join(', ')
buffer.writeString(s)
return buffer.toString()
}
public abstract getPrefix (): string
public keys (): number[] {
const keys: string[] = Object.keys(this.containedTag)
const nums: number[] = new Array(keys.length)
for (let j: number = 0; j < keys.length; ++j) {
nums[j] = parseInt(keys[j], 10)
}
return nums
}
public getFieldName (tag: number): string {
const s = this.tagToSimple[tag]
if (s == null) {
const gf: ContainedField = this.tagToField[tag]
if (gf !== null) {
return `${gf.name}`
}
return `${tag}`
}
return s.name
}
/**
* recurses down a path to return nested set definitiom of a group or component
* given in dot notation 'SecListGrp.NoRelatedSym.SecurityTradingRules.BaseTradingRules'
* @param path in dot notation
*/
public getSet (path: string): (IContainedSet | null) {
if (!path) return null
return path.split('.').reduce((set: IContainedSet, next: string): (IContainedSet | null) => {
return set.groups.get(next) ?? set.components.get(next) ?? null
}, this)
}
}