LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgImV4dHJhY2h1bmsuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKiByZWFkcyBhIGNodW5rIG91dG9mIHRoZSBleHRyYWNodW5rLXN0cnVjdHVyZSAqLwpIUkVTVUxUIFJlYWRFeHRyYUNodW5rKExQRVhUUkFDSFVOS1MgZXh0cmEsRk9VUkNDIGNraWQsTFBWT0lEIGxwRGF0YSwKCQkgICAgICAgTFBMT05HIHNpemUpCnsKICBMUEJZVEUgbHA7CiAgRFdPUkQgIGNiOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChleHRyYSAhPSBOVUxMKTsKICBhc3NlcnQoc2l6ZSAhPSBOVUxMKTsKCiAgbHAgPSBleHRyYS0+bHA7CiAgY2IgPSBleHRyYS0+Y2I7CgogIGlmIChscCAhPSBOVUxMKSB7CiAgICB3aGlsZSAoY2IgPiAwKSB7CiAgICAgIGlmICgoKEZPVVJDQyopbHApWzBdID09IGNraWQpIHsKCS8qIGZvdW5kIGNvcnJlY3QgY2h1bmsgKi8KCWlmIChscERhdGEgIT0gTlVMTCAmJiAqc2l6ZSA+IDApCgkgIG1lbWNweShscERhdGEsIGxwICsgMiAqIHNpemVvZihEV09SRCksCgkJIG1pbigoKExQRFdPUkQpbHApWzFdLCAqKExQRFdPUkQpc2l6ZSkpOwoKCSooTFBEV09SRClzaXplID0gKChMUERXT1JEKWxwKVsxXTsKCglyZXR1cm4gQVZJRVJSX09LOwogICAgICB9IGVsc2UgewoJLyogc2tpcCB0byBuZXh0IGNodW5rICovCgljYiAtPSAoKExQRFdPUkQpbHApWzFdICsgMiAqIHNpemVvZihEV09SRCk7CglscCArPSAoKExQRFdPUkQpbHApWzFdICsgMiAqIHNpemVvZihEV09SRCk7CiAgICAgIH0KICAgIH0KICB9CgogIC8qIHdhbnRlZCBjaHVuayBkb2Vzbid0IGV4aXN0ICovCiAgKnNpemUgPSAwOwoKICByZXR1cm4gQVZJRVJSX05PREFUQTsKfQoKLyogd3JpdGVzIGEgY2h1bmsgaW50byB0aGUgZXh0cmFjaHVuay1zdHJ1Y3R1cmUgKi8KSFJFU1VMVCBXcml0ZUV4dHJhQ2h1bmsoTFBFWFRSQUNIVU5LUyBleHRyYSxGT1VSQ0MgY2tpZCxMUFZPSUQgbHBEYXRhLAoJCQlMT05HIHNpemUpCnsKICBMUERXT1JEIGxwOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChleHRyYSAhPSBOVUxMKTsKICBhc3NlcnQobHBEYXRhICE9IE5VTEwpOwogIGFzc2VydChzaXplID4gMCk7CgogIGlmIChleHRyYS0+bHApCiAgICBscCA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGV4dHJhLT5scCwgZXh0cmEtPmNiICsgc2l6ZSArIDIgKiBzaXplb2YoRFdPUkQpKTsKICBlbHNlCiAgICBscCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplICsgMiAqIHNpemVvZihEV09SRCkpOwoKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBleHRyYS0+bHAgID0gbHA7CiAgbHAgPSAoTFBEV09SRCkgKChMUEJZVEUpbHAgKyBleHRyYS0+Y2IpOwogIGV4dHJhLT5jYiArPSBzaXplICsgMiAqIHNpemVvZihEV09SRCk7CgogIC8qIGluc2VydCBjaHVuay1oZWFkZXIgaW4gYmxvY2sgKi8KICBscFswXSA9IGNraWQ7CiAgbHBbMV0gPSBzaXplOwoKICBpZiAobHBEYXRhICE9IE5VTEwgJiYgc2l6ZSA+IDApCiAgICBtZW1jcHkobHAgKyAyLCBscERhdGEsIHNpemUpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKiByZWFkcyBhIGNodW5rIGZvbXIgdGhlIEhNTUlPIGludG8gdGhlIGV4dHJhY2h1bmstc3RydWN0dXJlICovCkhSRVNVTFQgUmVhZENodW5rSW50b0V4dHJhKExQRVhUUkFDSFVOS1MgZXh0cmEsSE1NSU8gaG1taW8sTU1DS0lORk8gKmxwY2spCnsKICBMUERXT1JEIGxwOwogIERXT1JEICAgY2I7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KGV4dHJhICE9IE5VTEwpOwogIGFzc2VydChobW1pbyAhPSBOVUxMKTsKICBhc3NlcnQobHBjayAgIT0gTlVMTCk7CgogIGNiICA9IGxwY2stPmNrc2l6ZSArIDIgKiBzaXplb2YoRFdPUkQpOwogIGNiICs9IChjYiAmIDEpOwoKICBpZiAoZXh0cmEtPmxwICE9IE5VTEwpCiAgICBscCA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGV4dHJhLT5scCwgZXh0cmEtPmNiICsgY2IpOwogIGVsc2UKICAgIGxwID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGNiKTsKCiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgZXh0cmEtPmxwICA9IGxwOwogIGxwID0gKExQRFdPUkQpICgoTFBCWVRFKWxwICsgZXh0cmEtPmNiKTsKICBleHRyYS0+Y2IgKz0gY2I7CgogIC8qIGluc2VydCBjaHVuay1oZWFkZXIgaW4gYmxvY2sgKi8KICBscFswXSA9IGxwY2stPmNraWQ7CiAgbHBbMV0gPSBscGNrLT5ja3NpemU7CgogIGlmIChscGNrLT5ja3NpemUgPiAwKSB7CiAgICBpZiAobW1pb1NlZWsoaG1taW8sIGxwY2stPmR3RGF0YU9mZnNldCwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgaWYgKG1taW9SZWFkKGhtbWlvLCAoSFBTVFIpJmxwWzJdLCBscGNrLT5ja3NpemUpICE9IChMT05HKWxwY2stPmNrc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qIHJlYWRzIGFsbCBub24tanVuayBjaHVua3MgaW50byB0aGUgZXh0cmFjaHVuay1zdHJ1Y3R1cmUgdW50aWwgaXQgZmluZHMKICogdGhlIGdpdmVuIGNodW5rIG9yIHRoZSBvcHRpb25hbCBwYXJlbnQtY2h1bmsgaXMgYXQgdGhlIGVuZCAqLwpIUkVTVUxUIEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoTFBFWFRSQUNIVU5LUyBleHRyYSxITU1JTyBobW1pbyxNTUNLSU5GTyAqbHBjaywKCQkJICAgICAgIE1NQ0tJTkZPICpscGNrUGFyZW50LFVJTlQgZmxhZ3MpCnsKICBGT1VSQ0MgIGNraWQ7CiAgRk9VUkNDICBmY2NUeXBlOwogIEhSRVNVTFQgaHI7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KGV4dHJhICE9IE5VTEwpOwogIGFzc2VydChobW1pbyAhPSBOVUxMKTsKICBhc3NlcnQobHBjayAgIT0gTlVMTCk7CgogIFRSQUNFKCIoeyVwLCVsdX0sJXAsJXAsJXAsMHglWClcbiIsIGV4dHJhLT5scCwgZXh0cmEtPmNiLCBobW1pbywgbHBjaywKCWxwY2tQYXJlbnQsIGZsYWdzKTsKCiAgLyogd2hhdCBjaHVuayBpZCBhbmQgZm9ybS9saXN0IHR5cGUgc2hvdWxkIHdlIHNlYXJjaD8gKi8KICBpZiAoZmxhZ3MgJiBNTUlPX0ZJTkRDSFVOSykgewogICAgY2tpZCAgICA9IGxwY2stPmNraWQ7CiAgICBmY2NUeXBlID0gMDsKICB9IGVsc2UgaWYgKGZsYWdzICYgTU1JT19GSU5ETElTVCkgewogICAgY2tpZCAgICA9IEZPVVJDQ19MSVNUOwogICAgZmNjVHlwZSA9IGxwY2stPmZjY1R5cGU7CiAgfSBlbHNlIGlmIChmbGFncyAmIE1NSU9fRklORFJJRkYpIHsKICAgIGNraWQgICAgPSBGT1VSQ0NfUklGRjsKICAgIGZjY1R5cGUgPSBscGNrLT5mY2NUeXBlOwogIH0gZWxzZQogICAgY2tpZCA9IGZjY1R5cGUgPSAoRk9VUkNDKS0xOyAvKiBjb2xsZWN0IGV2ZXJ5dGhpbmcgaW50byBleHRyYSEgKi8KCiAgVFJBQ0UoIjogZmluZCBja2lkPTB4JTA4bFggZmNjVHlwZT0weCUwOGxYXG4iLCBja2lkLCBmY2NUeXBlKTsKCiAgZm9yICg7OykgewogICAgaHIgPSBtbWlvRGVzY2VuZChobW1pbywgbHBjaywgbHBja1BhcmVudCwgMCk7CiAgICBpZiAoaHIgIT0gU19PSykgewogICAgICAvKiBObyBleHRyYSBjaHVua3MgaW4gZnJvbnQgb2YgZGVzaXJlZCBjaHVuaz8gKi8KICAgICAgaWYgKGZsYWdzID09IDAgJiYgaHIgPT0gTU1JT0VSUl9DSFVOS05PVEZPVU5EKQoJaHIgPSBBVklFUlJfT0s7CiAgICAgIHJldHVybiBocjsKICAgIH0KCiAgICAvKiBIYXZlIHdlIGZvdW5kIHdoYXQgd2Ugc2VhcmNoIGZvcj8gKi8KICAgIGlmICgobHBjay0+Y2tpZCA9PSBja2lkKSAmJgoJKGZjY1R5cGUgPT0gKEZPVVJDQykwIHx8IGxwY2stPmZjY1R5cGUgPT0gZmNjVHlwZSkpCiAgICAgIHJldHVybiBBVklFUlJfT0s7CgogICAgLyogU2tpcCBwYWRkaW5nIGNodW5rcywgdGhlIG90aGVycyBwdXQgaW50byB0aGUgZXh0cmFjaHVuay1zdHJ1Y3R1cmUgKi8KICAgIGlmIChscGNrLT5ja2lkID09IGNraWRBVklQQURESU5HIHx8CglscGNrLT5ja2lkID09IG1taW9GT1VSQ0MoJ3AnLCdhJywnZCcsJ2QnKSkKICAgICAgaHIgPSBtbWlvQXNjZW5kKGhtbWlvLCBscGNrLCAwKTsKICAgIGVsc2UKICAgICAgaHIgPSBSZWFkQ2h1bmtJbnRvRXh0cmEoZXh0cmEsIGhtbWlvLCBscGNrKTsKICAgIGlmIChGQUlMRUQoaHIpKQogICAgICByZXR1cm4gaHI7CiAgfQp9Cg==