LyoqCiAqIEBmaWxlIHByb2ZpbGUuaAogKiBFbmNhcHN1bGF0aW9uIGZvciBzYW1wbGVzIGZpbGVzIG92ZXIgYWxsIHByb2ZpbGUgY2xhc3NlcwogKiBiZWxvbmdpbmcgdG8gdGhlIHNhbWUgYmluYXJ5IGltYWdlCiAqCiAqIEByZW1hcmsgQ29weXJpZ2h0IDIwMDIgT1Byb2ZpbGUgYXV0aG9ycwogKiBAcmVtYXJrIFJlYWQgdGhlIGZpbGUgQ09QWUlORwogKgogKiBAYXV0aG9yIFBoaWxpcHBlIEVsaWUKICogQGF1dGhvciBKb2huIExldm9uCiAqLwoKI2lmbmRlZiBQUk9GSUxFX0gKI2RlZmluZSBQUk9GSUxFX0gKCiNpbmNsdWRlIDxzdHJpbmc+CiNpbmNsdWRlIDxtYXA+CiNpbmNsdWRlIDxpdGVyYXRvcj4KCiNpbmNsdWRlICJvZGIuaCIKI2luY2x1ZGUgIm9wX3R5cGVzLmgiCiNpbmNsdWRlICJ1dGlsaXR5LmgiCiNpbmNsdWRlICJwb3B1bGF0ZV9mb3Jfc3B1LmgiCgpjbGFzcyBvcGRfaGVhZGVyOwpjbGFzcyBvcF9iZmQ7CgovKioKICogQ2xhc3MgY29udGFpbmluZyBhIHNpbmdsZSBzYW1wbGUgZmlsZSBjb250ZW50cy4KICogaS5lLiBzZXQgb2YgY291bnQgdmFsdWVzIGZvciBWTUEgb2Zmc2V0cyBmb3IKICogYSBwYXJ0aWN1bGFyIGJpbmFyeS4KICovCmNsYXNzIHByb2ZpbGVfdCA6IG5vbmNvcHlhYmxlIHsKcHVibGljOgoJLyoqCgkgKiBwcm9maWxlX3QgLSBjb25zdHJ1Y3QgYW4gZW1wdHkgIHByb2ZpbGVfdCBvYmplY3QKCSAqLwoJcHJvZmlsZV90KCk7CgoJLy8vIHJldHVybiB0cnVlIGlmIG5vIHNhbXBsZSBmaWxlIGhhcyBiZWVuIGxvYWRlZAoJYm9vbCBlbXB0eSgpIGNvbnN0IHsgcmV0dXJuICFmaWxlX2hlYWRlci5nZXQoKTsgfQogCgkvLy8gcmV0dXJuIHRoZSBoZWFkZXIgb2YgdGhlIGxhc3Qgb3BlbmVkIHNhbXBsZXMgZmlsZQoJb3BkX2hlYWRlciBjb25zdCAmIGdldF9oZWFkZXIoKSBjb25zdCB7CgkJcmV0dXJuICpmaWxlX2hlYWRlcjsKCX0KCgkvKioKCSAqIGNvdW50IHNhbXBsZXMgY291bnQgdy9vIHJlY29yZGluZyB0aGVtCgkgKiBAcGFyYW0gZmlsZW5hbWUgc2FtcGxlIGZpbGVuYW1lCgkgKgoJICogY29udmVuaWVuY2UgaW50ZXJmYWNlIGZvciByYXcgYWNjZXNzIHRvIHNhbXBsZSBjb3VudCB3L28gcmVjb3JkaW5nCgkgKiB0aGVtLiBJdCdzIHBsYWNlZCBoZXJlIHNvIGFsbCBhY2Nlc3MgdG8gc2FtcGxlcyBmaWxlcyBnbyB0aHJvdWdoCgkgKiBwcm9maWxlX3Qgc3RhdGljIG9yIG5vbiBzdGF0aWMgbWVtYmVyLgoJICovCglzdGF0aWMgY291bnRfdHlwZSBzYW1wbGVfY291bnQoc3RkOjpzdHJpbmcgY29uc3QgJiBmaWxlbmFtZSk7CgoJLyoqCgkgKiBJbmRpY2F0ZSBpZiBnaXZlbiBzYW1wbGUgZmlsZSBpcyBmcm9tIGEgQ2VsbCBCcm9hZGJhbmQgRW5naW5lCgkgKiBTUFUgcHJvZmlsZQoJICogQHBhcmFtIGZpbGVuYW1lIHNhbXBsZSBmaWxlbmFtZQoJICoKCSAqIENvbnZlbmllbmNlIGludGVyZmFjZSBwdXQgaGVyZSBzbyBhbGwgYWNjZXNzIHRvIHNhbXBsZXMgZmlsZXMKCSAqIGdvIHRocm91Z2ggcHJvZmlsZV90IHN0YXRpYyBvciBub24gc3RhdGljIG1lbWJlci4KCSAqLwoJc3RhdGljIGVudW0gcHJvZmlsZV90eXBlIGlzX3NwdV9zYW1wbGVfZmlsZShzdGQ6OnN0cmluZyBjb25zdCAmIGZpbGVuYW1lKTsKCgkvKioKCSAqIGN1bXVsYXRlIHNhbXBsZSBmaWxlIHRvIG91ciBjb250YWluZXIgb2Ygc2FtcGxlcwoJICogQHBhcmFtIGZpbGVuYW1lICBzYW1wbGUgZmlsZSBuYW1lCgkgKgoJICogc3RvcmUgc2FtcGxlcyBmb3Igb25lIHNhbXBsZSBmaWxlLCBzYW1wbGUgZmlsZSBoZWFkZXIgaXMgc2FuaXRpemVkLgoJICoKCSAqIGFsbCBlcnJvciBhcmUgZmF0YWwKCSAqLwoJdm9pZCBhZGRfc2FtcGxlX2ZpbGUoc3RkOjpzdHJpbmcgY29uc3QgJiBmaWxlbmFtZSk7CgoJLy8vIFNldCBhbiBhcHByb3ByaWF0ZSBzdGFydCBvZmZzZXQsIHNlZSBjb21tZW50cyBiZWxvdy4KCXZvaWQgc2V0X29mZnNldChvcF9iZmQgY29uc3QgJiBhYmZkKTsKCXU2NCBnZXRfb2Zmc2V0KHZvaWQpIGNvbnN0IHsgcmV0dXJuIHN0YXJ0X29mZnNldDsgfQoKCWNsYXNzIGNvbnN0X2l0ZXJhdG9yOwoJdHlwZWRlZiBzdGQ6OnBhaXI8Y29uc3RfaXRlcmF0b3IsIGNvbnN0X2l0ZXJhdG9yPiBpdGVyYXRvcl9wYWlyOwoKCS8qKgoJICogQHBhcmFtIHN0YXJ0ICBzdGFydCBvZmZzZXQKCSAqIEBwYXJhbSBlbmQgIGVuZCBvZmZzZXQKCSAqCgkgKiByZXR1cm4gYW4gaXRlcmF0b3IgcGFpciB0byBbc3RhcnQsIGVuZCkgcmFuZ2UKCSAqLwoJaXRlcmF0b3JfcGFpcgoJc2FtcGxlc19yYW5nZShvZGJfa2V5X3Qgc3RhcnQsIG9kYl9rZXlfdCBlbmQpIGNvbnN0OwoKCS8vLyByZXR1cm4gYSBwYWlyIG9mIGl0ZXJhdG9yIGZvciBhbGwgc2FtcGxlcwoJaXRlcmF0b3JfcGFpciBzYW1wbGVzX3JhbmdlKCkgY29uc3Q7Cgpwcml2YXRlOgoJLy8vIGhlbHBlciBmb3Igc2FtcGxlX2NvdW50KCkgYW5kIGFkZF9zYW1wbGVfZmlsZSgpLiBBbGwgZXJyb3IgbGF1bmNoCgkvLy8gYW4gZXhjZXB0aW9uLgoJc3RhdGljIHZvaWQKCW9wZW5fc2FtcGxlX2ZpbGUoc3RkOjpzdHJpbmcgY29uc3QgJiBmaWxlbmFtZSwgb2RiX3QgJik7CgoJLy8vIGNvcHkgb2YgdGhlIHNhbXBsZXMgZmlsZSBoZWFkZXIKCXNjb3BlZF9wdHI8b3BkX2hlYWRlcj4gZmlsZV9oZWFkZXI7CgoJLy8vIHN0b3JhZ2UgdHlwZSBmb3Igc2FtcGxlcyBzb3J0ZWQgYnkgZWlwCgl0eXBlZGVmIHN0ZDo6bWFwPG9kYl9rZXlfdCwgY291bnRfdHlwZT4gb3JkZXJlZF9zYW1wbGVzX3Q7CgoJLyoqCgkgKiBTYW1wbGVzIGFyZSBzdG9yZWQgaW4gaGFzaCB0YWJsZSwgaXRlcmF0aW5nIG92ZXIgaGFzaCB0YWJsZSBkb24ndAoJICogcHJvdmlkZSBhbnkgb3JkZXJpbmcsIHRoZSBhYm92ZSBjb3VudCgpIGludGVyZmFjZSByZWx5IG9uIHNhbXBsZXMKCSAqIG9yZGVyZWQgYnkgZWlwLiBUaGlzIG1hcCBpcyBvbmx5IGEgdGVtcG9yYXJ5IHN0b3JhZ2Ugd2hlcmUgc2FtcGxlcwoJICogYXJlIG9yZGVyZWQgYnkgZWlwLgoJICovCglvcmRlcmVkX3NhbXBsZXNfdCBvcmRlcmVkX3NhbXBsZXM7CgoJLyoqCgkgKiBGb3IgY2VydGFpbiBwcm9maWxlcywgc3VjaCBhcyBrZXJuZWwvbW9kdWxlcywgYW5kIGFub24KCSAqIHJlZ2lvbnMgd2l0aCBhIG1hdGNoaW5nIGJpbmFyeSwgdGhpcyB2YWx1ZSBpcyBub24temVybywKCSAqIGFuZCByZXByZXNlbnRzIHRoZSBmaWxlIG9mZnNldCBvZiB0aGUgcmVsZXZhbnQgc2VjdGlvbi4KCSAqCgkgKiBGb3Iga2VybmVsIHByb2ZpbGVzLCB0aGlzIGlzIGRvbmUgYmVjYXVzZSB3ZSB1c2UgdGhlIGluZm9ybWF0aW9uCgkgKiBwcm92aWRlZCBpbiAvcHJvYy9rc3ltcywgd2hpY2ggb25seSBnaXZlcyB0aGUgbWFwcGVkIHBvc2l0aW9uIG9mCgkgKiAudGV4dCwgYW5kIHRoZSBzeW1ib2wgX3RleHQgZnJvbSB2bWxpbnV4LiBUaGlzIHZhbHVlIGlzIHVzZWQgdG8gZml4CgkgKiB1cCB0aGUgc2FtcGxlIG9mZnNldHMgZm9yIGtlcm5lbCBjb2RlIGFzIGEgcmVzdWx0IG9mIHRoaXMgZGlmZmVyZW5jZQoJICoKCSAqIEluIHVzZXItc3BhY2Ugc2FtcGxlcywgdGhlIHNhbXBsZSBvZmZzZXQgaXMgZnJvbSB0aGUgc3RhcnQgb2YgdGhlCgkgKiBtYXBwZWQgZmlsZSwgYXMgc2VlbiBpbiAvcHJvYy9waWQvbWFwcy4gVGhpcyBpcyBmaW5lIGZvcgoJICogbWFwcGluZ3Mgb2YgcGVybWFuZW50IGZpbGVzLCBidXQgd2l0aCBhbm9uIG1hcHBpbmdzLCB3ZSBuZWVkCgkgKiB0byBhZGp1c3QgdGhlIGtleSB2YWx1ZXMgdG8gYmUgYSBmaWxlIG9mZnNldCBhZ2FpbnN0IHRoZQoJICogKmJpbmFyeSogKGlmIHRoZXJlIGlzIG9uZSkuIFRoaXMgY2FuIG9idmlvdXNseSBiZSBkaWZmZXJlbnQuCgkgKiBTbyB3ZSBwYXNzIG91ciBhbm9uIG1hcHBpbmcgc3RhcnQgVk1BIHRvIG9wX2JmZCwgd2hpY2ggbG9va3MKCSAqIGZvciBhIHNlY3Rpb24gd2l0aCB0aGF0IFZNQSwgdGhlbiByZXR1cm5zIHRoZSBzZWN0aW9uJ3MKCSAqIGZpbGVwb3MuIFNvIGFsbCBpcyBnb29kLgoJICoKCSAqIEZpbmFsbHksIG5vdGUgdGhhdCBmb3IgY2cgd2UgY2FuJ3QgdXNlIHRoaXMgaW5zaWRlIHRoZQoJICogcHJvZmlsZV90LCBhcyB3ZSdyZSBzdG9yaW5nIHR3byBvZmZzZXRzIGluIHRoZSBrZXkgdmFsdWUuIFNvCgkgKiB3ZSBkbyBpdCBsYXRlciBpbiB0aGF0IGNhc2UuCgkgKgoJICogUGhldy4KCSAqLwoJdTY0IHN0YXJ0X29mZnNldDsKfTsKCgovLyBJdCB3aWxsIGJlIGVhc2llciB0byBkZXJpdmUgcHJvZmlsZV90Ojpjb25zdF9pdGVyYXRvciBmcm9tCi8vIHN0ZDo6aXRlcmF0b3I8c3RkOjppbnB1dF9pdGVyYXRvcl90YWcsIHVuc2lnbmVkIGludD4gYnV0IHRoaXMgZG9lc24ndAovLyB3b3JrIGZvciBnY2MgPD0gMi45NSBzbyB3ZSBwcm92aWRlIHRoZSBuZWNjZXNzYXJ5IHR5cGVkZWYgaW4gdGhlIGhhcmQgd2F5LgovLyBTZWUgSVNPIEMrKyAxNy40LjMuMSCnIDEgYW5kIDE0LjcuMyCnIDkuCm5hbWVzcGFjZSBzdGQgewoJdGVtcGxhdGUgPD4KCQlzdHJ1Y3QgaXRlcmF0b3JfdHJhaXRzPHByb2ZpbGVfdDo6Y29uc3RfaXRlcmF0b3I+IHsKCQkJdHlwZWRlZiBwdHJkaWZmX3QgZGlmZmVyZW5jZV90eXBlOwoJCQl0eXBlZGVmIGNvdW50X3R5cGUgdmFsdWVfdHlwZTsKCQkJdHlwZWRlZiBjb3VudF90eXBlICogcG9pbnRlcjsKCQkJdHlwZWRlZiBjb3VudF90eXBlICYgcmVmZXJlbmNlOwoJCQl0eXBlZGVmIGlucHV0X2l0ZXJhdG9yX3RhZyBpdGVyYXRvcl9jYXRlZ29yeTsKCQl9Owp9CgoKY2xhc3MgcHJvZmlsZV90Ojpjb25zdF9pdGVyYXRvcgp7Cgl0eXBlZGVmIG9yZGVyZWRfc2FtcGxlc190Ojpjb25zdF9pdGVyYXRvciBpdGVyYXRvcl90OwpwdWJsaWM6Cgljb25zdF9pdGVyYXRvcigpIDogc3RhcnRfb2Zmc2V0KDApIHt9Cgljb25zdF9pdGVyYXRvcihpdGVyYXRvcl90IGl0XywgdTY0IHN0YXJ0X29mZnNldF8pCgkJOiBpdChpdF8pLCBzdGFydF9vZmZzZXQoc3RhcnRfb2Zmc2V0Xykge30KCgljb3VudF90eXBlIG9wZXJhdG9yKigpIGNvbnN0IHsgcmV0dXJuIGl0LT5zZWNvbmQ7IH0KCWNvbnN0X2l0ZXJhdG9yICYgb3BlcmF0b3IrKygpIHsgKytpdDsgcmV0dXJuICp0aGlzOyB9CgoJb2RiX2tleV90IHZtYSgpIGNvbnN0IHsgcmV0dXJuIGl0LT5maXJzdCArIHN0YXJ0X29mZnNldDsgfQoJY291bnRfdHlwZSBjb3VudCgpIGNvbnN0IHsgcmV0dXJuICoqdGhpczsgfQoKCWJvb2wgb3BlcmF0b3IhPShjb25zdF9pdGVyYXRvciBjb25zdCAmIHJocykgY29uc3QgewoJCXJldHVybiBpdCAhPSByaHMuaXQ7Cgl9Cglib29sIG9wZXJhdG9yPT0oY29uc3RfaXRlcmF0b3IgY29uc3QgJiByaHMpIGNvbnN0IHsKCQlyZXR1cm4gaXQgPT0gcmhzLml0OwoJfQoKcHJpdmF0ZToKCWl0ZXJhdG9yX3QgaXQ7Cgl1NjQgc3RhcnRfb2Zmc2V0Owp9OwoKI2VuZGlmIC8qICFQUk9GSUxFX0ggKi8K