Skip to content

Instantly share code, notes, and snippets.

@stoefln
Created November 25, 2022 09:47
Show Gist options
  • Save stoefln/0ad74e5c69737c21188ff44bf6ebadda to your computer and use it in GitHub Desktop.
Save stoefln/0ad74e5c69737c21188ff44bf6ebadda to your computer and use it in GitHub Desktop.
//...
tryRead = minicapClient => {
this.log('tryRead')
var outgoingImage
for (var chunk; (chunk = minicapClient.read()); ) {
//console.info('chunk(length=%d)', chunk.length)
for (var cursor = 0, len = chunk.length; cursor < len; ) {
if (this.readBannerBytes < this.bannerLength) {
// parse minicap header (no longer used)
switch (this.readBannerBytes) {
case 0: // version
this.banner.version = chunk[cursor]
break
case 1: // length
if (this.banner.version == 2) {
this.bannerLength = 252
while (chunk.length < this.bannerLength) {
var extra = minicapClient.read()
if (!extra) continue
chunk = Buffer.concat([chunk, extra])
len = chunk.length
}
// first byte: version
// second byte-25th byte: machine
this.banner.machine = chunk.toString('utf8', 1, 25).replace(/\0+$/, '')
this.banner.appname = chunk.toString('utf8', 25, 89).replace(/\0+$/, '')
this.banner.appvers = chunk.toString('utf8', 89, 113).replace(/\0+$/, '')
this.banner.hostname = chunk.toString('utf8', 113, 176).replace(/\0+$/, '')
this.banner.scale = chunk.readFloatLE(176)
this.banner.isIpad = chunk.readInt32LE(180)
this.banner.protocolVersion = chunk.readInt32LE(184)
cursor = this.readBannerBytes = this.banner.length = 252
console.debug('header', chunk.length, this.banner)
continue
}
this.banner.length = this.bannerLength = chunk[cursor]
break
}
cursor += 1
this.readBannerBytes += 1
if (this.readBannerBytes === this.bannerLength) {
this.addLineToConnectionLog('banner: \n' + JSON.stringify(this.banner, null, 2))
}
} else if (this.readFrameBytes < 4) {
this.frameBodyLength += (chunk[cursor] << (this.readFrameBytes * 8)) >>> 0
cursor += 1
this.readFrameBytes += 1
//          console.info('headerbyte%d(val=%d)', readFrameBytes, frameBodyLength)
} else if (this.frameBodyLength > 1 << 30) {
// absurd/-ve length interpreted as event coming from device
console.log(`event ${this.frameBodyLength} ${cursor} ${len}`)
var frameSize = 24,
length,
touches = []
do {
while (cursor + frameSize > len) {
var extra = minicapClient.read()
if (!extra) continue
len = chunk.length
}
var frame = chunk.slice(cursor, cursor + frameSize)
touches.push({
timestamp: frame.readDoubleLE(0),
x: frame.readFloatLE(8),
y: frame.readFloatLE(12),
phase: frame.readInt32LE(16)
})
length = frame.readInt32LE(20)
cursor += frameSize
} while (length < -1) // can be muti-touch
console.log('touches: ', touches)
this.frameBodyLength = this.readFrameBytes = 0
this.frameBody = Buffer.alloc(0)
} else {
if (len - cursor >= this.frameBodyLength) {
//console.info('bodyfin(len=%d,cursor=%d)', this.frameBodyLength, cursor)
this.frameBody = Buffer.concat([this.frameBody, chunk.slice(cursor, cursor + this.frameBodyLength)])
outgoingImage = this.frameBody
cursor += this.frameBodyLength
this.frameBodyLength = this.readFrameBytes = 0
this.frameBody = Buffer.alloc(0)
} else {
//console.info('body(len=%d)', len - cursor)
this.frameBody = Buffer.concat([this.frameBody, chunk.slice(cursor, len)])
this.frameBodyLength -= len - cursor
this.readFrameBytes += len - cursor
cursor = len
}
}
}
}
if (outgoingImage) {
console.log('next frame ready: ' + (Date.now() - lastFrameTs) + 'ms')
lastFrameTs = Date.now()
this.publishData(outgoingImage)
}
}
///.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment