jspurefix
Version:
pure node js fix engine
194 lines (170 loc) • 6.08 kB
text/typescript
import { SimpleFieldDefinition } from '../../dictionary/definition'
import { SegmentDescription } from '../segment-description'
import { Structure } from '../structure'
import { TagType } from '../tags'
import { MsgView } from '../msg-view'
import { ElasticBuffer } from '../elastic-buffer'
import { ITimeFormatter } from '../time-formatter'
import { TimeFormatter } from './time-formatter'
import { TagPos } from '../tag-pos'
import { MsgTag } from '../../types/enum'
export class AsciiView extends MsgView {
private readonly timeFormatter: ITimeFormatter = new TimeFormatter(this.buffer)
constructor (public readonly segment: SegmentDescription,
public readonly buffer: ElasticBuffer,
public readonly structure: Structure,
public readonly ptr: number,
public readonly delimiter: number,
public readonly writeDelimiter: number) {
super(segment, structure)
}
// if the view is to be kept beyond the event on which it arrives, must be cloned
public clone (): MsgView {
const structure = this.structure
const buffer = this.buffer.clone()
const segment = this.segment
const delimiter = this.delimiter
const writeDelimiter = this.writeDelimiter
if (structure) {
return new AsciiView(segment, buffer, new Structure(structure.tags.clone(), structure.segments), this.ptr, delimiter, writeDelimiter)
}
return new AsciiView(segment, buffer, null, this.ptr, delimiter, writeDelimiter)
}
public checksum (): number {
const t = this.getPosition(MsgTag.CheckSum)
const structure = this.structure
const prev = structure.tags.tagPos[t - 1]
const tp = prev.start + prev.len + 1
let cs = this.buffer.sum(tp)
const delimiter = this.delimiter
const writeDelimiter = this.writeDelimiter
if (writeDelimiter !== delimiter) {
const changes = structure.tags.nextTagPos - 1
cs -= changes * writeDelimiter
cs += changes * delimiter
}
return cs % 256
}
protected toTyped (field: SimpleFieldDefinition): any {
const position: number = this.getPosition(field.tag)
if (position >= 0) {
switch (field.tagType) {
case TagType.String : {
return this.stringAtPosition(position)
}
case TagType.Float: {
return this.getNumber(position, true)
}
case TagType.Int:
case TagType.Length: {
return this.getNumber(position)
}
case TagType.Boolean: {
return this.getBoolean(field.tag)
}
case TagType.UtcTimestamp: {
return this.getDateTime(field.tag, true)
}
case TagType.UtcTimeOnly: {
return this.getTime(field.tag, true)
}
case TagType.UtcDateOnly: {
return this.getDate(field.tag, true)
}
case TagType.LocalDate: {
return this.getDate(field.tag, false)
}
case TagType.RawData: {
return this.getBuffer(position)
}
default: {
return this.stringAtPosition(position)
}
}
}
}
protected create (singleton: SegmentDescription): MsgView {
return new AsciiView(singleton,
this.buffer,
this.structure,
this.ptr,
this.delimiter,
this.writeDelimiter)
}
protected stringAtPosition (position: number): string {
const tags = this.structure.tags
if (position < 0 || position >= tags.nextTagPos) {
return null
}
const tag: TagPos = tags.tagPos[position]
return this.buffer.getString(tag.start, tag.start + tag.len)
}
private getBuffer (position: number): Buffer {
const tag: TagPos = this.structure.tags.tagPos[position]
return this.buffer.getBuffer(tag.start, tag.start + tag.len)
}
private getNumber (position: number, isFloat: boolean = false): number {
const buffer = this.buffer
const tag: TagPos = this.structure.tags.tagPos[position]
if (isFloat) {
return buffer.getFloat(tag.start, tag.start + tag.len - 1)
} else {
return buffer.getWholeNumber(tag.start, tag.start + tag.len - 1)
}
}
private getTime (tag: number, useUtc: boolean): Date {
const formatter = this.timeFormatter
const position: number = this.getPosition(tag)
const tagPos: TagPos = this.structure.tags.tagPos[position]
if (position < 0) {
return null
}
if (useUtc) {
return formatter.getUtcTime(tagPos.start)
} else {
return formatter.getLocalTime(tagPos.start)
}
}
private getDate (tag: number, useUtc: boolean): Date {
const formatter = this.timeFormatter
const position: number = this.getPosition(tag)
if (position < 0) {
return null
}
const tagPos: TagPos = this.structure.tags.tagPos[position]
// (SendingTime) = 20150417-01:00:08.201
if (tagPos.len < 8) {
return null
}
if (useUtc) {
return formatter.getUtcDate(tagPos.start)
} else {
return formatter.getLocalDate(tagPos.start)
}
}
private getDateTime (tag: number, useUtc: boolean): Date {
const position: number = this.getPosition(tag)
const tagPos: TagPos = this.structure.tags.tagPos[position]
const formatter = this.timeFormatter
if (position < 0) {
return null
}
// (SendingTime) = 20150417-01:00:08.201
if (tagPos.len < 8) {
return null
}
if (useUtc) {
return formatter.getUtcTimestamp(tagPos.start, tagPos.start + tagPos.len)
} else {
return formatter.getLocalTimestamp(tagPos.start, tagPos.start + tagPos.len)
}
}
private getBoolean (tag: number): boolean {
const position: number = this.getPosition(tag)
if (position < 0) {
return null
}
const tagPos: TagPos = this.structure.tags.tagPos[position]
return this.buffer.getBoolean(tagPos.start)
}
}