go-lib-5.6.0.9/000775 000000 000000 00000000000 13753517240 013031 5ustar00rootroot000000 000000 go-lib-5.6.0.9/.gitignore000664 000000 000000 00000000142 13753517240 015016 0ustar00rootroot000000 000000 */*.test _tmp graphic/testdata/test_* gdkpixbuf/testdata/test* *.bak _* !dbusutil/_tool **/*.test go-lib-5.6.0.9/.gitlab-ci.yml000664 000000 000000 00000000213 13753517240 015461 0ustar00rootroot000000 000000 include: - remote: 'https://gitlab.deepin.io/dev-tools/letmeci/raw/master/gitlab-ci/dde.yml' variables: CPPCHECK_DISABLED: "true" go-lib-5.6.0.9/.mailmap000664 000000 000000 00000000042 13753517240 014446 0ustar00rootroot000000 000000 Xu Fasheng go-lib-5.6.0.9/CHANGELOG.md000664 000000 000000 00000014312 13753517240 014643 0ustar00rootroot000000 000000 [1.10.2] 2019-04-08 * feat(desktopappinfo): do not process X-Deepin-Vendor field [1.10.1] 2019-04-03 * fix: build failed * chore(desktopappinfo): remove redundant println [1.10.0] 2019-03-15 * fix(asound): SelemHasCaptureSwitchJoined wrong * change(api): asound add more functions * fix(dbusutil): proxy.Object removeHandler not work if ruleAuto is false [1.9.2] 2019-03-01 * chore(dbusutil): RemoveHandler check signal ext * chore: use pkg.deepin.io/gir [1.9.1] 2019-02-25 * fix(proxy): abnormally clear env vars when modifying config [1.9.0] 2019-02-22 * refactor: fix a typo * change(api): appinfo AppLaunchContext add method SetCmdSuffixes * fix(desktpappinfo): failed to parse Exec field of wine programs desktop files ## [1.8.0] 2019-01-03 * chore: use dh golang build system on `sw_64` * feat(dbusutil): gsprop.Enum add methods GetString and SetString * fix(dbus): failed to find session bus address in systemd 240+ ## [1.7.0] 2018-12-29 * chore(`sound_effect`): player add method Finder ## [1.6.0] 2018-12-10 * fix(dbus1): defaultSignalHandler.DeliverSignal ## [1.5.0] 2018-12-07 * chore(dbus1): skip test transport nonce tcp * chore(dbus1): update to the latest upstream code * feat(imgutil): add method CanDecodeConfig * feat: add lib imgutil ## [1.4.0] 2018-11-23 * feat(desktopappinfo): support key X-Deepin-Vendor ## [1.3.0] 2018-10-25 * fix(dbusutil): gsprop nil pointer panic * feat: add lib shell * chore(gettext): do not run test * fix: make install lost a file * chore: add makefile for `sw_64` ## [1.2.16] 2018-08-07 * feat(sound-effect): check theme and event validity ## [1.2.15] 2018-07-31 * fix(desktopappinfo): expandFieldCode ## [1.2.14] 2018-07-20 * chore(proxy): defer proxySettings init ## [1.2.13] 2018-07-19 * fix: test failed ## [1.2.12] 2018-07-19 * chore(dbusutil): gsprop add mutex prevent data race * chore(dbus1): update to the latest upstream code * chore(dbusutil): request name error include name * chore: remove polkit * chore(gdkpixbuf): use go-x11-client * fix: play wav file with pulseaudio get error * chore(debian): update debian control * chore(appinfo): use go-x11-client * feat(audio): improve event handling ## [1.2.11] 2018-06-07 * fix(pulse): no subscribe server event * fix(pulse): Context data race * fix(dbus1): exportedObj data race * refactor(pulse): Context add some methods ## [1.2.10] 2018-05-23 * chore: update dbus1 ## [1.2.9] - 2018-05-15 * fix(pulse): event error should handle in go space * perf(pulse): avoid wasting CPU time to poll connect state ## [1.2.8] - 2018-05-14 * feat(dbusutil): dbusutil-gen add do not edit header * fix(pam): cbPAMConv return two values * fix(dbus1): test failed * fix(dbusutil): failed to set property of object * refactor(pulse): ignore pulseaudio's strange behavior * fix(pulse): memory leak about pa_operation * perf(pulse): remove useless memcpy * fix(pulse): unity all mainloop_lock to safeDo * fix(pulse): deadlock on pendingCallback * fix(pulse): block on ck.Feed * refactor(pulse): print info about failed pulse operation * fix(pulse): too early free C.String * refactor(pulse): erase magic number about PA init State * refactor(pulse): move all pa_threaded_mainloop_lock to one file * fix(pulse): move all callback out of mainloop thread ## [1.2.7] - 2018-04-17 * fix(desktopappinfo): incorrect use of os.Chdir to set working directory of cmd * fix(sound_effect): fix alsa backend play failed * chore(debian): add dependency on libpam0g-dev * feat(pam): add lib pam * Merge "feat(dbusutil): proxy.Object can choose not to use auto rule" * feat(dbusutil): proxy.Object can choose not to use auto rule * fix(pulse): protect pa_stream * fix(pulse): protect sink_suspend and meter * fix(pulse): protect pa_context_unref * feat(dbusutil): add support for auto generate code ## [1.2.6] - 2018-03-19 * perf: unref the `pa_operation` in macro "DEFINE" * feat: dbusutil/gsprop add Uint64 type * fix(pulse): data race on pulse.Context.free * refactor(pulse): hold lock when starting mainloop * feat(dbusutil): new api * refactor(pulse): remove global variable of `pa_threaded_mainloop` * refactor(pulse): hide internal functions ## [1.2.5] - 2018-03-07 * feat(dbusutil): hide log output * feat(dbusutil): allow field type pointer implements the Property interface * feat(dbusutil): delay emit property changed * doc: add document about dbusutil * feat(dbusutil): improves object introspection * fix(dbusutil): PropsMaster Begin and End * fix(dbusutil): no check impl is nil * feat(dbusutil): add PropsMaster * fix(dbusutil): method RequestName panic * feat(dbusutil) add method NameHasOwenr and GetNameOwner * fix(dbusutil/gsprop): use path property to connect changed * fix(dbusutil): auto quit * fix(dbusutil): ToError panic if param err is nil * feat: add lib dbusutil * fix(encoding/kv): constants value wrong * refactor: reduce global `success_cb` variable * fix: protect global variable "sourceMeterCBs" * chore: update license * feat: lib dbus/property and proxy use new lib gsettings * feat: add lib gsettings * fix(dbus1): test SystemBus failed in build env * add lib dbus1 ## [1.2.4] - 2018-01-24 * fix Adapt lintian * asound: add more types and functions * `sound_effect`: fix alsa play backend HWParams wrong * notify: fix notification Update and Show * `sound_effect`: fix can not compile with go 1.4 * dbus: fix SetAutoDestroyHandler * add lib cgroup * pulse/simple: fix wrong error handling * appinfo: do not call GetStartupNotifyId if timestamp is 0 ## [1.2.3] - 2017-12-13 * add some audio libs * fix package golang-dlib-dev depends wrong * fix: race condition on HasNewMessage * asound: add method SetRateNear and GetDeviceNameHints ## [1.2.2] - 2017-11-28 + fix concurrent access dbus PropertyProxy + add StartCommand method for DestkopAppInfo and DesktopAction ## [1.2.1] - 2017-11-16 + add field Section for DesktopAction + add SetDataDirs in desktopappinfo ## [1.2.0] - 2017-10-12 ### Added + add pulse init timeout ### Changed + update license + replace syscall 'statfs' with 'statvfs' + make transport endian aware ### Fixed + fix dbus introspection map concurrency go-lib-5.6.0.9/LICENSE000664 000000 000000 00000104513 13753517240 014042 0ustar00rootroot000000 000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . go-lib-5.6.0.9/Makefile000664 000000 000000 00000000645 13753517240 014476 0ustar00rootroot000000 000000 GOPATH_DIR = gopath GOPKG_PREFIX = pkg.deepin.io/lib prepare: @if [ ! -d ${GOPATH_DIR}/src/${GOPKG_PREFIX} ]; then \ mkdir -p ${GOPATH_DIR}/src/$(dir ${GOPKG_PREFIX}); \ ln -sf ../../.. ${GOPATH_DIR}/src/${GOPKG_PREFIX}; \ fi print_gopath: prepare GOPATH="${CURDIR}/${GOPATH_DIR}:${GOPATH}" clean: rm -rf ${GOPATH_DIR} check_code_quality: prepare env GOPATH="${CURDIR}/${GOPATH_DIR}:${GOPATH}" go vet ./... go-lib-5.6.0.9/README.md000664 000000 000000 00000002256 13753517240 014315 0ustar00rootroot000000 000000 ## Deepin GoLang Library Deepin GoLang Library is a library containing many useful go routines for things such as glib, gettext, archive, graphic,etc. ## Dependencies ### Build dependencies * gio-2.0 * glib-2.0 * x11 * gdk-pixbuf-2.0 * libpulse * mobile-broadband-provider-info ## Installation Install prerequisites ``` $ go get github.com/smartystreets/goconvey $ go get github.com/howeyc/fsnotify $ go get gopkg.in/check.v1 $ go get github.com/linuxdeepin/go-x11-client ``` Install ``` mkdir -p $GOPATH/src/pkg.deepin.io cp -r go-lib $GOPATH/src/pkg.deepin.io/lib ``` ## Getting help Any usage issues can ask for help via * [Gitter](https://gitter.im/orgs/linuxdeepin/rooms) * [IRC channel](https://webchat.freenode.net/?channels=deepin) * [Forum](https://bbs.deepin.org/) * [WiKi](http://wiki.deepin.org/) ## Getting involved We encourage you to report issues and contribute changes. * [Contribution guide for users](http://wiki.deepin.org/index.php?title=Contribution_Guidelines_for_Users) * [Contribution guide for developers](http://wiki.deepin.org/index.php?title=Contribution_Guidelines_for_Developers) ## License Deepin GoLang Library is licensed under [GPLv3](LICENSE). go-lib-5.6.0.9/TODO000664 000000 000000 00000000102 13753517240 013512 0ustar00rootroot000000 000000 [ ] compact utils directory, separate it into different packages. go-lib-5.6.0.9/app/000775 000000 000000 00000000000 13753517240 013611 5ustar00rootroot000000 000000 go-lib-5.6.0.9/app/app.go000664 000000 000000 00000010546 13753517240 014726 0ustar00rootroot000000 000000 /* * Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // app provide a convenient application structure with commandline and profile features. package app import ( "fmt" "gopkg.in/alecthomas/kingpin.v2" "pkg.deepin.io/lib/log" "pkg.deepin.io/lib/profile" "strings" ) func toLogLevel(name string) (log.Priority, error) { name = strings.ToLower(name) logLevel := log.LevelInfo var err error switch name { case "": case "error": logLevel = log.LevelError case "warn": logLevel = log.LevelWarning case "info": logLevel = log.LevelInfo case "debug": logLevel = log.LevelDebug case "no": logLevel = log.LevelDisable default: err = fmt.Errorf("%s is not support", name) } return logLevel, err } // App is app structure with commandline and profile features. type App struct { cmd *kingpin.Application verbose *bool logLevel *string memprof *string cpuprof *string profile *profile.Config } // ParseCommandLine will parse command line which should not contains the executable name, // and then return the sub-command. Exit if parse failed. func (app *App) ParseCommandLine(args []string) string { subcmd := kingpin.MustParse(app.cmd.Parse(args)) app.profile.CPUProfile = app.CpuProf() app.profile.MemProfile = app.MemProf() return subcmd } // Flag extends a new global flag. see kingpin for details. func (app *App) Flag(longName string, desc string) *kingpin.FlagClause { return app.cmd.Flag(longName, desc) } // Command extends an sub-command. see kingpin for details. func (app *App) Command(name string, desc string) *kingpin.CmdClause { return app.cmd.Command(name, desc) } // StartProfile starts all possible profiles. func (app *App) StartProfile() error { return app.profile.Start() } // StopProfile stop profile, this should be called when shutdown hook is disabled, // and this method does nothing when shutdown hook is enabled. func (app *App) StopProfile() { app.profile.Stop() } // EnableNoHookShutdown enables or disable shutdown hook. // If shutdown hook is disabled, StopProfile is needed to be called. func (app *App) EnableNoShutdownHook(noShutdownHook bool) { app.profile.NoShutdownHook = noShutdownHook } // LogLevel returns the log level. func (app *App) LogLevel() log.Priority { if *app.logLevel == "" && *app.verbose { return log.LevelDebug } lv, _ := toLogLevel(*app.logLevel) return lv } func (app *App) IsLogLevelNone() bool { return !(*app.verbose) && *app.logLevel == "" } // MemProf returns memory profile's path. func (app *App) MemProf() string { return *app.memprof } // CpuProf returns cpu profile's path func (app *App) CpuProf() string { return *app.cpuprof } // New creates a new application according to name, description and version. // There are some default command line flag: // verbose(v for short): show much more message, shorthand for --loglevel debug which will be ignored if loglevel is specificed. // loglevel(l for short): set log level, possible value is error/warn/info/debug/no, info is default. // memprof: the file to save memory profile. // cpuprof: the file to save cpu profile. func New(name string, desc string, version string) *App { cmd := kingpin.New(name, desc) cmd.Version(version) app := &App{ cmd: cmd, profile: &profile.Config{}, verbose: cmd.Flag("verbose", "Show much more message, shorthand for --loglevel debug which will be ignored if loglevel is specificed.").Short('v').Bool(), logLevel: cmd.Flag("loglevel", "Set log level, possible value is error/warn/info/debug/no, info is default.").Short('l').String(), memprof: cmd.Flag("memprof", "Write memory profile to specific file").String(), cpuprof: cmd.Flag("cpuprof", "Write cpu profile to specific file").String(), } return app } go-lib-5.6.0.9/app/app_test.go000664 000000 000000 00000002010 13753517240 015750 0ustar00rootroot000000 000000 // +build ignore /* * Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package app import ( "os" ) func ExampleApp() { app := New("test app", "this is a test app", "version 0.0.0") subcmd := app.ParseCommandLine(os.Args[1:]) if app.StartProfile() != nil { // error handle return } switch subcmd { // deal with subcmd } } go-lib-5.6.0.9/appinfo/000775 000000 000000 00000000000 13753517240 014465 5ustar00rootroot000000 000000 go-lib-5.6.0.9/appinfo/appinfo.go000664 000000 000000 00000001760 13753517240 016454 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package appinfo type AppInfo interface { GetId() string GetName() string GetIcon() string GetExecutable() string GetFileName() string GetCommandline() string Launch(files []string, launchContext *AppLaunchContext) error GetStartupWMClass() string } go-lib-5.6.0.9/appinfo/applaunchcontext.go000664 000000 000000 00000005255 13753517240 020403 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package appinfo import ( "fmt" "os" "path/filepath" "strconv" "sync" "github.com/linuxdeepin/go-x11-client" ) var ( pid int prog string hostname string ) func init() { pid = os.Getpid() prog = filepath.Base(os.Args[0]) hostname, _ = os.Hostname() } type AppLaunchContext struct { sync.Mutex conn *x.Conn count uint timestamp uint32 cmdPrefixes []string cmdSuffixes []string } func NewAppLaunchContext(conn *x.Conn) *AppLaunchContext { return &AppLaunchContext{ conn: conn, } } func (ctx *AppLaunchContext) SetTimestamp(timestamp uint32) { ctx.timestamp = timestamp } func (ctx *AppLaunchContext) GetTimestamp() uint32 { return ctx.timestamp } func (ctx *AppLaunchContext) SetCmdPrefixes(v []string) { ctx.cmdPrefixes = v } func (ctx *AppLaunchContext) GetCmdPrefixes() []string { return ctx.cmdPrefixes } func (ctx *AppLaunchContext) SetCmdSuffixes(v []string) { ctx.cmdSuffixes = v } func (ctx *AppLaunchContext) GetCmdSuffixes() []string { return ctx.cmdSuffixes } func (ctx *AppLaunchContext) GetStartupNotifyId(appInfo AppInfo, files []string) (string, error) { execBase := filepath.Base(appInfo.GetExecutable()) snId := fmt.Sprintf("%s-%d-%s-%s-%d_TIME%d", prog, pid, hostname, execBase, ctx.count, ctx.timestamp) ctx.count++ screenStr := strconv.Itoa(ctx.conn.ScreenNumber) // send new msg msg := &StartupNotifyMessage{ Type: "new", KeyValues: map[string]string{ "ID": snId, "SCREEN": screenStr, "NAME": appInfo.GetName(), }, } startupWMClass := appInfo.GetStartupWMClass() if startupWMClass != "" { msg.KeyValues["WMCLASS"] = startupWMClass } err := msg.Broadcast(ctx.conn) if err != nil { return "", err } return snId, nil } func (ctx *AppLaunchContext) LaunchFailed(startupNotifyId string) error { // send remove msg msg := &StartupNotifyMessage{ Type: "remove", KeyValues: map[string]string{ "ID": startupNotifyId, }, } return msg.Broadcast(ctx.conn) } go-lib-5.6.0.9/appinfo/desktopappinfo/000775 000000 000000 00000000000 13753517240 017513 5ustar00rootroot000000 000000 go-lib-5.6.0.9/appinfo/desktopappinfo/desktopappinfo.go000664 000000 000000 00000040664 13753517240 023102 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package desktopappinfo import ( "bytes" "errors" "os" "os/exec" "path/filepath" "regexp" "strings" "sync" "time" gio "pkg.deepin.io/gir/gio-2.0" "pkg.deepin.io/lib/appinfo" "pkg.deepin.io/lib/keyfile" "pkg.deepin.io/lib/shell" "pkg.deepin.io/lib/xdg/basedir" ) const ( MainSection = "Desktop Entry" KeyType = "Type" KeyVersion = "Version" KeyName = "Name" KeyGenericName = "GenericName" KeyNoDisplay = "NoDisplay" KeyComment = "Comment" KeyIcon = "Icon" KeyHidden = "Hidden" KeyOnlyShowIn = "OnlyShowIn" KeyNotShowIn = "NotShowIn" KeyTryExec = "TryExec" KeyExec = "Exec" KeyPath = "Path" KeyTerminal = "Terminal" KeyMimeType = "MimeType" KeyCategories = "Categories" KeyKeywords = "Keywords" KeyStartupNotify = "StartupNotify" KeyStartupWMClass = "StartupWMClass" KeyURL = "URL" KeyActions = "Actions" KeyDBusActivatable = "DBusActivatable" TypeApplication = "Application" TypeLink = "Link" TypeDirectory = "Directory" envDesktopEnv = "XDG_CURRENT_DESKTOP" desktopExt = ".desktop" gsSchemaStartdde = "com.deepin.dde.startdde" enableInvoker = "ENABLE_TURBO_INVOKER" turboInvokerFailedMsg = "Failed to invoke: Booster:" turboInvokerErrMsg = "deepin-turbo-invoker: error" ) var xdgDataDirs []string var xdgAppDirs []string func init() { xdgDataDirs = make([]string, 0, 3) xdgDataDirs = append(xdgDataDirs, basedir.GetUserDataDir()) sysDataDirs := basedir.GetSystemDataDirs() xdgDataDirs = append(xdgDataDirs, sysDataDirs...) xdgAppDirs = make([]string, len(xdgDataDirs)) for i, dir := range xdgDataDirs { xdgAppDirs[i] = filepath.Join(dir, "applications") } } func SetDataDirs(dirs []string) { xdgDataDirs = dirs xdgAppDirs = make([]string, len(xdgDataDirs)) for i, dir := range xdgDataDirs { xdgAppDirs[i] = filepath.Join(dir, "applications") } } type DesktopAppInfo struct { *keyfile.KeyFile filename string id string name string icon string } func NewDesktopAppInfo(id string) *DesktopAppInfo { if !strings.HasSuffix(id, desktopExt) { id += desktopExt } if filepath.IsAbs(id) { ai, _ := NewDesktopAppInfoFromFile(id) return ai } for _, appDir := range xdgAppDirs { file := filepath.Join(appDir, id) ai, err := newDesktopAppInfoFromFile(file) if err == nil { // length of desktopExt is 8 ai.id = id[:len(id)-8] return ai } } return nil } var ErrInvalidFileExt = errors.New("the file extension is not " + desktopExt) var ErrInvalidFirstSection = errors.New("first section is not " + MainSection) var ErrInvalidType = errors.New("type is not " + TypeApplication) // Only the characters A-Za-z0-9- may be used in key names. var keyReg = regexp.MustCompile(`^[A-Za-z0-9\-]+(\[[A-Za-z0-9@_\-.]+])?$`) func newDesktopAppInfoFromFile(filename string) (*DesktopAppInfo, error) { kfile := keyfile.NewKeyFile() kfile.SetKeyRegexp(keyReg) err := kfile.LoadFromFile(filename) if err != nil { return nil, err } f, err := NewDesktopAppInfoFromKeyFile(kfile) if err != nil { return nil, err } f.filename = filename return f, nil } func NewDesktopAppInfoFromKeyFile(kfile *keyfile.KeyFile) (*DesktopAppInfo, error) { f := &DesktopAppInfo{ KeyFile: kfile, } sections := f.GetSections() if !(len(sections) > 0 && sections[0] == MainSection) { return nil, ErrInvalidFirstSection } type0, _ := f.GetValue(MainSection, KeyType) if type0 != TypeApplication { return nil, ErrInvalidType } f.name, _ = f.GetLocaleString(MainSection, KeyName, "") icon, _ := f.GetString(MainSection, KeyIcon) /* Work around a common mistake in desktop files */ if !filepath.IsAbs(icon) { ext := filepath.Ext(icon) switch ext { case ".png", ".xpm", ".svg": icon = strings.TrimSuffix(icon, ext) } } f.icon = icon return f, nil } func NewDesktopAppInfoFromFile(filename string) (*DesktopAppInfo, error) { if !strings.HasSuffix(filename, desktopExt) { return nil, ErrInvalidFileExt } filename, err := filepath.Abs(filename) if err != nil { return nil, err } ai, err := newDesktopAppInfoFromFile(filename) if err != nil { return nil, err } ai.id = getId(filename) return ai, err } // filename must has suffix desktopExt // example: // /usr/share/applications/a.desktop -> a // /usr/share/applications/kde4/a.desktop -> kde4/a // /xxxx/dir/a.desktop -> /xxxx/dir/a func getId(filename string) string { filename = strings.TrimSuffix(filename, desktopExt) i := strings.Index(filename, "/applications/") if i == -1 { return filename } dir := filename[:i] var installed bool for _, d := range xdgDataDirs { if d == dir { installed = true break } } if installed { // length of "/applications/" is 14 return filename[i+14:] } return filename } func (ai *DesktopAppInfo) GetId() string { return ai.id } func (ai *DesktopAppInfo) IsInstalled() bool { i := strings.Index(ai.filename, "/applications/") if i == -1 { return false } dir := ai.filename[:i] for _, d := range xdgDataDirs { if d == dir { return true } } return false } func (ai *DesktopAppInfo) GetFileName() string { return ai.filename } // deprecated func (ai *DesktopAppInfo) GetIsHiden() bool { hidden, _ := ai.GetBool(MainSection, KeyHidden) return hidden } func (ai *DesktopAppInfo) GetIsHidden() bool { hidden, _ := ai.GetBool(MainSection, KeyHidden) return hidden } func (ai *DesktopAppInfo) GetNoDisplay() bool { noDisplay, _ := ai.GetBool(MainSection, KeyNoDisplay) return noDisplay } var currentDesktops []string var currentDesktopsOnce sync.Once func getCurrentDesktop() []string { currentDesktopsOnce.Do(func() { desktopEnv := os.Getenv(envDesktopEnv) currentDesktops = strings.Split(desktopEnv, ":") }) return currentDesktops } func (ai *DesktopAppInfo) GetShowIn(desktopEnvs []string) bool { if len(desktopEnvs) == 0 { desktopEnvs = getCurrentDesktop() } onlyShowIn, _ := ai.GetStringList(MainSection, KeyOnlyShowIn) notShowIn, _ := ai.GetStringList(MainSection, KeyNotShowIn) for _, env := range desktopEnvs { for _, de := range onlyShowIn { if env == de { return true } } for _, de := range notShowIn { if env == de { return false } } } return len(onlyShowIn) == 0 } func (ai *DesktopAppInfo) ShouldShow() bool { if ai.GetNoDisplay() { return false } if ai.GetIsHidden() { return false } return ai.GetShowIn(nil) } func (ai *DesktopAppInfo) GetName() string { return ai.name } func (ai *DesktopAppInfo) GetGenericName() string { gname, _ := ai.GetLocaleString(MainSection, KeyGenericName, "") return gname } func (ai *DesktopAppInfo) GetComment() string { comment, _ := ai.GetLocaleString(MainSection, KeyComment, "") return comment } func (ai *DesktopAppInfo) GetDisplayName() string { return ai.GetName() } func (ai *DesktopAppInfo) GetMimeTypes() []string { mimeTypes, _ := ai.GetStringList(MainSection, KeyMimeType) return mimeTypes } func (ai *DesktopAppInfo) GetCategories() []string { categories, _ := ai.GetStringList(MainSection, KeyCategories) return categories } func (ai *DesktopAppInfo) GetKeywords() []string { keywords, _ := ai.GetLocaleStringList(MainSection, KeyKeywords, "") return keywords } func (ai *DesktopAppInfo) GetStartupWMClass() string { wmclass, _ := ai.GetString(MainSection, KeyStartupWMClass) return wmclass } func (ai *DesktopAppInfo) GetStartupNotify() bool { sn, _ := ai.GetBool(MainSection, KeyStartupNotify) return sn } func (ai *DesktopAppInfo) GetIcon() string { return ai.icon } func (ai *DesktopAppInfo) GetCommandline() string { exec, _ := ai.GetString(MainSection, KeyExec) return exec } func (ai *DesktopAppInfo) GetPath() string { wd, _ := ai.GetString(MainSection, KeyPath) return wd } // TryExec is Path to an executable file on disk used to determine if the program is actually installed func (ai *DesktopAppInfo) GetTryExec() string { tryExec, _ := ai.GetString(MainSection, KeyTryExec) return tryExec } // DBusActivatable is a boolean value specifying if D-Bus activation is supported for this application func (ai *DesktopAppInfo) GetDBusActivatable() bool { b, _ := ai.GetBool(MainSection, KeyDBusActivatable) return b } func (ai *DesktopAppInfo) GetTerminal() bool { useTerminal, _ := ai.GetBool(MainSection, KeyTerminal) return useTerminal } func (ai *DesktopAppInfo) Launch(files []string, launchContext *appinfo.AppLaunchContext) error { return launch(ai, ai.GetCommandline(), files, launchContext) } func (ai *DesktopAppInfo) StartCommand(files []string, launchContext *appinfo.AppLaunchContext) (*exec.Cmd, error) { return startCommand(ai, ai.GetCommandline(), files, launchContext, false) } func (ai *DesktopAppInfo) GetExecutable() string { cmdline := ai.GetCommandline() if cmdline == "" { return "" } parts, _ := splitExec(cmdline) if len(parts) == 0 { return "" } return parts[0] } func (ai *DesktopAppInfo) IsExecutableOk() bool { tryExec := ai.GetTryExec() if tryExec != "" { _, err := exec.LookPath(tryExec) return err == nil } exe := ai.GetExecutable() if exe == "" { return false } _, err := exec.LookPath(exe) return err == nil } var _startddeGs *gio.Settings var _startddeGsMu sync.Mutex func getStartddeGs() *gio.Settings { _startddeGsMu.Lock() if _startddeGs == nil { _startddeGs = gio.NewSettings(gsSchemaStartdde) } _startddeGsMu.Unlock() return _startddeGs } // isAction 表示是否是启动一个 desktop action。 func shouldUseTurboInvoker(ai *DesktopAppInfo, isAction bool, turboInvokerPath string, ctx *appinfo.AppLaunchContext) bool { // NOTE: 启用 turbo invoker 的条件: // 必须 isAction 为 false,即必须不是 desktop action 快捷动作,而是 desktop 文件主要的那个。 // 必须有 deepin-turbo-invoker 程序,它在 deepin-turbo 包。 // 必须 desktop 文件中有 X-Deepin-TurboType 字段的值不为空。 // 如果开了应用代理添加了 prefix 或 suffix 则不用 turbo。 // 环境变量 ENABLE_TURBO_INVOKER == 1 // 或者环境变量 ENABLE_TURBO_INVOKER == 空且 gsettings com.deepin.dde.startdde turbo-invoker-enabled 设置为 true。 // 因此当环境变量 ENABLE_TURBO_INVOKER == 0 时,可以禁用此功能。 if isAction || turboInvokerPath == "" { return false } turboType, _ := ai.GetString(MainSection, "X-Deepin-TurboType") if turboType == "" { return false } // 应用代理是通过添加 prefix 和 suffix 来实现的 for _, prefix := range ctx.GetCmdPrefixes() { if strings.Contains(prefix, "proxychains") { return false } } for _, suffix := range ctx.GetCmdSuffixes() { if strings.Contains(suffix, "--proxy-server") { return false } } envEnabled := os.Getenv(enableInvoker) if envEnabled == "1" { return true } gsEnabled := getStartddeGs().GetBoolean("turbo-invoker-enabled") return envEnabled == "" && gsEnabled } type failDetector struct { buf bytes.Buffer done bool // 是否完成检测 ch chan struct{} mu sync.Mutex } func newFailDetector(ch chan struct{}) *failDetector { return &failDetector{ ch: ch, } } func (w *failDetector) markDone() { w.mu.Lock() w.done = true w.buf = bytes.Buffer{} w.mu.Unlock() } func (w *failDetector) Write(p []byte) (n int, err error) { w.mu.Lock() defer w.mu.Unlock() if w.done { return len(p), nil } n, err = w.buf.Write(p) data := w.buf.Bytes() if bytes.Contains(data, []byte(turboInvokerFailedMsg)) || bytes.Contains(data, []byte(turboInvokerErrMsg)) { w.done = true w.buf = bytes.Buffer{} select { case w.ch <- struct{}{}: // 告知 turbo invoker 启动失败 default: // 表示 ch 已经没有接收者了 } } else { // 把最后一个 \n 前面的数据清除 idx := bytes.LastIndexByte(data, '\n') if idx != -1 { newData := make([]byte, len(data)-idx-1) copy(newData, data[idx+1:]) w.buf.Reset() w.buf.Write(newData) } } // 防止 buf 数据量太大 if w.buf.Len() > 50000 { w.done = true w.buf = bytes.Buffer{} // 释放 w.buf 占用的内存 } return n, err } func startCommand(ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext, isAction bool) (*exec.Cmd, error) { turboInvokerPath, _ := exec.LookPath("deepin-turbo-invoker") if shouldUseTurboInvoker(ai, isAction, turboInvokerPath, launchContext) { args := []string{"--desktop-file"} args = append(args, ai.GetFileName()) for _, file := range files { args = append(args, file) } cmd := exec.Command(turboInvokerPath, args...) failCh := make(chan struct{}) fdOut := newFailDetector(failCh) fdErr := newFailDetector(failCh) cmd.Stdout = fdOut cmd.Stderr = fdErr err := cmd.Start() if err == nil { select { case <-time.After(2 * time.Second): // turbo invoker 启动成功 fdOut.markDone() fdErr.markDone() return cmd, nil case <-failCh: // turbo invoker 启动失败 go func() { // NOTE: 注意回收 cmd 进程资源 _ = cmd.Wait() }() } } } if cmdline == "" { return nil, errors.New("command line is empty") } // get working dir workingDir := ai.GetPath() if workingDir == "" { // fallback to user home dir workingDir = basedir.GetUserHomeDir() // fallback to fs root / if workingDir == "" { workingDir = "/" } } exeargs, err := splitExec(cmdline) if err != nil { return nil, err } exeargs, err = ai.expandFieldCode(exeargs, files) if err != nil { return nil, err } useTerminal := ai.GetTerminal() if useTerminal { termExec, termExecArg := getDefaultTerminal() exeargs = append([]string{termExec, termExecArg}, exeargs...) } if launchContext != nil { cmdPrefixes := launchContext.GetCmdPrefixes() cmdSuffixes := launchContext.GetCmdSuffixes() exeargs = append(cmdPrefixes, exeargs...) exeargs = append(exeargs, cmdSuffixes...) } var launchScriptBuf bytes.Buffer launchScriptBuf.WriteString(`export GIO_LAUNCHED_DESKTOP_FILE_PID=$$;exec`) for _, arg := range exeargs { launchScriptBuf.WriteByte(' ') launchScriptBuf.WriteString(shell.Encode(arg)) } cmd := exec.Command("/bin/sh", "-c", launchScriptBuf.String()) cmd.Env = append(os.Environ(), "GIO_LAUNCHED_DESKTOP_FILE="+ai.GetFileName()) cmd.Dir = workingDir var snId string startupNotify := ai.GetStartupNotify() if startupNotify && launchContext != nil && launchContext.GetTimestamp() != 0 { snId, _ = launchContext.GetStartupNotifyId(ai, files) cmd.Env = append(cmd.Env, "DESKTOP_STARTUP_ID="+snId) } err = cmd.Start() return cmd, err } func launch(ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext) error { cmd, err := startCommand(ai, cmdline, files, launchContext, false) go func() { _ = cmd.Wait() }() return err } // [Desktop Action new-window] // or [Full_Screenshot Shortcut Group] func isDesktopAction(name string) bool { return strings.HasPrefix(name, "Desktop Action") || strings.HasSuffix(name, "Shortcut Group") } func (ai *DesktopAppInfo) GetActions() []DesktopAction { var actions []DesktopAction for _, section := range ai.GetSections() { if isDesktopAction(section) { name, _ := ai.GetLocaleString(section, KeyName, "") exec, _ := ai.GetString(section, KeyExec) action := DesktopAction{ Section: section, Name: name, Exec: exec, parent: ai, } actions = append(actions, action) } } return actions } type DesktopAction struct { parent *DesktopAppInfo Section string Name string Exec string } func (action *DesktopAction) Launch(files []string, launchContext *appinfo.AppLaunchContext) error { ai := action.parent return launch(ai, action.Exec, files, launchContext) } func (action *DesktopAction) StartCommand(files []string, launchContext *appinfo.AppLaunchContext) (*exec.Cmd, error) { ai := action.parent return startCommand(ai, action.Exec, files, launchContext, true) } go-lib-5.6.0.9/appinfo/desktopappinfo/desktopappinfo_test.go000664 000000 000000 00000036013 13753517240 024132 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package desktopappinfo import ( "os" "path/filepath" "testing" . "github.com/smartystreets/goconvey/convey" "pkg.deepin.io/lib/keyfile" ) func TestNewDesktopAppInfoFromKeyFile(t *testing.T) { Convey("NewDesktopAppInfoFromKeyFile failed, empty keyfile", t, func(c C) { kfile := keyfile.NewKeyFile() ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldNotBeNil) c.So(err, ShouldEqual, ErrInvalidFirstSection) c.So(ai, ShouldBeNil) t.Log(err) }) Convey("NewDesktopAppInfoFromKeyFile failed, invalid type", t, func(c C) { kfile := keyfile.NewKeyFile() kfile.SetValue(MainSection, KeyType, "xxxx") kfile.SetValue(MainSection, KeyName, "Deepin Screenshot") ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldNotBeNil) c.So(err, ShouldEqual, ErrInvalidType) c.So(ai, ShouldBeNil) t.Log(err) }) Convey("NewDesktopAppInfoFromKeyFile sucess", t, func(c C) { kfile := keyfile.NewKeyFile() kfile.SetValue(MainSection, KeyType, TypeApplication) kfile.SetValue(MainSection, KeyName, "Deepin Screenshot") kfile.SetValue(MainSection, KeyExec, "deepin-screenshot --icon") kfile.SetValue(MainSection, KeyIcon, "deepin-screenshot.png") ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetCommandline(), ShouldEqual, "deepin-screenshot --icon") c.So(ai.GetName(), ShouldEqual, "Deepin Screenshot") c.So(ai.GetIcon(), ShouldEqual, "deepin-screenshot") }) } func TestNewDesktopAppInfo(t *testing.T) { Convey("NewDesktopAppInfo", t, func(c C) { testDataDir, err := filepath.Abs("testdata") c.So(err, ShouldBeNil) xdgDataDirs = []string{testDataDir} xdgAppDirs = []string{filepath.Join(testDataDir, "applications")} c.Convey("NewDesktopAppInfoFromFile", func(c C) { ai, err := NewDesktopAppInfoFromFile("testdata/applications/deepin-screenshot.desktop") c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(err, ShouldBeNil) c.So(ai.GetIcon(), ShouldEqual, "deepin-screenshot") c.So(ai.GetId(), ShouldEqual, "deepin-screenshot") }) c.Convey("NewDesktopAppInfo By Id", func(c C) { ai := NewDesktopAppInfo("deepin-screenshot") c.So(ai, ShouldNotBeNil) c.So(ai.GetId(), ShouldEqual, "deepin-screenshot") ai = NewDesktopAppInfo("deepin-screenshot.desktop") c.So(ai, ShouldNotBeNil) ai = NewDesktopAppInfo("not-exist") c.So(ai, ShouldBeNil) }) }) } func TestGetActions(t *testing.T) { Convey("DesktopAppInfo.GetActions", t, func(c C) { ai, err := NewDesktopAppInfoFromFile("testdata/applications/deepin-screenshot.desktop") c.So(err, ShouldBeNil) actions := ai.GetActions() t.Log("actions:", actions) c.So(actions, ShouldHaveLength, 2) c.So(actions[0].Exec, ShouldEqual, "deepin-screenshot -f") c.So(actions[1].Exec, ShouldEqual, "deepin-screenshot -d 5") }) } func init() { os.Setenv(envDesktopEnv, "Deepin:GNOME") } func TestGetCurrentDestkops(t *testing.T) { Convey("getCurrentDesktop", t, func(c C) { c.So(getCurrentDesktop(), ShouldResemble, []string{"Deepin", "GNOME"}) }) } const desktopFileContent0 = ` [Desktop Entry] Type=Application Name=xxx OnlyShowIn=Deepin ` const desktopFileContent1 = ` [Desktop Entry] Type=Application Name=xxx OnlyShowIn=GNOME ` const desktopFileContent2 = ` [Desktop Entry] Type=Application Name=xxx ` const desktopFileContent3 = ` [Desktop Entry] Type=Application Name=xxx OnlyShowIn=GNOME;Deepin ` const desktopFileContent4 = ` [Desktop Entry] Type=Application Name=xxx OnlyShowIn=Xfce;KDE ` const desktopFileContent5 = ` [Desktop Entry] Type=Application Name=xxx NotShowIn=Deepin ` const desktopFileContent6 = ` [Desktop Entry] Type=Application Name=xxx NotShowIn=KDE;GNOME; ` func TestGetShowIn(t *testing.T) { Convey("GetShowIn destkop env: Deepin", t, func(c C) { currentDesktops = []string{"Deepin"} c.Convey("GetShowIn OnlyShowIn=Deepin", func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent0)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetShowIn(nil), ShouldBeTrue) }) c.Convey("GetShowIn OnlyShowIn=GNOME", func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent1)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetShowIn(nil), ShouldBeFalse) }) c.Convey("GetShowIn OnlyShowIn undefined and NotShowIn undefined", func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent2)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetShowIn(nil), ShouldBeTrue) }) c.Convey("GetShowIn OnlyShowIn=GNOME;Deepin", func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent3)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetShowIn(nil), ShouldBeTrue) }) c.Convey("GetShowIn OnlyShowIn=Xfce;KDE", func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent4)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetShowIn(nil), ShouldBeFalse) }) c.Convey("GetShowIn NotShowIn=Deepin", func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent5)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetShowIn(nil), ShouldBeFalse) }) c.Convey("GetShowIn NotShowIn=KDE;GNOME;", func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent6)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetShowIn(nil), ShouldBeTrue) }) }) } const desktopFileContent7 = ` [Desktop Entry] Type=Application Name=shell Exec=sh ` const desktopFileContent8 = ` [Desktop Entry] Type=Application Name=shell Exec=sh $ ` const desktopFileContent9 = ` [Desktop Entry] Type=Application Name=shell Exec=/bin/sh ` const desktopFileContent10 = ` [Desktop Entry] Type=Application Name=shell Exec=/bin/sh/notexist ` const desktopFileContent11 = ` [Desktop Entry] Type=Application Name=shell Exec=notexist ` func TestGetExecutable(t *testing.T) { Convey("GetExecutable Exec undefined", t, func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent6)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetExecutable(), ShouldEqual, "") c.So(ai.IsExecutableOk(), ShouldBeFalse) }) Convey("GetExecutable Exec=sh", t, func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent7)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetExecutable(), ShouldEqual, "sh") c.So(ai.IsExecutableOk(), ShouldBeTrue) }) Convey("GetExecutable Exec=sh $", t, func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent8)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetExecutable(), ShouldEqual, "") c.So(ai.IsExecutableOk(), ShouldBeFalse) }) Convey("GetExecutable Exec=/bin/sh", t, func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent9)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetExecutable(), ShouldEqual, "/bin/sh") c.So(ai.IsExecutableOk(), ShouldBeTrue) }) Convey("GetExecutable Exec=/bin/sh/notexist", t, func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent10)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetExecutable(), ShouldEqual, "/bin/sh/notexist") c.So(ai.IsExecutableOk(), ShouldBeFalse) }) Convey("GetExecutable Exec=notexist", t, func(c C) { kfile := keyfile.NewKeyFile() err := kfile.LoadFromData([]byte(desktopFileContent11)) c.So(err, ShouldBeNil) ai, err := NewDesktopAppInfoFromKeyFile(kfile) c.So(err, ShouldBeNil) c.So(ai, ShouldNotBeNil) c.So(ai.GetExecutable(), ShouldEqual, "notexist") c.So(ai.IsExecutableOk(), ShouldBeFalse) }) } func Test_splitExec(t *testing.T) { Convey("splitExec", t, func(c C) { parts, err := splitExec(`abc def ghi`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"abc", "def", "ghi"}) parts, err = splitExec(`"abc" def "ghi"`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"abc", "def", "ghi"}) parts, err = splitExec(`"abc 123" def "ghi"`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"abc 123", "def", "ghi"}) parts, err = splitExec(`abc def "" ghi`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"abc", "def", "", "ghi"}) parts, err = splitExec(`"abc's" def`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"abc's", "def"}) parts, err = splitExec(`"abc\\s" def`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"abc\\s", "def"}) parts, err = splitExec(`abc def ghi`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"abc", "def", "ghi"}) parts, err = splitExec(`"abc"`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"abc"}) _, err = splitExec(`"abcdef`) c.So(err, ShouldEqual, ErrQuotingNotClosed) _, err = splitExec(`"abcdef\"`) c.So(err, ShouldEqual, ErrQuotingNotClosed) _, err = splitExec(`"$abcdef"`) c.So(err, ShouldResemble, ErrCharNotEscaped{'$'}) _, err = splitExec("\"`abcdef\" def") c.So(err, ShouldResemble, ErrCharNotEscaped{'`'}) _, err = splitExec(`"abc\def"`) c.So(err, ShouldResemble, ErrInvalidEscapeSequence{'d'}) _, err = splitExec(`#echo hello world`) c.So(err, ShouldResemble, ErrReservedCharNotQuoted{'#'}) _, err = splitExec(`(1)`) c.So(err, ShouldResemble, ErrReservedCharNotQuoted{'('}) _, err = splitExec(`"abc"def`) c.So(err, ShouldEqual, ErrNoSpaceAfterQuoting) parts, err = splitExec(`env WINEPREFIX="/home/tp/.wine" wine-stable C:\\windows\\command\\start.exe /Unix /home/tp/.wine/dosdevices/c:/users/tp/Start\ Menu/Programs/sc1.08/sc1.08.lnk`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"env", "WINEPREFIX=/home/tp/.wine", "wine-stable", "C:\\\\windows\\\\command\\\\start.exe", "/Unix", "/home/tp/.wine/dosdevices/c:/users/tp/Start Menu/Programs/sc1.08/sc1.08.lnk"}) parts, err = splitExec(`echo hello\ world`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"echo", "hello world"}) parts, err = splitExec(`echo hello\world`) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"echo", "helloworld"}) _, err = splitExec(`echo hello\`) c.So(err, ShouldEqual, ErrEscapeCharAtEnd) }) } func Test_expandFieldCode(t *testing.T) { Convey("expandFieldCode", t, func(c C) { icon := "test_icon" desktopFile := "test.desktop" files := []string{"/dir1/dir2/a", "/dir1/dir2/b"} translatedName := "translatedName" cmdline := []string{"start", "%f", "%i", "%c", "%k", "end"} parts, err := expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", files[0], "--icon", icon, translatedName, desktopFile, "end"}) cmdline = []string{"start", "%G", "end"} _, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldEqual, ErrBadFieldCode) cmdline = []string{"start", "%d", "%d", "%v", "end"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", "end"}) cmdline = []string{"start", "%F", "end"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", "/dir1/dir2/a", "/dir1/dir2/b", "end"}) cmdline = []string{"start", "%u", "end"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", "file:///dir1/dir2/a", "end"}) cmdline = []string{"start", "%U", "end"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", "file:///dir1/dir2/a", "file:///dir1/dir2/b", "end"}) cmdline = []string{"start", "%%", "%abc", "end"} _, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldEqual, ErrBadFieldCode) cmdline = []string{"start", "1%%", "end"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", "1%", "end"}) files = []string{"file:///home/tp/2017%E5%B9%B403%E6%9C%88-%E6%B7%B1%E5%BA%A6%E9%9B%86%E7%BB%93-%E7%94%B5%E5%AD%90%E7%89%88.pdf"} cmdline = []string{"/opt/Foxitreader/FoxitReader.sh", "%F"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"/opt/Foxitreader/FoxitReader.sh", "/home/tp/2017年03月-深度集结-电子版.pdf"}) files = []string{"/a/b/log"} cmdline = []string{"start", "file=%u", "end"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", "file=file:///a/b/log", "end"}) cmdline = []string{"start", "file=%u+++", "end"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", "file=file:///a/b/log+++", "end"}) cmdline = []string{"start", "icon:%i", "end"} parts, err = expandFieldCode(cmdline, files, translatedName, icon, desktopFile) c.So(err, ShouldBeNil) c.So(parts, ShouldResemble, []string{"start", "icon:--icon", "test_icon", "end"}) }) } go-lib-5.6.0.9/appinfo/desktopappinfo/exec.go000664 000000 000000 00000014423 13753517240 020772 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package desktopappinfo import ( "bytes" "errors" "fmt" "net/url" "strings" "pkg.deepin.io/lib/utils" ) func getDefaultTerminal() (exec string, execArg string) { gs, err := utils.CheckAndNewGSettings("com.deepin.desktop.default-applications.terminal") if err == nil { exec = gs.GetString("exec") execArg = gs.GetString("exec-arg") } else { exec = "xterm" execArg = "-e" } return } // The characters that must be escaped var escapeChars = []byte{'`', '$', '\\', '"'} // Reserved characters var reservedChars = []byte{'`', '$', '\\', '"', '\t', '\n', '\'', '>', '<', '~', '|', '&', ';', '*', '?', '#', '(', ')'} func isReservedChar(ch byte) bool { for _, v := range reservedChars { if v == ch { return true } } return false } func shouldEscapeChar(ch byte) bool { for _, v := range escapeChars { if v == ch { return true } } return false } var ErrQuotingNotClosed = errors.New("quoting is not be closed") var ErrEscapeCharAtEnd = errors.New("escape char \\ at end of string") var ErrNoSpaceAfterQuoting = errors.New("no space character found after a quoting") type ErrReservedCharNotQuoted struct { Char byte } func (err ErrReservedCharNotQuoted) Error() string { return fmt.Sprintf("reserved character %q is not be quoted", err.Char) } type ErrCharNotEscaped struct { Char byte } func (err ErrCharNotEscaped) Error() string { return fmt.Sprintf("character %q is not be escaped", err.Char) } type ErrInvalidEscapeSequence struct { Char byte } func (err ErrInvalidEscapeSequence) Error() string { return fmt.Sprintf("invalid escape sequence %q", "\\"+string(err.Char)) } func eatAllSpace(reader *strings.Reader) { for { ch, err := reader.ReadByte() if err != nil { // EOF return } if ch != ' ' { _ = reader.UnreadByte() break } } } func splitExec(exec string) ([]string, error) { var buf bytes.Buffer var outlist []string reader := strings.NewReader(exec) var in bool for { ch, err := reader.ReadByte() if err != nil { // err is EOF if in { return nil, ErrQuotingNotClosed } outlist = append(outlist, buf.String()) break } switch ch { case ' ': if in { buf.WriteByte(ch) } else { eatAllSpace(reader) outlist = append(outlist, buf.String()) buf.Reset() } case '"': in = !in if !in { ch0, err0 := reader.ReadByte() if err0 != nil { continue } if ch0 != ' ' { return nil, ErrNoSpaceAfterQuoting } _ = reader.UnreadByte() } case '\\': if in { ch1, err1 := reader.ReadByte() if err1 != nil { // err1 is EOF return nil, ErrEscapeCharAtEnd } if shouldEscapeChar(ch1) { // \# buf.WriteByte(ch1) } else { // \b return nil, ErrInvalidEscapeSequence{ch1} } } else { ch1, err1 := reader.ReadByte() if err1 != nil { // \ at end return nil, ErrEscapeCharAtEnd } switch ch1 { case ' ': // \ + space => space buf.WriteByte(' ') case '\\': // \ + \ => \ + \ buf.WriteString(`\\`) default: // \ + w => w _ = reader.UnreadByte() } } default: if isReservedChar(ch) { if in { if shouldEscapeChar(ch) { return nil, ErrCharNotEscaped{ch} } buf.WriteByte(ch) } else { return nil, ErrReservedCharNotQuoted{ch} } } else { buf.WriteByte(ch) } } } return outlist, nil } func toURL(path string) string { var u *url.URL if strings.HasPrefix(path, "/") { u = &url.URL{ Path: path, Scheme: "file", } } else { var err error u, err = url.Parse(path) if err != nil { return "" } } return u.String() } func toLocalPath(in string) string { u, err := url.Parse(in) if err != nil { return "" } if u.Scheme == "file" { return u.Path } return in } func (ai *DesktopAppInfo) expandFieldCode(cmdline, files []string) ([]string, error) { return expandFieldCode(cmdline, files, ai.GetName(), ai.GetIcon(), ai.GetFileName()) } var ErrBadFieldCode = errors.New("bad field code") func expandFieldCode(cmdline, files []string, translatedName, icon, desktopFile string) ([]string, error) { // element of files can be local path (starts with /) or uri (starts with file:///) var ret []string var buf bytes.Buffer submitBuf := func() { ret = append(ret, buf.String()) buf.Reset() } for _, arg := range cmdline { argR := strings.NewReader(arg) for { c, err := argR.ReadByte() if err != nil { break } if c == '%' { fieldCode, err := argR.ReadByte() if err != nil { break } switch fieldCode { case 'f': // a single file name if len(files) > 0 { buf.WriteString(toLocalPath(files[0])) } case 'F': // a list of files for _, file := range files { buf.WriteString(toLocalPath(file)) submitBuf() } case 'u': // a single URL if len(files) > 0 { buf.WriteString(toURL(files[0])) } case 'U': // a list of URLs for _, file := range files { buf.WriteString(toURL(file)) submitBuf() } case 'i': // icon if icon != "" { buf.WriteString("--icon") submitBuf() buf.WriteString(icon) } case 'c': // translated name buf.WriteString(translatedName) case 'k': // location of desktop file or URI buf.WriteString(desktopFile) case '%': buf.WriteByte('%') case 'd', 'D', 'n', 'N', 'v', 'm': // Deprecated default: return nil, ErrBadFieldCode } } else { buf.WriteByte(c) } } if len(buf.Bytes()) > 0 { submitBuf() } } return ret, nil } go-lib-5.6.0.9/appinfo/desktopappinfo/fail_detector_test.go000664 000000 000000 00000002206 13753517240 023705 0ustar00rootroot000000 000000 package desktopappinfo import ( "testing" "github.com/stretchr/testify/assert" ) // 测试简单的情况 func TestFailDetectorSimple(t *testing.T) { ch := make(chan struct{}) fd := newFailDetector(ch) _, err := fd.Write([]byte("Failed to invoke: Booster: abcdef")) assert.Nil(t, err) assert.True(t, fd.done) fd = newFailDetector(ch) _, err = fd.Write([]byte("deepin-turbo-invoker: error: xxxx not a file\n")) assert.Nil(t, err) assert.True(t, fd.done) } // 测试多次写入,\n 后有其他字符的情况 func TestFailDetectorWrite(t *testing.T) { ch := make(chan struct{}) fd := newFailDetector(ch) _, err := fd.Write([]byte("line1\n")) assert.Nil(t, err) assert.False(t, fd.done) assert.Len(t, fd.buf.Bytes(), 0) _, err = fd.Write([]byte("line2\nabc")) assert.Nil(t, err) assert.False(t, fd.done) assert.Equal(t, []byte("abc"), fd.buf.Bytes()) _, err = fd.Write(nil) assert.Nil(t, err) assert.False(t, fd.done) assert.Equal(t, []byte("abc"), fd.buf.Bytes()) _, err = fd.Write([]byte("abc-abc\nFailed to invoke: Booster: abcdef\nline 3")) assert.Nil(t, err) assert.True(t, fd.done) assert.Zero(t, fd.buf.Bytes()) } go-lib-5.6.0.9/appinfo/desktopappinfo/get_all.go000664 000000 000000 00000006136 13753517240 021457 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package desktopappinfo import ( "os" "path/filepath" "strings" //"fmt" ) type AppsDir struct { Path string AppNames map[string]int } func getDirs(skipDirs map[string][]string) []AppsDir { var dirs []AppsDir for _, path := range xdgAppDirs { appsDir := AppsDir{ Path: path, } appsDir.AppNames = getAppNames(path, skipDirs[path]) dirs = append(dirs, appsDir) } return dirs } func GetAll(skipDirs map[string][]string) []*DesktopAppInfo { var infos []*DesktopAppInfo dirs := getDirs(skipDirs) infoMap := make(map[string]int) var count int for _, dir := range dirs { for appName := range dir.AppNames { if count > 0 { if _, ok := infoMap[appName]; ok { // appName masked continue } } filename := filepath.Join(dir.Path, appName) ai, err := NewDesktopAppInfoFromFile(filename) if err != nil { continue } infoMap[appName] = 0 if ai.ShouldShow() { infos = append(infos, ai) } } count++ } return infos } func getAppNames(root string, skipDirs []string) map[string]int { ret := make(map[string]int) Walk(root, func(name string, info os.FileInfo) bool { if info.IsDir() { return stringSliceContains(skipDirs, name) } if strings.HasSuffix(name, desktopExt) { ret[name] = 0 } return false }) return ret } func readDirNames(dirname string) ([]string, error) { f, err := os.Open(dirname) if err != nil { return nil, err } names, err := f.Readdirnames(-1) f.Close() if err != nil { return nil, err } return names, nil } func Walk(root string, walkFn WalkFunc) { info, err := os.Lstat(root) if err != nil { return } walk(root, ".", info, walkFn) } func walk(root, name0 string, info os.FileInfo, walkFn WalkFunc) { //fmt.Println("root:", root, "name0:", name0) skipDir := walkFn(name0, info) if skipDir { //fmt.Println("skip ", name0) return } if !info.IsDir() { return } path := filepath.Join(root, name0) names, err := readDirNames(path) if err != nil { return } for _, name := range names { filename := filepath.Join(path, name) fileInfo, err := os.Lstat(filename) if err != nil { continue } walk(root, filepath.Join(name0, name), fileInfo, walkFn) } } type WalkFunc func(name string, info os.FileInfo) bool func stringSliceContains(slice []string, str string) bool { for _, v := range slice { if str == v { return true } } return false } go-lib-5.6.0.9/appinfo/desktopappinfo/testdata/000775 000000 000000 00000000000 13753517240 021324 5ustar00rootroot000000 000000 go-lib-5.6.0.9/appinfo/desktopappinfo/testdata/applications/000775 000000 000000 00000000000 13753517240 024012 5ustar00rootroot000000 000000 go-lib-5.6.0.9/appinfo/desktopappinfo/testdata/applications/deepin-screenshot.desktop000664 000000 000000 00000000737 13753517240 031033 0ustar00rootroot000000 000000 [Desktop Entry] Categories=Graphics;GTK; Comment=Screen capturing application Exec=deepin-screenshot --icon GenericName=Screen capturing application Icon=deepin-screenshot Name=Deepin Screenshot Name[xy_XY.UTF-8@abc123]=test StartupNotify=false Type=Application [Full_Screenshot Shortcut Group] Exec=deepin-screenshot -f Name=Full Screenshot Name[zh_CN]=全屏截图 [Delay_Screenshot Shortcut Group] Exec=deepin-screenshot -d 5 Name=Delay Screenshot Name[zh_CN]=延时截图 go-lib-5.6.0.9/appinfo/startup_notify_msg.go000664 000000 000000 00000005344 13753517240 020762 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package appinfo import ( "bytes" "io" "github.com/linuxdeepin/go-x11-client" ) type StartupNotifyMessage struct { Type string KeyValues map[string]string } func (msg *StartupNotifyMessage) fillBuffer() *bytes.Buffer { var buf bytes.Buffer buf.WriteString(msg.Type) buf.WriteByte(':') for k, v := range msg.KeyValues { buf.WriteString(k) buf.WriteString(`="`) vlen := len(v) for i := 0; i < vlen; i++ { b := v[i] switch b { case 0, ' ', '"', '\\': buf.WriteByte('\\') } buf.WriteByte(b) } buf.WriteString(`" `) } buf.WriteByte(0) return &buf } func (msg *StartupNotifyMessage) Broadcast(conn *x.Conn) error { atomMsgType, err := conn.GetAtom("_NET_STARTUP_INFO") if err != nil { return err } atomMsgTypeBegin, err := conn.GetAtom("_NET_STARTUP_INFO_BEGIN") if err != nil { return err } return broadcastXMessage(conn, atomMsgType, atomMsgTypeBegin, msg.fillBuffer()) } func broadcastXMessage(conn *x.Conn, atomMsgType, atomMsgTypeBegin x.Atom, msgReader io.Reader) error { // create window xid, err := conn.AllocID() if err != nil { return err } defer func() { _ = conn.FreeID(xid) }() win := x.Window(xid) root := conn.GetDefaultScreen().Root err = x.CreateWindowChecked(conn, 0, win, root, 0, 0, 1, 1, 0, x.WindowClassInputOnly, x.CopyFromParent, x.CWOverrideRedirect|x.CWEventMask, []uint32{1, x.EventMaskPropertyChange | x.EventMaskStructureNotify}).Check(conn) if err != nil { return err } // send x message ev := x.ClientMessageEvent{ Format: 8, Window: win, Type: atomMsgTypeBegin, } var buf [20]byte var readDone bool for !readDone { n, err := msgReader.Read(buf[:]) if err != nil { // EOF readDone = true } if n == 0 { break } ev.Data = x.ClientMessageData{} ev.Data.SetData8(&buf) w := x.NewWriter() x.WriteClientMessageEvent(w, &ev) x.SendEvent(conn, false, root, x.EventMaskPropertyChange, w.Bytes()) ev.Type = atomMsgType } x.DestroyWindow(conn, win) conn.Flush() return nil } go-lib-5.6.0.9/arch/000775 000000 000000 00000000000 13753517240 013746 5ustar00rootroot000000 000000 go-lib-5.6.0.9/arch/arch.go000664 000000 000000 00000001767 13753517240 015225 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package arch import ( "runtime" ) type ArchFamilyType int const ( Unknown ArchFamilyType = iota AMD64 Sunway ) func Get() ArchFamilyType { switch runtime.GOARCH { case "sw_64": return Sunway case "amd64": return AMD64 default: return Unknown } } go-lib-5.6.0.9/archive/000775 000000 000000 00000000000 13753517240 014452 5ustar00rootroot000000 000000 go-lib-5.6.0.9/archive/archive.go000664 000000 000000 00000004600 13753517240 016422 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package archive import ( "fmt" "strings" "pkg.deepin.io/lib/archive/gzip" ) const ( CompressTypeUnkown int32 = iota CompressTypeTar CompressTypeTarGz CompressTypeTarBz2 CompressTypeZip ) func CompressDir(src, dest string) error { switch getCompressType(dest) { case CompressTypeTar: return tarCompressFiles([]string{src}, dest) case CompressTypeTarGz: return gzip.CompressDir(src, dest, gzip.ArchiveTypeTar) case CompressTypeTarBz2: return nil case CompressTypeZip: return nil default: return fmt.Errorf("Invalid archive compress type") } } func CompressFiles(files []string, dest string) error { switch getCompressType(dest) { case CompressTypeTar: return tarCompressFiles(files, dest) case CompressTypeTarGz: return gzip.CompressFiles(files, dest, gzip.ArchiveTypeTar) case CompressTypeTarBz2: return nil case CompressTypeZip: return nil default: return fmt.Errorf("Invalid archive compress type") } } func Extracte(src, dest string) ([]string, error) { switch getCompressType(src) { case CompressTypeTar: return tarExtracteFile(src, dest) case CompressTypeTarGz: return gzip.Extracte(src, dest, gzip.ArchiveTypeTar) case CompressTypeTarBz2: return nil, nil case CompressTypeZip: return nil, nil default: return nil, fmt.Errorf("Invalid archive compress type") } } func getCompressType(file string) int32 { switch { case strings.HasSuffix(file, "tar"): return CompressTypeTar case strings.HasSuffix(file, "tar.gz"): return CompressTypeTarGz case strings.HasSuffix(file, "tar.ba2"): return CompressTypeTarBz2 case strings.HasSuffix(file, "zip"): return CompressTypeZip } return CompressTypeUnkown } go-lib-5.6.0.9/archive/archive_test.go000664 000000 000000 00000004140 13753517240 017460 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package archive import ( C "gopkg.in/check.v1" "os" "testing" ) type testWrapper struct{} func init() { C.Suite(&testWrapper{}) } func Test(t *testing.T) { C.TestingT(t) } func (*testWrapper) TestTarCompresssFiles(c *C.C) { var infos = []struct { files []string dest string errIsNil bool }{ { files: []string{"testdata/tar-compress-datas"}, dest: "testdata/tmp-compress.tar", errIsNil: true, }, { files: []string{"testdata/xxxxx"}, dest: "testdata/xxxxx", errIsNil: false, }, } for _, info := range infos { err := tarCompressFiles(info.files, info.dest) if !info.errIsNil { c.Check(err, C.Not(C.Equals), nil) } else { c.Check(err, C.Equals, nil) } os.Remove(info.dest) } } func (*testWrapper) TestTarExtracteFile(c *C.C) { var infos = []struct { src string dest string fileNum int errIsNil bool }{ { src: "testdata/tar-extracte-data.tar", dest: "testdata/tmp-extracte", fileNum: 2, errIsNil: true, }, { src: "testdata/xxxxx", dest: "testdata/xxxxx", errIsNil: false, }, } for _, info := range infos { files, err := tarExtracteFile(info.src, info.dest) if !info.errIsNil { c.Check(err, C.Not(C.Equals), nil) continue } c.Check(err, C.Equals, nil) c.Check(info.fileNum, C.Equals, len(files)) os.RemoveAll(info.dest) } } go-lib-5.6.0.9/archive/gzip/000775 000000 000000 00000000000 13753517240 015423 5ustar00rootroot000000 000000 go-lib-5.6.0.9/archive/gzip/gzip.go000664 000000 000000 00000003230 13753517240 016721 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gzip import ( "fmt" ) const ( ArchiveTypeTar int32 = iota + 1 ArchiveTypeZip ArchiveTypeRar ) func CompressDir(src, dest string, t int32) error { switch t { case ArchiveTypeTar: return tarCompressFiles([]string{src}, dest) case ArchiveTypeZip: return nil case ArchiveTypeRar: return nil default: return fmt.Errorf("Invalid archive type: %q", t) } } func CompressFiles(files []string, dest string, t int32) error { switch t { case ArchiveTypeTar: return tarCompressFiles(files, dest) case ArchiveTypeZip: return nil case ArchiveTypeRar: return nil default: return fmt.Errorf("Invalid archive type: %q", t) } } func Extracte(src, destDir string, t int32) ([]string, error) { switch t { case ArchiveTypeTar: return tarExtracte(src, destDir) case ArchiveTypeZip: return nil, nil case ArchiveTypeRar: return nil, nil default: return nil, fmt.Errorf("Invalid archive type: %q", t) } } go-lib-5.6.0.9/archive/gzip/gzip_test.go000664 000000 000000 00000004137 13753517240 017767 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gzip import ( C "gopkg.in/check.v1" "os" "testing" ) type testWrapper struct{} func init() { C.Suite(&testWrapper{}) } func Test(t *testing.T) { C.TestingT(t) } func (*testWrapper) TestTarCompresssFiles(c *C.C) { var infos = []struct { files []string dest string errIsNil bool }{ { files: []string{"testdata/tar-compress-datas"}, dest: "testdata/tmp-compress.tar.gz", errIsNil: true, }, { files: []string{"testdata/xxxxx"}, dest: "testdata/xxxxx", errIsNil: false, }, } for _, info := range infos { err := tarCompressFiles(info.files, info.dest) if !info.errIsNil { c.Check(err, C.Not(C.Equals), nil) } else { c.Check(err, C.Equals, nil) } os.Remove(info.dest) } } func (*testWrapper) TestTarExtracteFile(c *C.C) { var infos = []struct { src string dest string fileNum int errIsNil bool }{ { src: "testdata/tar-extracte-data.tar.gz", dest: "testdata/tmp-extracte", fileNum: 2, errIsNil: true, }, { src: "testdata/xxxxx", dest: "testdata/xxxxx", errIsNil: false, }, } for _, info := range infos { files, err := tarExtracte(info.src, info.dest) if !info.errIsNil { c.Check(err, C.Not(C.Equals), nil) continue } c.Check(err, C.Equals, nil) c.Check(info.fileNum, C.Equals, len(files)) os.RemoveAll(info.dest) } } go-lib-5.6.0.9/archive/gzip/tar.go000664 000000 000000 00000002603 13753517240 016541 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gzip import ( "archive/tar" "compress/gzip" "os" "pkg.deepin.io/lib/archive/utils" ) func tarCompressFiles(files []string, dest string) error { dw, err := os.Create(dest) if err != nil { return err } defer dw.Close() gw := gzip.NewWriter(dw) defer gw.Close() tw := tar.NewWriter(gw) defer tw.Close() return utils.TarWriterCompressFiles(tw, files) } func tarExtracte(src, dest string) ([]string, error) { sr, err := os.Open(src) if err != nil { return nil, err } defer sr.Close() gr, err := gzip.NewReader(sr) if err != nil { return nil, err } defer gr.Close() return utils.TarReaderExtracte(tar.NewReader(gr), dest) } go-lib-5.6.0.9/archive/gzip/testdata/000775 000000 000000 00000000000 13753517240 017234 5ustar00rootroot000000 000000 go-lib-5.6.0.9/archive/gzip/testdata/tar-compress-datas/000775 000000 000000 00000000000 13753517240 022745 5ustar00rootroot000000 000000 go-lib-5.6.0.9/archive/gzip/testdata/tar-compress-datas/data1000664 000000 000000 00000000006 13753517240 023656 0ustar00rootroot000000 000000 12345 go-lib-5.6.0.9/archive/gzip/testdata/tar-compress-datas/data2000664 000000 000000 00000000006 13753517240 023657 0ustar00rootroot000000 000000 abcde go-lib-5.6.0.9/archive/gzip/testdata/tar-extracte-data.tar.gz000664 000000 000000 00000000200 13753517240 023665 0ustar00rootroot000000 000000  n*I,M-(J-.MI,I,F T3$6P؈An JARs=7D@bRrJ*@b  iYp4Q0 F(q go-lib-5.6.0.9/archive/tar.go000664 000000 000000 00000002365 13753517240 015575 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package archive import ( "archive/tar" "os" "pkg.deepin.io/lib/archive/utils" ) func tarCompressFiles(files []string, dest string) error { dw, err := os.Create(dest) if err != nil { return err } defer dw.Close() tw := tar.NewWriter(dw) defer tw.Close() return utils.TarWriterCompressFiles(tw, files) } func tarExtracteFile(src, dest string) ([]string, error) { sr, err := os.Open(src) if err != nil { return nil, err } defer sr.Close() return utils.TarReaderExtracte(tar.NewReader(sr), dest) } go-lib-5.6.0.9/archive/testdata/000775 000000 000000 00000000000 13753517240 016263 5ustar00rootroot000000 000000 go-lib-5.6.0.9/archive/testdata/tar-compress-datas/000775 000000 000000 00000000000 13753517240 021774 5ustar00rootroot000000 000000 go-lib-5.6.0.9/archive/testdata/tar-compress-datas/data1000664 000000 000000 00000000006 13753517240 022705 0ustar00rootroot000000 000000 12345 go-lib-5.6.0.9/archive/testdata/tar-compress-datas/data2000664 000000 000000 00000000006 13753517240 022706 0ustar00rootroot000000 000000 abcde go-lib-5.6.0.9/archive/testdata/tar-extracte-data.tar000664 000000 000000 00000006000 13753517240 022301 0ustar00rootroot000000 000000 tar-compress-datas/data20000000000000000000000000000000600000000000013532 ustar0000000000000000abcde tar-compress-datas/data10000000000000000000000000000000600000000000013531 ustar000000000000000012345 go-lib-5.6.0.9/archive/utils/000775 000000 000000 00000000000 13753517240 015612 5ustar00rootroot000000 000000 go-lib-5.6.0.9/archive/utils/tar.go000664 000000 000000 00000005703 13753517240 016734 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package utils import ( "archive/tar" "fmt" "io" "os" "path" dutils "pkg.deepin.io/lib/utils" ) func TarWriterCompressFiles(writer *tar.Writer, files []string) error { if writer == nil { return fmt.Errorf("Invalid tar writer") } for _, file := range files { var err error if dutils.IsDir(file) { err = tarWriterCompressDir(writer, file, "") } else { err = tarWriterCompressFile(writer, file, "") } if err != nil { return err } } return nil } func TarReaderExtracte(reader *tar.Reader, dest string) ([]string, error) { if reader == nil { return nil, fmt.Errorf("Invalid tar reader") } var files []string for { h, err := reader.Next() if err == io.EOF { break } if err != nil { return nil, err } tmp := path.Join(dest, h.Name) if h.FileInfo().IsDir() { err = os.MkdirAll(tmp, 0755) if err != nil { return nil, err } continue } err = os.MkdirAll(path.Dir(tmp), 0755) if err != nil { return nil, err } fw, err := os.OpenFile(tmp, os.O_CREATE|os.O_WRONLY, os.FileMode(h.Mode)) if err != nil { return nil, err } _, err = io.Copy(fw, reader) fw.Close() if err != nil { return nil, err } files = append(files, tmp) } return files, nil } func tarWriterCompressDir(tw *tar.Writer, dir, parent string) error { dr, err := os.Open(dir) if err != nil { return err } defer dr.Close() finfos, err := dr.Readdir(0) if err != nil { return err } parent = path.Join(parent, path.Base(dir)) for _, finfo := range finfos { file := path.Join(dir, finfo.Name()) var err error if finfo.IsDir() { err = tarWriterCompressDir(tw, file, parent) } else { err = tarWriterCompressFile(tw, file, parent) } if err != nil { return err } } return nil } func tarWriterCompressFile(tw *tar.Writer, file, parent string) error { fr, err := os.Open(file) if err != nil { return err } defer fr.Close() finfo, err := fr.Stat() if err != nil { return err } h := new(tar.Header) h.Name = path.Join(parent, finfo.Name()) h.Size = finfo.Size() h.Mode = 0644 //h.ModTime = finfo.ModTime() err = tw.WriteHeader(h) if err != nil { return err } _, err = io.Copy(tw, fr) if err != nil { return err } return nil } go-lib-5.6.0.9/asound/000775 000000 000000 00000000000 13753517240 014322 5ustar00rootroot000000 000000 go-lib-5.6.0.9/asound/asound.go000664 000000 000000 00000127220 13753517240 016146 0ustar00rootroot000000 000000 package asound /* #cgo pkg-config: alsa #include #include #include */ import "C" import ( "errors" "fmt" "unsafe" ) // Format is the type used for specifying sample formats. type PCMFormat C.snd_pcm_format_t // The range of sample formats supported by ALSA. const ( PCMFormatS8 = C.SND_PCM_FORMAT_S8 PCMFormatU8 = C.SND_PCM_FORMAT_U8 PCMFormatS16LE = C.SND_PCM_FORMAT_S16_LE PCMFormatS16BE = C.SND_PCM_FORMAT_S16_BE PCMFormatU16LE = C.SND_PCM_FORMAT_U16_LE PCMFormatU16BE = C.SND_PCM_FORMAT_U16_BE PCMFormatS24LE = C.SND_PCM_FORMAT_S24_LE PCMFormatS24BE = C.SND_PCM_FORMAT_S24_BE PCMFormatU24LE = C.SND_PCM_FORMAT_U24_LE PCMFormatU24BE = C.SND_PCM_FORMAT_U24_BE PCMFormatS32LE = C.SND_PCM_FORMAT_S32_LE PCMFormatS32BE = C.SND_PCM_FORMAT_S32_BE PCMFormatU32LE = C.SND_PCM_FORMAT_U32_LE PCMFormatU32BE = C.SND_PCM_FORMAT_U32_BE PCMFormatFloatLE = C.SND_PCM_FORMAT_FLOAT_LE PCMFormatFloatBE = C.SND_PCM_FORMAT_FLOAT_BE PCMFormatFloat64LE = C.SND_PCM_FORMAT_FLOAT64_LE PCMFormatFloat64BE = C.SND_PCM_FORMAT_FLOAT64_BE ) // Size return bytes needed to store a quantity of PCM sample. func (format PCMFormat) Size(samples uint) int { ret := C.snd_pcm_format_size(C.snd_pcm_format_t(format), C.size_t(samples)) return int(ret) } func (format PCMFormat) Name() string { ret := C.snd_pcm_format_name(C.snd_pcm_format_t(format)) return C.GoString(ret) } // PCM sample subformat type PCMSubformat C.snd_pcm_subformat_t func (subformat PCMSubformat) Name() string { ret := C.snd_pcm_subformat_name(C.snd_pcm_subformat_t(subformat)) return C.GoString(ret) } func (subformat PCMSubformat) Desc() string { ret := C.snd_pcm_subformat_description(C.snd_pcm_subformat_t(subformat)) return C.GoString(ret) } // Internal structure for an output object. // // The ALSA library uses a pointer to this structure as a handle to an output object. Applications don't access its contents directly. type Output struct { Ptr unsafe.Pointer } func (v Output) native() *C.snd_output_t { return (*C.snd_output_t)(v.Ptr) } // Creates a new output object writing to a file. func OpenOutput(file, mode string) (Output, error) { file0 := C.CString(file) mode0 := C.CString(mode) var outputPtr *C.snd_output_t ret := C.snd_output_stdio_open(&outputPtr, file0, mode0) C.free(unsafe.Pointer(file0)) C.free(unsafe.Pointer(mode0)) if ret == 0 { return Output{unsafe.Pointer(outputPtr)}, nil } return Output{}, newError("snd_output_stdio_open", ret) } // Flushes an output handle (like fflush(3)). func (o Output) Flush() error { ret := C.snd_output_flush(o.native()) return newError("snd_output_flush", ret) } // Writes a string to an output handle (like fputs(3)). func (o Output) WriteString(str string) error { str0 := C.CString(str) ret := C.snd_output_puts(o.native(), str0) C.free(unsafe.Pointer(str0)) return newError("snd_output_puts", ret) } func (o Output) Println(a ...interface{}) error { str := fmt.Sprintln(a...) return o.WriteString(str) } func (o Output) Printf(format string, a ...interface{}) error { str := fmt.Sprintf(format, a...) return o.WriteString(str) } // Closes an output handle. func (o Output) Close() error { ret := C.snd_output_close(o.native()) return newError("snd_output_close", ret) } // PCM handle type PCM struct { Ptr unsafe.Pointer } func (v PCM) native() *C.snd_pcm_t { return (*C.snd_pcm_t)(v.Ptr) } func wrapPCM(ptr *C.snd_pcm_t) PCM { return PCM{Ptr: unsafe.Pointer(ptr)} } // PCM type type PCMType C.snd_pcm_type_t func (typ PCMType) Name() string { ret := C.snd_pcm_type_name(C.snd_pcm_type_t(typ)) return C.GoString(ret) } // PCM Stream type PCMStream C.snd_pcm_stream_t const ( PCMStreamPlayback = C.SND_PCM_STREAM_PLAYBACK PCMStreamCapture = C.SND_PCM_STREAM_CAPTURE ) func (stream PCMStream) Name() string { ret := C.snd_pcm_stream_name(C.snd_pcm_stream_t(stream)) return C.GoString(ret) } // Opens a PCM. func OpenPCM(name string, stream PCMStream, mode int) (PCM, error) { var pcmp *C.snd_pcm_t name0 := C.CString(name) ret := C.snd_pcm_open(&pcmp, name0, C.snd_pcm_stream_t(stream), C.int(mode)) C.free(unsafe.Pointer(name0)) if ret == 0 { return wrapPCM(pcmp), nil } return PCM{}, newError("snd_pcm_open", ret) } // get identifier of PCM handle func (pcm PCM) Name() string { ret := C.snd_pcm_name(pcm.native()) return C.GoString(ret) } // get type of PCM handle func (pcm PCM) Type() PCMType { typ := C.snd_pcm_type(pcm.native()) return PCMType(typ) } // get stream for a PCM handle func (pcm PCM) Stream() PCMStream { stream := C.snd_pcm_stream(pcm.native()) return PCMStream(stream) } // Obtain general (static) information for PCM handle. func (pcm PCM) Info(info PCMInfo) error { ret := C.snd_pcm_info(pcm.native(), info.native()) return newError("snd_pcm_info", ret) } // Stop a PCM preserving pending frames. // // For playback wait for all pending frames to be played and then stop the PCM. For capture stop PCM permitting to retrieve residual frames. func (pcm PCM) Drain() error { ret := C.snd_pcm_drain(pcm.native()) return newError("snd_pcm_drain", ret) } // Stop a PCM dropping pending frames. // // This function stops the PCM immediately. The pending samples on the buffer are ignored. func (pcm PCM) Drop() error { ret := C.snd_pcm_drop(pcm.native()) return newError("snd_pcm_drop", ret) } // Pause/resume PCM. func (pcm PCM) Pause(enable bool) error { var val C.int if enable { val = 1 } ret := C.snd_pcm_pause(pcm.native(), val) return newError("snd_pcm_pause", ret) } // Prepare PCM for use. func (pcm PCM) Prepare() error { ret := C.snd_pcm_prepare(pcm.native()) return newError("snd_pcm_prepare", ret) } // close PCM handle // // Closes the specified PCM handle and frees all associated resources. func (pcm PCM) Close() error { ret := C.snd_pcm_close(pcm.native()) return newError("snd_pcm_close", ret) } // Recover the stream state from an error or suspend. // // This a high-level helper function building on other functions. // //This functions handles -EINTR (interrupted system call), -EPIPE (overrun or underrun) and -ESTRPIPE (stream is suspended) error codes trying to prepare given stream for next I/O. // //Note that this function returs the original error code when it is not handled inside this function (for example -EAGAIN is returned back). func (pcm PCM) Recover(err int, silent bool) error { var silent0 C.int if silent { silent0 = 1 } ret := C.snd_pcm_recover(pcm.native(), C.int(err), silent0) return newError("snd_pcm_recover", ret) } // Remove PCM hardware configuration and free associated resources. func (pcm PCM) HwFree() error { ret := C.snd_pcm_hw_free(pcm.native()) return newError("snd_pcm_hw_free", ret) } // Start a PCM. func (pcm PCM) Start() error { ret := C.snd_pcm_start(pcm.native()) return newError("snd_pcm_start", ret) } // Resume from suspend, no samples are lost. // // This function can be used when the stream is in the suspend state to do the fine resume from this state. Not all hardware supports this feature, when an -ENOSYS error is returned, use the PCM.Prepare() function to recovery. func (pcm PCM) Resume() error { ret := C.snd_pcm_resume(pcm.native()) return newError("snd_pcm_resume", ret) } // Reset PCM position. // // Reduce PCM delay to 0. func (pcm PCM) Reset() error { ret := C.snd_pcm_reset(pcm.native()) return newError("snd_pcm_reset", ret) } func (pcm PCM) DumpHwSetup(out Output) error { ret := C.snd_pcm_dump_hw_setup(pcm.native(), out.native()) return newError("snd_pcm_dump_hw_setup", ret) } func (pcm PCM) DumpSwSetup(out Output) error { ret := C.snd_pcm_dump_sw_setup(pcm.native(), out.native()) return newError("snd_pcm_dump_sw_setup", ret) } func (pcm PCM) DumpSetup(out Output) error { ret := C.snd_pcm_dump_setup(pcm.native(), out.native()) return newError("snd_pcm_dump_setup", ret) } func (pcm PCM) Dump(out Output) error { ret := C.snd_pcm_dump(pcm.native(), out.native()) return newError("snd_pcm_dump", ret) } // PCM state type PCMState C.snd_pcm_state_t // Return PCM state. // // This is a faster way to obtain only the PCM state without calling PCM.Status(). func (pcm PCM) State() PCMState { ret := C.snd_pcm_state(pcm.native()) return PCMState(ret) } // Signed frames quantity type PCMSFrames C.snd_pcm_sframes_t var ErrUnderrun = errors.New("underrun") // Write interleaved frames to a PCM. // // If the blocking behaviour is selected and it is running, then routine waits until all requested frames are played or put to the playback ring buffer. The returned number of frames can be less only if a signal or underrun occurred. // //If the non-blocking behaviour is selected, then routine doesn't wait at all. func (pcm PCM) Writei(buffer unsafe.Pointer, size PCMUFrames) (PCMUFrames, error) { ret := C.snd_pcm_writei(pcm.native(), buffer, C.snd_pcm_uframes_t(size)) if ret == -C.EPIPE { return 0, ErrUnderrun } else if ret < 0 { return 0, newError("snd_pcm_writei", C.int(ret)) } return PCMUFrames(ret), nil } // PCM hardware configuration space container // // snd_pcm_hw_params_t is an opaque structure which contains a set of possible PCM hardware configurations. For example, a given instance might include a range of buffer sizes, a range of period sizes, and a set of several sample formats. Some subset of all possible combinations these sets may be valid, but not necessarily any combination will be valid. // // When a parameter is set or restricted using a snd_pcm_hw_params_set* function, all of the other ranges will be updated to exclude as many impossible configurations as possible. Attempting to set a parameter outside of its acceptable range will result in the function failing and an error code being returned. type PCMHwParams struct { Ptr unsafe.Pointer } func wrapPCMHwParams(ptr *C.snd_pcm_hw_params_t) PCMHwParams { return PCMHwParams{Ptr: unsafe.Pointer(ptr)} } func (v PCMHwParams) native() *C.snd_pcm_hw_params_t { return (*C.snd_pcm_hw_params_t)(v.Ptr) } func NewPCMHwParams() (PCMHwParams, error) { var params *C.snd_pcm_hw_params_t ret := C.snd_pcm_hw_params_malloc(¶ms) if ret == 0 { return wrapPCMHwParams(params), nil } return PCMHwParams{}, newError("snd_pcm_hw_params_malloc", ret) } func (params PCMHwParams) Free() { C.snd_pcm_hw_params_free(params.native()) } // Dump a PCM hardware configuration space. func (params PCMHwParams) Dump(out Output) error { ret := C.snd_pcm_hw_params_dump(params.native(), out.native()) return newError("snd_pcm_hw_params_dump", ret) } // PCM access type type PCMAccess C.snd_pcm_access_t const ( PCMAccessMMapInterleaved = C.SND_PCM_ACCESS_MMAP_INTERLEAVED PCMAccessMMapNonInterleaved = C.SND_PCM_ACCESS_MMAP_NONINTERLEAVED PCMAccessMMapComplex = C.SND_PCM_ACCESS_MMAP_COMPLEX PCMAccessRWInterleaved = C.SND_PCM_ACCESS_RW_INTERLEAVED PCMAccessRWNonInterleaved = C.SND_PCM_ACCESS_RW_NONINTERLEAVED ) // get name of PCM access type func (access PCMAccess) Name() string { ret := C.snd_pcm_access_name(C.snd_pcm_access_t(access)) return C.GoString(ret) } // Fill params with a full configuration space for a PCM. // // The configuration space will be filled with all possible ranges for the PCM device. func (pcm PCM) HwParamsAny(params PCMHwParams) { C.snd_pcm_hw_params_any(pcm.native(), params.native()) } // Install one PCM hardware configuration chosen from a configuration space and snd_pcm_prepare it. // // The configuration is chosen fixing single parameters in this order: first access, first format, first subformat, min channels, min rate, min period time, max buffer size, min tick time. If no mutually compatible set of parameters can be chosen, a negative error code will be returned. // //After this call, snd_pcm_prepare() is called automatically and the stream is brought to SND_PCM_STATE_PREPARED state. // //The hardware parameters cannot be changed when the stream is running (active). The software parameters can be changed at any time. // //The configuration space will be updated to reflect the chosen parameters. func (pcm PCM) HwParams(params PCMHwParams) error { ret := C.snd_pcm_hw_params(pcm.native(), params.native()) return newError("snd_pcm_hw_params", ret) } // Restrict a configuration space to contain only one access type. func (pcm PCM) HwParamsSetAccess(params PCMHwParams, access PCMAccess) error { ret := C.snd_pcm_hw_params_set_access(pcm.native(), params.native(), C.snd_pcm_access_t(access)) return newError("snd_pcm_hw_params_set_access", ret) } // Restrict a configuration space to contain only one format. func (pcm PCM) HwParamsSetFormat(params PCMHwParams, format PCMFormat) error { ret := C.snd_pcm_hw_params_set_format(pcm.native(), params.native(), C.snd_pcm_format_t(format)) return newError("snd_pcm_hw_params_set_format", ret) } // Unsigned frames quantity type PCMUFrames C.snd_pcm_uframes_t // Restrict a configuration space to contain only one buffer size. func (pcm PCM) HwParamsSetBufferSize(params PCMHwParams, val PCMUFrames) error { ret := C.snd_pcm_hw_params_set_buffer_size(pcm.native(), params.native(), C.snd_pcm_uframes_t(val)) return newError("snd_pcm_hw_params_set_buffer_size", ret) } // Extract maximum buffer time from a configuration space. // val approximate maximum buffer duration in us func (params PCMHwParams) GetBufferTimeMax() (val uint, dir int, err error) { var val0 C.uint var dir0 C.int ret := C.snd_pcm_hw_params_get_buffer_time_max(params.native(), &val0, &dir0) err = newError("snd_pcm_hw_params_get_buffer_time_max", ret) if err != nil { return } val = uint(val0) dir = int(dir0) return } // Restrict a configuration space to contain only one channels count. func (pcm PCM) HwParamsSetChannels(params PCMHwParams, val uint) error { ret := C.snd_pcm_hw_params_set_channels(pcm.native(), params.native(), C.uint(val)) return newError("snd_pcm_hw_params_set_channels", ret) } // Restrict a configuration space to contain only one rate. func (pcm PCM) HwParamsSetRate(params PCMHwParams, val uint, dir int) error { ret := C.snd_pcm_hw_params_set_rate(pcm.native(), params.native(), C.uint(val), C.int(dir)) return newError("snd_pcm_hw_params_set_rate", ret) } // Restrict a configuration space to have rate nearest to a target. func (pcm PCM) HwParamsSetRateNear(params PCMHwParams, val *uint) (int, error) { cVal := C.uint(*val) var dir C.int ret := C.snd_pcm_hw_params_set_rate_near(pcm.native(), params.native(), &cVal, &dir) if ret == 0 { *val = uint(cVal) return int(dir), nil } return 0, newError("snd_pcm_hw_params_set_rate_near", ret) } // Restrict a configuration space to have period time nearest to a target. func (pcm PCM) HwParamsSetPeriodTimeNear(params PCMHwParams, val *uint) (int, error) { val0 := C.uint(*val) var dir0 C.int ret := C.snd_pcm_hw_params_set_period_time_near(pcm.native(), params.native(), &val0, &dir0) if ret == 0 { *val = uint(val0) return int(dir0), nil } return 0, newError("snd_pcm_hw_params_set_period_time_near", ret) } // Restrict a configuration space to have buffer time nearest to a target. func (pcm PCM) HwParamsSetBufferTimeNear(params PCMHwParams, val *uint) (int, error) { val0 := C.uint(*val) var dir0 C.int ret := C.snd_pcm_hw_params_set_buffer_time_near(pcm.native(), params.native(), &val0, &dir0) if ret == 0 { *val = uint(val0) return int(dir0), nil } return 0, newError("snd_pcm_hw_params_set_buffer_time_near", ret) } // Restrict a configuration space to contain only one period size. func (pcm PCM) HwParamsSetPeriodSize(params PCMHwParams, val PCMUFrames, dir int) error { ret := C.snd_pcm_hw_params_set_period_size(pcm.native(), params.native(), C.snd_pcm_uframes_t(val), C.int(dir)) return newError("snd_pcm_hw_params_set_period_size", ret) } // Restrict a configuration space to have period size nearest to a target. func (pcm PCM) HwParamsSetPeriodSizeNear(params PCMHwParams, val PCMUFrames) (PCMUFrames, int, error) { cval := C.snd_pcm_uframes_t(val) var dir C.int ret := C.snd_pcm_hw_params_set_period_size_near(pcm.native(), params.native(), &cval, &dir) if ret == 0 { return PCMUFrames(cval), int(dir), nil } return 0, 0, newError("snd_pcm_hw_params_set_period_size_near", ret) } // Extract period size from a configuration space. func (params PCMHwParams) GetPeriodSize() (PCMUFrames, int, error) { var val C.snd_pcm_uframes_t var dir C.int ret := C.snd_pcm_hw_params_get_period_size(params.native(), &val, &dir) if ret == 0 { return PCMUFrames(val), int(dir), nil } return 0, 0, newError("snd_pcm_hw_params_get_period_size", ret) } // Extract period time from a configuration space. time unit us microseconds func (params PCMHwParams) GetPeriodTime() (uint, int, error) { var val C.uint var dir C.int ret := C.snd_pcm_hw_params_get_period_time(params.native(), &val, &dir) if ret == 0 { return uint(val), int(dir), nil } return 0, 0, newError("snd_pcm_hw_params_get_period_time", ret) } const sizeOfPointer = unsafe.Sizeof(unsafe.Pointer(nil)) // Get a set of device name hints. func GetDeviceNameHints(card int, iface string) (DeviceNameHints, error) { iface0 := C.CString(iface) var hints *unsafe.Pointer ret := C.snd_device_name_hint(C.int(card), iface0, &hints) C.free(unsafe.Pointer(iface0)) if ret == 0 { return DeviceNameHints{hints}, nil } return DeviceNameHints{}, newError("snd_device_name_hint", ret) } type DeviceNameHints struct { // it pointer to a array of unsafe.Pointer, type in C is void** Ptr *unsafe.Pointer } func (v DeviceNameHints) Free() { C.snd_device_name_free_hint(v.Ptr) } func (v DeviceNameHints) Iter() *DeviceNameHintsIter { return &DeviceNameHintsIter{ hints: v.Ptr, } } type DeviceNameHintsIter struct { hints, n *unsafe.Pointer } func (iter *DeviceNameHintsIter) Next() bool { if iter.n == nil { // init iter.n iter.n = iter.hints } else { // same as iter.n++ in C iter.n = (*unsafe.Pointer)(unsafe.Pointer( uintptr(unsafe.Pointer(iter.n)) + sizeOfPointer, )) } return *iter.n != nil } func (iter DeviceNameHintsIter) Get(id string) string { id0 := C.CString(id) ret0 := C.snd_device_name_get_hint(*iter.n, id0) ret := C.GoString(ret0) C.free(unsafe.Pointer(ret0)) return ret } // Try to determine the next card. // // Tries to determine the next card from given card number. If card number is -1, then the first available card is returned. If the result card number is -1, no more cards are available. func CardNext(rcard *int) error { rcard0 := C.int(*rcard) ret := C.snd_card_next(&rcard0) *rcard = int(rcard0) return newError("snd_card_next", ret) } // Try to load the driver for a card. // // return true if driver is present, false if driver is not present func CardLoad(card int) bool { ret := C.snd_card_load(C.int(card)) return ret == 1 } // CTL handle type CTL struct { Ptr unsafe.Pointer } func wrapCTL(p *C.snd_ctl_t) CTL { return CTL{ unsafe.Pointer(p), } } func (v CTL) native() *C.snd_ctl_t { return (*C.snd_ctl_t)(v.Ptr) } // Opens a CTL. func CTLOpen(name string, mode int) (CTL, error) { name0 := C.CString(name) var ctlp *C.snd_ctl_t ret := C.snd_ctl_open(&ctlp, name0, C.int(mode)) C.free(unsafe.Pointer(name0)) if ret == 0 { return wrapCTL(ctlp), nil } return CTL{}, newError("snd_ctl_open", ret) } // close CTL handle // // Closes the specified CTL handle and frees all associated resources. func (ctl CTL) Close() error { ret := C.snd_ctl_close(ctl.native()) return newError("snd_ctl_close", ret) } // Get card related information. func (ctl CTL) CardInfo(info CTLCardInfo) error { ret := C.snd_ctl_card_info(ctl.native(), info.native()) return newError("snd_ctl_card_info", ret) } // PCM generic info container type PCMInfo struct { Ptr unsafe.Pointer } func wrapPCMInfo(ptr *C.snd_pcm_info_t) PCMInfo { return PCMInfo{ Ptr: unsafe.Pointer(ptr), } } func NewPCMInfo() (PCMInfo, error) { var p *C.snd_pcm_info_t ret := C.snd_pcm_info_malloc(&p) if ret == 0 { return wrapPCMInfo(p), nil } return PCMInfo{}, newError("snd_pcm_info_malloc", ret) } func (v PCMInfo) native() *C.snd_pcm_info_t { return (*C.snd_pcm_info_t)(v.Ptr) } func (info PCMInfo) Free() { C.snd_pcm_info_free(info.native()) } //Set wanted device inside a PCM info container func (info PCMInfo) SetDevice(val uint) { C.snd_pcm_info_set_device(info.native(), C.uint(val)) } // Set wanted stream inside a PCM info container func (info PCMInfo) SetStream(val PCMStream) { C.snd_pcm_info_set_stream(info.native(), C.snd_pcm_stream_t(val)) } //Set wanted sub device inside a PCM info container func (info PCMInfo) SetSubdevice(val uint) { C.snd_pcm_info_set_subdevice(info.native(), C.uint(val)) } // Get card from a PCM info container. func (info PCMInfo) GetCard() int { ret := C.snd_pcm_info_get_card(info.native()) return int(ret) } // PCM class type PCMClass C.snd_pcm_class_t // Get class from a PCM info container. func (info PCMInfo) GetClass() PCMClass { ret := C.snd_pcm_info_get_class(info.native()) return PCMClass(ret) } // Get id from a PCM info container. func (info PCMInfo) GetID() string { ret := C.snd_pcm_info_get_id(info.native()) return C.GoString(ret) } // Get name from a PCM info container. func (info PCMInfo) GetName() string { ret := C.snd_pcm_info_get_name(info.native()) return C.GoString(ret) } // Get stream (direction) from a PCM info container. func (info PCMInfo) GetStream() PCMStream { ret := C.snd_pcm_info_get_stream(info.native()) return PCMStream(ret) } // PCM subclass type PCMSubclass C.snd_pcm_subclass_t // Get subclass from a PCM info container. func (info PCMInfo) GetSubclass() PCMSubclass { ret := C.snd_pcm_info_get_subclass(info.native()) return PCMSubclass(ret) } // Get subdevice from a PCM info container. func (info PCMInfo) GetSubdevice() uint { ret := C.snd_pcm_info_get_subdevice(info.native()) return uint(ret) } // Get subdevice name from a PCM info container. func (info PCMInfo) GetSubdeviceName() string { ret := C.snd_pcm_info_get_subdevice_name(info.native()) return C.GoString(ret) } // Get available subdevices count from a PCM info container. func (info PCMInfo) GetSubdevicesAvail() uint { ret := C.snd_pcm_info_get_subdevices_avail(info.native()) return uint(ret) } // Get subdevices count from a PCM info container. func (info PCMInfo) GetSubdevicesCount() uint { ret := C.snd_pcm_info_get_subdevices_count(info.native()) return uint(ret) } // Get next PCM device number. func (ctl CTL) PCMNextDevice(device *int) error { device0 := C.int(*device) ret := C.snd_ctl_pcm_next_device(ctl.native(), &device0) *device = int(device0) return newError("snd_ctl_pcm_next_device", ret) } // Get info about a PCM device. func (ctl CTL) PCMInfo(info PCMInfo) error { ret := C.snd_ctl_pcm_info(ctl.native(), info.native()) return newError("snd_ctl_pcm_info", ret) } // CTL card info container type CTLCardInfo struct { Ptr unsafe.Pointer } func (v CTLCardInfo) native() *C.snd_ctl_card_info_t { return (*C.snd_ctl_card_info_t)(v.Ptr) } func wrapCTLCardInfo(ptr *C.snd_ctl_card_info_t) CTLCardInfo { return CTLCardInfo{ Ptr: unsafe.Pointer(ptr), } } func NewCTLCardInfo() (CTLCardInfo, error) { var p *C.snd_ctl_card_info_t ret := C.snd_ctl_card_info_malloc(&p) if ret == 0 { return wrapCTLCardInfo(p), nil } return CTLCardInfo{}, newError("snd_ctl_card_info_malloc", ret) } func (info CTLCardInfo) Free() { C.snd_ctl_card_info_free(info.native()) } // Get card identifier from a CTL card info. func (info CTLCardInfo) GetID() string { ret := C.snd_ctl_card_info_get_id(info.native()) return C.GoString(ret) } // Get card number from a CTL card info. func (info CTLCardInfo) GetCard() int { ret := C.snd_ctl_card_info_get_card(info.native()) return int(ret) } // Get card component list from a CTL card info. func (info CTLCardInfo) GetComponents() string { ret := C.snd_ctl_card_info_get_components(info.native()) return C.GoString(ret) } // Get card driver name from a CTL card info. func (info CTLCardInfo) GetDriver() string { ret := C.snd_ctl_card_info_get_driver(info.native()) return C.GoString(ret) } // Get card long name from a CTL card info. func (info CTLCardInfo) GetLongName() string { ret := C.snd_ctl_card_info_get_longname(info.native()) return C.GoString(ret) } // Get card mixer name from a CTL card info. func (info CTLCardInfo) GetMixerName() string { ret := C.snd_ctl_card_info_get_mixername(info.native()) return C.GoString(ret) } // Get card name from a CTL card info. func (info CTLCardInfo) GetName() string { ret := C.snd_ctl_card_info_get_name(info.native()) return C.GoString(ret) } // Mixer Interface type Mixer struct { Ptr unsafe.Pointer } func (m Mixer) native() *C.snd_mixer_t { return (*C.snd_mixer_t)(m.Ptr) } func wrapMixer(ptr *C.snd_mixer_t) Mixer { return Mixer{ Ptr: unsafe.Pointer(ptr), } } // Opens an empty mixer. func OpenMixer(mode int) (Mixer, error) { var mixer *C.snd_mixer_t ret := C.snd_mixer_open(&mixer, C.int(mode)) if ret == 0 { return wrapMixer(mixer), nil } return Mixer{}, newError("snd_mixer_open", ret) } // Load a mixer elements. func (m Mixer) Load() error { ret := C.snd_mixer_load(m.native()) return newError("snd_mixer_load", ret) } // Close a mixer and free all related resources. func (m Mixer) Close() error { ret := C.snd_mixer_close(m.native()) return newError("snd_mixer_close", ret) } // Unload all mixer elements and free all related resources. func (m Mixer) Free() { C.snd_mixer_free(m.native()) } // Attach an HCTL specified with the CTL device name to an opened mixer. func (m Mixer) Attach(name string) error { cName := C.CString(name) ret := C.snd_mixer_attach(m.native(), cName) C.free(unsafe.Pointer(cName)) return newError("snd_mixer_attach", ret) } // get first element for a mixer func (m Mixer) FirstElem() MixerElem { ret := C.snd_mixer_first_elem(m.native()) return wrapMixerElem(ret) } // Find a mixer simple element. func (m Mixer) FindSelem(id MixerSelemId) MixerElem { ret := C.snd_mixer_find_selem(m.native(), id.native()) return wrapMixerElem(ret) } type MixerElem struct { Ptr unsafe.Pointer } func wrapMixerElem(ptr *C.snd_mixer_elem_t) MixerElem { return MixerElem{ Ptr: unsafe.Pointer(ptr), } } func (e MixerElem) native() *C.snd_mixer_elem_t { return (*C.snd_mixer_elem_t)(e.Ptr) } // get next mixer element func (e MixerElem) Next() MixerElem { ret := C.snd_mixer_elem_next(e.native()) return wrapMixerElem(ret) } // get previous mixer element func (e MixerElem) Prev() MixerElem { ret := C.snd_mixer_elem_prev(e.native()) return wrapMixerElem(ret) } // Return true if mixer simple element has only one volume control for both playback and capture. func (e MixerElem) SelemHasCommonVolume() bool { ret := C.snd_mixer_selem_has_common_volume(e.native()) return ret != 0 } // Return info about playback volume control of a mixer simple element. // return false if no control is present, true if it's present func (e MixerElem) SelemHasPlaybackVolume() bool { ret := C.snd_mixer_selem_has_playback_volume(e.native()) return ret != 0 } // Return info about playback volume control of a mixer simple element. // return false if control is separated per channel, true if control acts on all channels together func (e MixerElem) SelemHasPlaybackVolumeJoined() bool { ret := C.snd_mixer_selem_has_playback_volume_joined(e.native()) return ret != 0 } // Return info about capture volume control of a mixer simple element. // return false if no control is present, true if it's present func (e MixerElem) SelemHasCaptureVolume() bool { ret := C.snd_mixer_selem_has_capture_volume(e.native()) return ret != 0 } // Return info about capture volume control of a mixer simple element. // return false if control is separated per channel, true if control acts on all channels together func (e MixerElem) SelemHasCaptureVolumeJoined() bool { ret := C.snd_mixer_selem_has_capture_volume_joined(e.native()) return ret != 0 } // Return true if mixer simple element has only one switch control for both playback and capture. func (e MixerElem) SelemHasCommonSwitch() bool { ret := C.snd_mixer_selem_has_common_switch(e.native()) return ret != 0 } // Return info about playback switch control existence of a mixer simple element. func (e MixerElem) SelemHasPlaybackSwitch() bool { ret := C.snd_mixer_selem_has_playback_switch(e.native()) return ret != 0 } // Return info about playback switch control of a mixer simple element. // return false if control is separated per channel, true if control acts on all channels together func (e MixerElem) SelemHasPlaybackSwitchJoined() bool { ret := C.snd_mixer_selem_has_playback_switch_joined(e.native()) return ret != 0 } // Return info about capture switch control existence of a mixer simple element. // return false if no control is present, true if it's present func (e MixerElem) SelemHasCaptureSwitch() bool { ret := C.snd_mixer_selem_has_capture_switch(e.native()) return ret != 0 } // Return info about capture switch control of a mixer simple element. // return false if control is separated per channel, true if control acts on all channels together func (e MixerElem) SelemHasCaptureSwitchJoined() bool { ret := C.snd_mixer_selem_has_capture_switch_joined(e.native()) return ret != 0 } // Return info about capture switch control of a mixer simple element. // return false if control is separated per element, true if control acts on other elements too (i.e. only one active at a time inside a group) func (e MixerElem) SelemHasCaptureSwitchExclusive() bool { ret := C.snd_mixer_selem_has_capture_switch_exclusive(e.native()) return ret != 0 } // Return true if mixer simple enumerated element belongs to the playback direction. func (e MixerElem) SelemIsEnumPlayback() bool { ret := C.snd_mixer_selem_is_enum_playback(e.native()) return ret != 0 } // Return true if mixer simple enumerated element belongs to the capture direction. func (e MixerElem) SelemIsEnumCapture() bool { ret := C.snd_mixer_selem_is_enum_capture(e.native()) return ret != 0 } // Return true if mixer simple element is an enumerated control. func (e MixerElem) SelemIsEnumerated() bool { ret := C.snd_mixer_selem_is_enumerated(e.native()) return ret != 0 } // Return the number of enumerated items of the given mixer simple element. func (e MixerElem) SelemGetEnumItems() (int, error) { ret := C.snd_mixer_selem_get_enum_items(e.native()) if ret < 0 { return 0, newError("snd_mixer_selem_get_enum_items", ret) } return int(ret), nil } // get the enumerated item string for the given mixer simple element func (e MixerElem) SelemGetEnumItemName(item uint, maxLen int) (string, error) { buf := (*C.char)(C.malloc(C.size_t(maxLen + 1))) defer C.free(unsafe.Pointer(buf)) ret := C.snd_mixer_selem_get_enum_item_name(e.native(), C.uint(item), C.size_t(maxLen), buf) if ret == 0 { return C.GoString(buf), nil } return "", newError("snd_mixer_selem_get_enum_item_name", ret) } // Return info about capture switch control of a mixer simple element. // return group for switch exclusivity func (e MixerElem) SelemGetCaptureGroup() int { ret := C.snd_mixer_selem_get_capture_group(e.native()) return int(ret) } // Get info about channels of playback stream of a mixer simple element. // return false if not mono, true if mono func (e MixerElem) SelemIsPlaybackMono() bool { ret := C.snd_mixer_selem_is_playback_mono(e.native()) return ret != 0 } // Get info about channels of playback stream of a mixer simple element. // return false if channel is not present, true if present func (e MixerElem) SelemHasPlaybackChannel(channel MixerSelemChannelId) bool { ret := C.snd_mixer_selem_has_playback_channel(e.native(), C.snd_mixer_selem_channel_id_t(channel)) return ret != 0 } // Get info about channels of capture stream of a mixer simple element. // return false if not mono, true if mono func (e MixerElem) SelemIsCaptureMono() bool { ret := C.snd_mixer_selem_is_capture_mono(e.native()) return ret != 0 } // Get info about channels of capture stream of a mixer simple element. // return false if channel is not present, true if present func (e MixerElem) SelemHasCaptureChannel(channel MixerSelemChannelId) bool { ret := C.snd_mixer_selem_has_capture_channel(e.native(), C.snd_mixer_selem_channel_id_t(channel)) return ret != 0 } // Get range for playback volume of a mixer simple element. func (e MixerElem) SelemGetPlaybackVolumeRange() (min, max int) { var cMin, cMax C.long C.snd_mixer_selem_get_playback_volume_range(e.native(), &cMin, &cMax) return int(cMin), int(cMax) } // Get range for capture volume of a mixer simple element. func (e MixerElem) SelemGetCaptureVolumeRange() (min, max int) { var cMin, cMax C.long C.snd_mixer_selem_get_capture_volume_range(e.native(), &cMin, &cMax) return int(cMin), int(cMax) } // Return value of playback switch control of a mixer simple element. func (e MixerElem) SelemGetPlaybackSwitch(channel MixerSelemChannelId) (bool, error) { var value C.int ret := C.snd_mixer_selem_get_playback_switch(e.native(), C.snd_mixer_selem_channel_id_t(channel), &value) if ret == 0 { return value != 0, nil } return false, newError("snd_mixer_selem_get_playback_switch", ret) } // Return value of capture switch control of a mixer simple element. func (e MixerElem) SelemGetCaptureSwitch(channel MixerSelemChannelId) (bool, error) { var value C.int ret := C.snd_mixer_selem_get_capture_switch(e.native(), C.snd_mixer_selem_channel_id_t(channel), &value) if ret == 0 { return value != 0, nil } return false, newError("snd_mixer_selem_get_capture_switch", ret) } // Return value of playback volume control of a mixer simple element. func (e MixerElem) SelemGetPlaybackVolume(channel MixerSelemChannelId) (int, error) { var value C.long ret := C.snd_mixer_selem_get_playback_volume(e.native(), C.snd_mixer_selem_channel_id_t(channel), &value) if ret == 0 { return int(value), nil } return 0, newError("snd_mixer_selem_get_playback_volume", ret) } // Return value of capture volume control of a mixer simple element. func (e MixerElem) SelemGetCaptureVolume(channel MixerSelemChannelId) (int, error) { var value C.long ret := C.snd_mixer_selem_get_capture_volume(e.native(), C.snd_mixer_selem_channel_id_t(channel), &value) if ret == 0 { return int(value), nil } return 0, newError("snd_mixer_selem_get_capture_volume", ret) } // Return value of playback volume in dB control of a mixer simple element. // return value (dB * 100) func (e MixerElem) SelemGetPlaybackDB(channel MixerSelemChannelId) (int, error) { var value C.long ret := C.snd_mixer_selem_get_playback_dB(e.native(), C.snd_mixer_selem_channel_id_t(channel), &value) if ret == 0 { return int(value), nil } return 0, newError("snd_mixer_selem_get_playback_dB", ret) } // Return value of capture volume in dB control of a mixer simple element. // return value (dB * 100) func (e MixerElem) SelemGetCaptureDB(channel MixerSelemChannelId) (int, error) { var value C.long ret := C.snd_mixer_selem_get_capture_dB(e.native(), C.snd_mixer_selem_channel_id_t(channel), &value) if ret == 0 { return int(value), nil } return 0, newError("snd_mixer_selem_get_capture_dB", ret) } // Get range in dB for playback volume of a mixer simple element. // return minimum (dB * 100) and maximum (dB * 100) func (e MixerElem) SelemGetPlaybackDBRange() (min, max int) { var cMin, cMax C.long C.snd_mixer_selem_get_playback_dB_range(e.native(), &cMin, &cMax) return int(cMin), int(cMax) } // Get range in dB for capture volume of a mixer simple element. // return minimum (dB * 100) and maximum (dB * 100) func (e MixerElem) SelemGetCaptureDBRange() (min, max int) { var cMin, cMax C.long C.snd_mixer_selem_get_capture_dB_range(e.native(), &cMin, &cMax) return int(cMin), int(cMax) } // Set value of playback volume control of a mixer simple element. func (e MixerElem) SelemSetPlaybackVolume(channel MixerSelemChannelId, value int) error { ret := C.snd_mixer_selem_set_playback_volume(e.native(), C.snd_mixer_selem_channel_id_t(channel), C.long(value)) return newError("snd_mixer_selem_set_playback_volume", ret) } // Set value of capture volume control of a mixer simple element. func (e MixerElem) SelemSetCaptureVolume(channel MixerSelemChannelId, value int) error { ret := C.snd_mixer_selem_set_capture_volume(e.native(), C.snd_mixer_selem_channel_id_t(channel), C.long(value)) return newError("snd_mixer_selem_set_capture_volume", ret) } // Set value in dB of playback volume control of a mixer simple element. // value: control value in dB * 100 // dir: rounding mode - rounds up if dir > 0, otherwise rounds down func (e MixerElem) SelemSetPlaybackDB(channel MixerSelemChannelId, value, dir int) error { ret := C.snd_mixer_selem_set_playback_dB(e.native(), C.snd_mixer_selem_channel_id_t(channel), C.long(value), C.int(dir)) return newError("snd_mixer_selem_set_playback_dB", ret) } // Set value in dB of capture volume control of a mixer simple element. // value: control value in dB * 100 // dir: rounding mode - rounds up if dir > 0, otherwise rounds down func (e MixerElem) SelemSetCaptureDB(channel MixerSelemChannelId, value, dir int) error { ret := C.snd_mixer_selem_set_capture_dB(e.native(), C.snd_mixer_selem_channel_id_t(channel), C.long(value), C.int(dir)) return newError("snd_mixer_selem_set_capture_dB", ret) } // Set value of playback volume control for all channels of a mixer simple element. func (e MixerElem) SelemSetPlaybackVolumeAll(value int) error { ret := C.snd_mixer_selem_set_playback_volume_all(e.native(), C.long(value)) return newError("snd_mixer_selem_set_playback_volume_all", ret) } // Set value of capture volume control for all channels of a mixer simple element. func (e MixerElem) SelemSetCaptureVolumeAll(value int) error { ret := C.snd_mixer_selem_set_capture_volume_all(e.native(), C.long(value)) return newError("snd_mixer_selem_set_capture_volume_all", ret) } // Set value in dB of playback volume control for all channels of a mixer simple element. // value: control value in dB * 100 // dir: rounding mode - rounds up if dir > 0, otherwise rounds down func (e MixerElem) SelemSetPlaybackDBAll(value, dir int) error { ret := C.snd_mixer_selem_set_playback_dB_all(e.native(), C.long(value), C.int(dir)) return newError("snd_mixer_selem_set_playback_dB_all", ret) } // Set value in dB of capture volume control for all channels of a mixer simple element. // value: control value in dB * 100 // dir: rounding mode - rounds up if dir > 0, otherwise rounds down func (e MixerElem) SelemSetCaptureDBAll(value, dir int) error { ret := C.snd_mixer_selem_set_capture_dB_all(e.native(), C.long(value), C.int(dir)) return newError("snd_mixer_selem_set_capture_dB_all", ret) } // Set value of playback switch control of a mixer simple element. func (e MixerElem) SelemSetPlaybackSwitch(channel MixerSelemChannelId, value bool) error { var cValue C.int if value { cValue = 1 } ret := C.snd_mixer_selem_set_playback_switch(e.native(), C.snd_mixer_selem_channel_id_t(channel), cValue) return newError("snd_mixer_selem_set_playback_switch", ret) } // Set value of capture switch control of a mixer simple element. func (e MixerElem) SelemSetCaptureSwitch(channel MixerSelemChannelId, value bool) error { var cValue C.int if value { cValue = 1 } ret := C.snd_mixer_selem_set_capture_switch(e.native(), C.snd_mixer_selem_channel_id_t(channel), cValue) return newError("snd_mixer_selem_set_capture_switch", ret) } // Set value of playback switch control for all channels of a mixer simple element. func (e MixerElem) SelemSetPlaybackSwitchAll(value bool) error { var cValue C.int if value { cValue = 1 } ret := C.snd_mixer_selem_set_playback_switch_all(e.native(), cValue) return newError("snd_mixer_selem_set_playback_switch_all", ret) } // Set value of capture switch control for all channels of a mixer simple element. func (e MixerElem) SelemSetCaptureSwitchAll(value bool) error { var cValue C.int if value { cValue = 1 } ret := C.snd_mixer_selem_set_capture_switch_all(e.native(), cValue) return newError("snd_mixer_selem_set_capture_switch_all", ret) } // Mixer simple element channel identifier type MixerSelemChannelId C.snd_mixer_selem_channel_id_t const ( MixerSChanUnknown = C.SND_MIXER_SCHN_UNKNOWN /* Front left */ MixerSChanFrontLeft = C.SND_MIXER_SCHN_FRONT_LEFT /* Front right */ MixerSChanFrontRight = C.SND_MIXER_SCHN_FRONT_RIGHT /* Rear left */ MixerSChanRearLeft = C.SND_MIXER_SCHN_REAR_LEFT /* Rear right */ MixerSChanRearRight = C.SND_MIXER_SCHN_REAR_RIGHT /* Front center */ MixerSChanFrontCenter = C.SND_MIXER_SCHN_FRONT_CENTER /* Woofer */ MixerSChanWoofer = C.SND_MIXER_SCHN_WOOFER /* Side Left */ MixerSChanSideLeft = C.SND_MIXER_SCHN_SIDE_LEFT /* Side Right */ MixerSChanSideRight = C.SND_MIXER_SCHN_SIDE_RIGHT /* Rear Center */ MixerSChanRearCenter = C.SND_MIXER_SCHN_REAR_CENTER /* Mono (Front left alias) */ MixerSChanMono = C.SND_MIXER_SCHN_MONO MixerSChanLast = C.SND_MIXER_SCHN_LAST ) // Return name of mixer simple element channel. func (id MixerSelemChannelId) Name() string { return C.GoString(C.snd_mixer_selem_channel_name(C.snd_mixer_selem_channel_id_t(id))) } // get the current selected enumerated item for the given mixer simple element func (e MixerElem) SelemGetEnumItem(channel MixerSelemChannelId) (uint, error) { var item C.uint ret := C.snd_mixer_selem_get_enum_item(e.native(), C.snd_mixer_selem_channel_id_t(channel), &item) if ret == 0 { return uint(item), nil } return 0, newError("snd_mixer_selem_get_enum_item", ret) } type MixerSelemRegopt struct { c C.struct_snd_mixer_selem_regopt device *C.char } func (opt *MixerSelemRegopt) Free() { if opt.device != nil { C.free(unsafe.Pointer(opt.device)) opt.device = nil } } func (opt *MixerSelemRegopt) SetDevice(device string) { if opt.device != nil { C.free(unsafe.Pointer(opt.device)) } opt.device = C.CString(device) opt.c.device = opt.device } func (opt *MixerSelemRegopt) SetVer(ver int) { opt.c.ver = C.int(ver) } func (opt *MixerSelemRegopt) SetPlaybackPCM(pcm PCM) { opt.c.playback_pcm = pcm.native() } func (opt *MixerSelemRegopt) SetCapturePCM(pcm PCM) { opt.c.capture_pcm = pcm.native() } const ( MixerSAbstractNone = C.SND_MIXER_SABSTRACT_NONE MixerSAbstractBasic = C.SND_MIXER_SABSTRACT_BASIC ) type MixerClass struct { Ptr unsafe.Pointer } // Register mixer simple element class. func (m Mixer) SelemRegister(options *MixerSelemRegopt, class *MixerClass) error { var cOptions *C.struct_snd_mixer_selem_regopt if options != nil { cOptions = &options.c } var cClass **C.snd_mixer_class_t if class != nil { cClass = (**C.snd_mixer_class_t)(unsafe.Pointer(&class.Ptr)) } ret := C.snd_mixer_selem_register(m.native(), cOptions, cClass) return newError("snd_mixer_selem_register", ret) } type MixerSelem struct { Ptr unsafe.Pointer } // Get mixer simple element identifier. func (e MixerElem) GetSelemId(id MixerSelemId) { C.snd_mixer_selem_get_id(e.native(), id.native()) } // Get info about the active state of a mixer simple element. func (e MixerElem) SelemIsActive() bool { ret := C.snd_mixer_selem_is_active(e.native()) return ret != 0 } type MixerSelemId struct { Ptr unsafe.Pointer } func wrapMixerSelemId(ptr *C.snd_mixer_selem_id_t) MixerSelemId { return MixerSelemId{ Ptr: unsafe.Pointer(ptr), } } func (id MixerSelemId) native() *C.snd_mixer_selem_id_t { return (*C.snd_mixer_selem_id_t)(id.Ptr) } func NewMixerSelemId() (MixerSelemId, error) { var ptr *C.snd_mixer_selem_id_t ret := C.snd_mixer_selem_id_malloc(&ptr) if ret == 0 { return wrapMixerSelemId(ptr), nil } return MixerSelemId{}, newError("snd_mixer_selem_id_malloc", ret) } func (id MixerSelemId) Free() { C.snd_mixer_selem_id_free(id.native()) } // Get name part of mixer simple element identifier. func (id MixerSelemId) GetName() string { ret := C.snd_mixer_selem_id_get_name(id.native()) return C.GoString(ret) } // Get index part of a mixer simple element identifier. func (id MixerSelemId) GetIndex() uint { ret := C.snd_mixer_selem_id_get_index(id.native()) return uint(ret) } type Error struct { code C.int fn string } func newError(fn string, code C.int) error { if code == 0 { return nil } return &Error{ fn: fn, code: code, } } func (err *Error) Error() string { errStr := C.GoString(C.snd_strerror(err.code)) return err.fn + ": " + errStr } go-lib-5.6.0.9/backlight/000775 000000 000000 00000000000 13753517240 014761 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/common/000775 000000 000000 00000000000 13753517240 016251 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/common/common.go000664 000000 000000 00000004533 13753517240 020075 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package common import ( "errors" "io/ioutil" "path/filepath" "strconv" "strings" ) type Controller struct { Path string Name string MaxBrightness int } var errMaxBrightnessIsZero = errors.New("max brightness of controller is zero") func NewController(path string) (*Controller, error) { c := &Controller{ Path: path, Name: filepath.Base(path), } var err error c.MaxBrightness, err = c.GetPropInt("max_brightness") if err != nil { return nil, err } if c.MaxBrightness == 0 { return nil, errMaxBrightnessIsZero } return c, nil } func (c *Controller) GetBrightness() (int, error) { brightness, err := c.GetPropInt("brightness") if err != nil { return 0, err } return brightness, nil } func (c *Controller) GetPropBytes(name string) ([]byte, error) { filename := filepath.Join(c.Path, name) contents, err := ioutil.ReadFile(filename) if err != nil { return nil, err } return contents, nil } func (c *Controller) GetPropString(name string) (string, error) { bytes, err := c.GetPropBytes(name) if err != nil { return "", err } return string(bytes), nil } func (c *Controller) GetPropInt(name string) (int, error) { str, err := c.GetPropString(name) if err != nil { return 0, err } num, err := strconv.Atoi(strings.TrimSpace(str)) if err != nil { return 0, err } return num, nil } func ListControllerPaths(dir string) ([]string, error) { fileInfos, err := ioutil.ReadDir(dir) if err != nil { return nil, err } paths := make([]string, len(fileInfos)) for i, fileInfo := range fileInfos { paths[i] = filepath.Join(dir, fileInfo.Name()) } return paths, nil } go-lib-5.6.0.9/backlight/display/000775 000000 000000 00000000000 13753517240 016426 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/display/display.go000664 000000 000000 00000005052 13753517240 020424 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package display import ( "pkg.deepin.io/lib/backlight/common" "strings" ) const controllersDir = "/sys/class/backlight" type Controller struct { *common.Controller Type ControllerType DeviceEDID []byte } func NewController(path string) (*Controller, error) { basec, err := common.NewController(path) if err != nil { return nil, err } c := &Controller{ Controller: basec, Type: ControllerTypeUnknown, } typeStr, err := c.GetPropString("type") if err != nil { return nil, err } c.Type = ControllerTypeFromString(strings.TrimSpace(typeStr)) c.DeviceEDID, _ = c.GetPropBytes("device/edid") return c, nil } func (c *Controller) GetActualBrightness() (int, error) { brightness, err := c.GetPropInt("actual_brightness") if err != nil { return 0, err } return brightness, nil } type Controllers []*Controller func List() (Controllers, error) { return list(controllersDir) } func list(dir string) (Controllers, error) { paths, err := common.ListControllerPaths(dir) if err != nil { return nil, err } controllers := make(Controllers, 0, len(paths)) for _, path := range paths { c, err := NewController(path) if err != nil { continue } controllers = append(controllers, c) } return controllers, nil } func (cs Controllers) GetByEDID(edid []byte) *Controller { if len(edid) == 0 { return nil } for _, c := range cs { if byteSliceEqual(c.DeviceEDID, edid) { return c } } return nil } func (cs Controllers) GetByName(name string) *Controller { for _, c := range cs { if c.Name == name { return c } } return nil } func byteSliceEqual(a, b []byte) bool { if a == nil && b == nil { return true } if a == nil || b == nil { return false } if len(a) != len(b) { return false } for i := range a { if a[i] != b[i] { return false } } return true } go-lib-5.6.0.9/backlight/display/display_test.go000664 000000 000000 00000006677 13753517240 021501 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package display import ( . "github.com/smartystreets/goconvey/convey" "testing" ) var edid0 = []byte{0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x30, 0xe4, 0x5e, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x18, 0x1, 0x4, 0x95, 0x1f, 0x11, 0x78, 0xea, 0xeb, 0xf5, 0x95, 0x59, 0x54, 0x90, 0x27, 0x1e, 0x50, 0x54, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0xd0, 0x1d, 0x56, 0xf4, 0x50, 0x0, 0x16, 0x30, 0x30, 0x20, 0x35, 0x0, 0x36, 0xae, 0x10, 0x0, 0x0, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfe, 0x0, 0x4c, 0x47, 0x20, 0x44, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0xa, 0x20, 0x20, 0x0, 0x0, 0x0, 0xfe, 0x0, 0x4c, 0x50, 0x31, 0x34, 0x30, 0x57, 0x48, 0x38, 0x2d, 0x54, 0x50, 0x44, 0x31, 0x0, 0x25} var edid1 = []byte{0x0, 0xff} func getControllerByName(cs []*Controller, name string) *Controller { for _, c := range cs { if c.Name == name { return c } } return nil } func Test_list(t *testing.T) { Convey("Test list", t, func(c C) { controllers, err := list("./testdata") c.So(err, ShouldBeNil) c.So(controllers, ShouldHaveLength, 2) c.Convey("Test Controller", func(c C) { c.Convey("Test intel_backlight", func(c C) { controller := getControllerByName(controllers, "intel_backlight") c.So(controller.Type, ShouldEqual, ControllerTypeRaw) c.So(controller.MaxBrightness, ShouldEqual, 937) c.So(controller.DeviceEDID, ShouldHaveLength, 128) t.Logf("%#v\n", controller.DeviceEDID) br, err := controller.GetBrightness() c.So(err, ShouldBeNil) c.So(br, ShouldEqual, 100) abr, err := controller.GetActualBrightness() c.So(err, ShouldBeNil) c.So(abr, ShouldEqual, 100) }) c.Convey("Test acpi_video0", func(c C) { controller := getControllerByName(controllers, "acpi_video0") c.So(controller.Type, ShouldEqual, ControllerTypeFirmware) c.So(controller.MaxBrightness, ShouldEqual, 15) c.So(controller.DeviceEDID, ShouldBeNil) br, err := controller.GetBrightness() c.So(err, ShouldBeNil) c.So(br, ShouldEqual, 1) abr, err := controller.GetActualBrightness() c.So(err, ShouldBeNil) c.So(abr, ShouldEqual, 1) }) }) c.Convey("Test GetByEDID", func(c C) { controller := controllers.GetByEDID(edid0) c.So(controller, ShouldNotBeNil) c.So(controller.Name, ShouldEqual, "intel_backlight") controller = controllers.GetByEDID(edid1) c.So(controller, ShouldBeNil) }) }) } func TestList(t *testing.T) { controllers, err := List() t.Log(err) for _, c := range controllers { t.Logf("%+v\n", c) br, _ := c.GetBrightness() t.Log("brightness", br) abr, _ := c.GetActualBrightness() t.Log("actual_brightness", abr) } } go-lib-5.6.0.9/backlight/display/testdata/000775 000000 000000 00000000000 13753517240 020237 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/display/testdata/acpi_video0/000775 000000 000000 00000000000 13753517240 022421 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/display/testdata/acpi_video0/actual_brightness000664 000000 000000 00000000002 13753517240 026035 0ustar00rootroot000000 000000 1 go-lib-5.6.0.9/backlight/display/testdata/acpi_video0/bl_power000664 000000 000000 00000000002 13753517240 024145 0ustar00rootroot000000 000000 0 go-lib-5.6.0.9/backlight/display/testdata/acpi_video0/brightness000664 000000 000000 00000000002 13753517240 024504 0ustar00rootroot000000 000000 1 go-lib-5.6.0.9/backlight/display/testdata/acpi_video0/max_brightness000664 000000 000000 00000000003 13753517240 025352 0ustar00rootroot000000 000000 15 go-lib-5.6.0.9/backlight/display/testdata/acpi_video0/type000664 000000 000000 00000000011 13753517240 023315 0ustar00rootroot000000 000000 firmware go-lib-5.6.0.9/backlight/display/testdata/intel_backlight/000775 000000 000000 00000000000 13753517240 023362 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/display/testdata/intel_backlight/actual_brightness000664 000000 000000 00000000004 13753517240 027000 0ustar00rootroot000000 000000 100 go-lib-5.6.0.9/backlight/display/testdata/intel_backlight/bl_power000664 000000 000000 00000000002 13753517240 025106 0ustar00rootroot000000 000000 0 go-lib-5.6.0.9/backlight/display/testdata/intel_backlight/brightness000664 000000 000000 00000000004 13753517240 025447 0ustar00rootroot000000 000000 100 go-lib-5.6.0.9/backlight/display/testdata/intel_backlight/max_brightness000664 000000 000000 00000000004 13753517240 026314 0ustar00rootroot000000 000000 937 go-lib-5.6.0.9/backlight/display/testdata/intel_backlight/type000664 000000 000000 00000000004 13753517240 024260 0ustar00rootroot000000 000000 raw go-lib-5.6.0.9/backlight/display/type.go000664 000000 000000 00000002546 13753517240 017745 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package display type ControllerType uint const ( ControllerTypeUnknown ControllerType = iota ControllerTypeFirmware ControllerTypePlatform ControllerTypeRaw ) func (t ControllerType) String() string { switch t { case ControllerTypeFirmware: return "firmware" case ControllerTypePlatform: return "platform" case ControllerTypeRaw: return "raw" } return "unknown" } func ControllerTypeFromString(str string) ControllerType { switch str { case "firmware": return ControllerTypeFirmware case "platform": return ControllerTypePlatform case "raw": return ControllerTypeRaw } return ControllerTypeUnknown } go-lib-5.6.0.9/backlight/keyboard/000775 000000 000000 00000000000 13753517240 016561 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/keyboard/keyboard.go000664 000000 000000 00000002551 13753517240 020713 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package keyboard import ( "path/filepath" . "pkg.deepin.io/lib/backlight/common" "strings" ) const controllersDir = "/sys/class/leds" func List() ([]*Controller, error) { return list(controllersDir) } func list(dir string) ([]*Controller, error) { paths, err := ListControllerPaths(dir) if err != nil { return nil, err } controllers := make([]*Controller, 0, 1) for _, path := range paths { base := filepath.Base(path) if !strings.Contains(base, "kbd_backlight") { continue } c, err := NewController(path) if err != nil { continue } controllers = append(controllers, c) } return controllers, nil } go-lib-5.6.0.9/backlight/keyboard/keyboard_test.go000664 000000 000000 00000003017 13753517240 021750 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package keyboard import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestList(t *testing.T) { controllers, err := List() t.Log(err) if len(controllers) == 0 { t.Log("not found") return } for _, c := range controllers { t.Logf("%+v\n", c) br, _ := c.GetBrightness() t.Log("brightness", br) } } func Test_list(t *testing.T) { Convey("Test list", t, func(c C) { controllers, err := list("./testdata") c.So(err, ShouldBeNil) c.So(controllers, ShouldHaveLength, 1) c.Convey("Test Controller", func(c C) { controller := controllers[0] c.So(controller.Name, ShouldEqual, "xxx::kbd_backlight") c.So(controller.MaxBrightness, ShouldEqual, 3) br, err := controller.GetBrightness() c.So(err, ShouldBeNil) c.So(br, ShouldEqual, 1) }) }) } go-lib-5.6.0.9/backlight/keyboard/testdata/000775 000000 000000 00000000000 13753517240 020372 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/keyboard/testdata/input7::capslock/000775 000000 000000 00000000000 13753517240 023524 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/keyboard/testdata/input7::capslock/brightness000664 000000 000000 00000000002 13753517240 025607 0ustar00rootroot000000 000000 0 go-lib-5.6.0.9/backlight/keyboard/testdata/input7::capslock/max_brightness000664 000000 000000 00000000002 13753517240 026454 0ustar00rootroot000000 000000 1 go-lib-5.6.0.9/backlight/keyboard/testdata/xxx::kbd_backlight/000775 000000 000000 00000000000 13753517240 024076 5ustar00rootroot000000 000000 go-lib-5.6.0.9/backlight/keyboard/testdata/xxx::kbd_backlight/brightness000664 000000 000000 00000000002 13753517240 026161 0ustar00rootroot000000 000000 1 go-lib-5.6.0.9/backlight/keyboard/testdata/xxx::kbd_backlight/max_brightness000664 000000 000000 00000000002 13753517240 027026 0ustar00rootroot000000 000000 3 go-lib-5.6.0.9/calendar/000775 000000 000000 00000000000 13753517240 014602 5ustar00rootroot000000 000000 go-lib-5.6.0.9/calendar/calendar.go000664 000000 000000 00000005426 13753517240 016711 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package calendar import ( "pkg.deepin.io/lib/calendar/lunar" ) /* 参考资料: 算法系列之十七:日历生成算法-中国公历(格里历)(上) https://blog.csdn.net/orbit/article/details/7749723 算法系列之十七:日历生成算法-中国公历(格里历)(下) https://blog.csdn.net/orbit/article/details/7825004 算法系列之十八:用天文方法计算二十四节气(上) https://blog.csdn.net/orbit/article/details/7910220 算法系列之十八:用天文方法计算二十四节气(下) https://blog.csdn.net/orbit/article/details/7944248 算法系列之十九:用天文方法计算日月合朔(新月) https://blog.csdn.net/orbit/article/details/8223751 算法系列之二十:计算中国农历(一) https://blog.csdn.net/orbit/article/details/9210413 算法系列之二十:计算中国农历(二) https://blog.csdn.net/orbit/article/details/9337377 参考项目:github.com/oyyq99999/ChineseLunarCalendar */ type LunarDayInfo struct { GanZhiYear string // 农历年的干支 GanZhiMonth string // 农历月的干支 GanZhiDay string // 农历日的干支 LunarMonthName string // 农历月名 LunarDayName string // 农历日名 LunarLeapMonth int32 // 未使用 Zodiac string // 农历年的生肖 Term string // 农历节气 SolarFestival string // 公历节日 LunarFestival string // 农历节日 Worktime int32 // 未使用 } func SolarToLunar(year, month, day int) (LunarDayInfo, bool) { solarDay := Day{ Year: year, Month: month, Day: day, } cc := lunar.New(year) lunarDay := cc.SolarDayToLunarDay(month, day) dayInfo := LunarDayInfo{ GanZhiYear: lunarDay.GanZhiYear(), GanZhiMonth: lunarDay.GanZhiMonth(), GanZhiDay: lunarDay.GanZhiDay(), LunarMonthName: lunarDay.MonthName(), LunarDayName: lunarDay.DayName(), Term: lunarDay.SolarTermName(), SolarFestival: solarDay.Festival(), LunarFestival: lunarDay.Festival(), Zodiac: lunarDay.YearZodiac(), } return dayInfo, true } go-lib-5.6.0.9/calendar/calendar_test.go000664 000000 000000 00000005324 13753517240 017745 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package calendar import ( "testing" . "github.com/smartystreets/goconvey/convey" ) func Test_SolarToLunar(t *testing.T) { Convey("2016-02-19", t, func(c C) { dayInfo, _ := SolarToLunar(2016, 2, 19) c.So(dayInfo.LunarMonthName, ShouldEqual, "正月") c.So(dayInfo.LunarDayName, ShouldEqual, "十二") c.So(dayInfo.Term, ShouldEqual, "雨水") c.So(dayInfo.Zodiac, ShouldEqual, "猴") c.So(dayInfo.GanZhiYear, ShouldEqual, "丙申") c.So(dayInfo.GanZhiMonth, ShouldEqual, "庚寅") c.So(dayInfo.GanZhiDay, ShouldEqual, "辛未") }) Convey("2012-01-23", t, func(c C) { dayInfo, _ := SolarToLunar(2012, 1, 23) c.So(dayInfo.LunarMonthName, ShouldEqual, "正月") c.So(dayInfo.LunarDayName, ShouldEqual, "初一") c.So(dayInfo.Term, ShouldEqual, "") c.So(dayInfo.LunarFestival, ShouldEqual, "春节") c.So(dayInfo.Zodiac, ShouldEqual, "龙") c.So(dayInfo.GanZhiYear, ShouldEqual, "壬辰") c.So(dayInfo.GanZhiMonth, ShouldEqual, "辛丑") c.So(dayInfo.GanZhiDay, ShouldEqual, "癸未") }) Convey("2014-06-01", t, func(c C) { dayInfo, _ := SolarToLunar(2014, 6, 1) c.So(dayInfo.LunarMonthName, ShouldEqual, "五月") c.So(dayInfo.LunarDayName, ShouldEqual, "初四") c.So(dayInfo.Term, ShouldEqual, "") c.So(dayInfo.LunarFestival, ShouldEqual, "") c.So(dayInfo.SolarFestival, ShouldEqual, "儿童节") c.So(dayInfo.Zodiac, ShouldEqual, "马") c.So(dayInfo.GanZhiYear, ShouldEqual, "甲午") c.So(dayInfo.GanZhiMonth, ShouldEqual, "己巳") c.So(dayInfo.GanZhiDay, ShouldEqual, "癸卯") }) Convey("2057-10-27", t, func(c C) { dayInfo, _ := SolarToLunar(2057, 10, 27) c.So(dayInfo.LunarMonthName, ShouldEqual, "九月") c.So(dayInfo.LunarDayName, ShouldEqual, "三十") c.So(dayInfo.Term, ShouldEqual, "") c.So(dayInfo.LunarFestival, ShouldEqual, "") c.So(dayInfo.Zodiac, ShouldEqual, "牛") c.So(dayInfo.GanZhiYear, ShouldEqual, "丁丑") c.So(dayInfo.GanZhiMonth, ShouldEqual, "庚戌") c.So(dayInfo.GanZhiDay, ShouldEqual, "丁巳") }) } go-lib-5.6.0.9/calendar/day.go000664 000000 000000 00000007142 13753517240 015712 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package calendar import "strings" type Day struct { Year, Month, Day int } type festival struct { name string startYear int } var solarFestivals = map[int][]festival{ 101: { { name: "元旦", startYear: 0, }, }, 214: { { name: "情人节", startYear: 0, }, }, 305: { { name: "学雷锋纪念日", startYear: 1963, }, }, 308: { { name: "妇女节", startYear: 0, }, }, 312: { { name: "植树节", startYear: 0, }, }, 401: { { name: "愚人节", startYear: 0, }, }, 415: { { name: "全民国家安全教育日", startYear: 0, }, }, 501: { { name: "劳动节", startYear: 0, }, }, 504: { { name: "青年节", startYear: 0, }, }, 601: { { name: "儿童节", startYear: 0, }, }, 701: { { name: "建党节", startYear: 0, }, { name: "香港回归纪念日", startYear: 1997, }, }, 801: { { name: "建军节", startYear: 0, }, }, 903: { { name: "抗日战争胜利纪念日", startYear: 1945, }, }, 910: { { name: "教师节", startYear: 0, }, }, 1001: { { name: "国庆节", startYear: 0, }, }, 1213: { { name: "南京大屠杀死难者国家公祭日", startYear: 1937, }, }, 1220: { { name: "澳门回归纪念", startYear: 1999, }, }, 1224: { { name: "平安夜", startYear: 0, }, }, 1225: { { name: "圣诞节", startYear: 0, }, }, 1226: { { name: "毛泽东诞辰纪念", startYear: 0, }, }, } func (d *Day) Festival() string { year := d.Year month := d.Month day := d.Day name := "" var festivals []string if (month == 5) || (month == 6) { name = festivalForFatherAndMother(year, month, day) if name != "" { festivals = append(festivals, name) } } key := month*100 + day if solarFestival, ok := solarFestivals[key]; ok { for _, festival := range solarFestival { if festival.startYear <= year { festivals = append(festivals, festival.name) } } } return strings.Join(festivals, ",") } func festivalForFatherAndMother(year, month, day int) string { var disparityMotherDay, disparityFatherDay, fatherDay, i, motherDay int var leapYear int for i = 1900; i <= year; i++ { if (i%400 == 0) || ((i%100 != 0) && (i%4 == 0)) { leapYear = leapYear + 1 } } if month == 5 { disparityMotherDay = (((year-1899)*365 + leapYear) - (31 + 30 + 31 + 31 + 30 + 31 + 30 + 31)) % 7 motherDay = 14 - disparityMotherDay if day == motherDay { return "母亲节" } else { return "" } } if month == 6 { disparityFatherDay = (((year-1899)*365 + leapYear) - (30 + 31 + 31 + 30 + 31 + 30 + 31)) % 7 fatherDay = 21 - disparityFatherDay if day == fatherDay { return "父亲节" } else { return "" } } return "" } go-lib-5.6.0.9/calendar/lunar/000775 000000 000000 00000000000 13753517240 015723 5ustar00rootroot000000 000000 go-lib-5.6.0.9/calendar/lunar/day.go000664 000000 000000 00000006236 13753517240 017036 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar // Day 保存农历日信息 type Day struct { Year int // 公历年 Month int // 公历月 Day int // 公历日 LunarYear int // 农历年 LunarDay int // 农历日 LunarMonth *Month // 农历月 MonthZhi int // 农历日所在的月的地支 SolarTerm int // 0~23 二十四节气 ,-1 非节气 } // 十二月名 var monthNames = []string{"正", "二", "三", "四", "五", "六", "七", "八", "九", "十", "冬", "腊"} // MonthName 获取当天的农历月名称 func (d *Day) MonthName() string { monthName := monthNames[d.LunarMonth.Name-1] if d.LunarMonth.IsLeap { return "闰" + monthName + "月" } return monthName + "月" } // 农历日名 // 月份分为大月和小月,大月三十天,小月二十九天 var dayNames = []string{ "初一", "初二", "初三", "初四", "初五", "初六", "初七", "初八", "初九", "初十", "十一", "十二", "十三", "十四", "十五", "十六", "十七", "十八", "十九", "二十", "廿一", "廿二", "廿三", "廿四", "廿五", "廿六", "廿七", "廿八", "廿九", "三十", } // DayName 获取当天的农历日名 func (d *Day) DayName() string { return dayNames[d.LunarDay-1] } //农历节日 var lunarFestival = map[int]string{ 101: "春节", 115: "元宵节", 505: "端午节", 707: "七夕节", 815: "中秋节", 909: "重阳节", 1208: "腊八节", } // Festival 获取当天的农历节日名 // 没有则返回空字符串 func (d *Day) Festival() string { key := d.LunarMonth.Name*100 + d.LunarDay if name, ok := lunarFestival[key]; ok { return name } // 农历腊月(十二月)的最后个一天 if d.LunarMonth.Name == 12 && d.LunarDay == d.LunarMonth.Days { return "除夕" } if d.SolarTerm == QingMing { return "清明节" } return "" } // SolarTermName 获取当天的二十四节气名 // 没有则返回空字符串 func (d *Day) SolarTermName() string { return GetSolarTermName(d.SolarTerm) } // GanZhiMonth 获取当天的月干支 func (d *Day) GanZhiMonth() string { return cyclical((d.Year-1900)*12 + d.MonthZhi + 12) } // GanZhiYear 获取当天的年干支 func (d *Day) GanZhiYear() string { return GetYearGanZhi(d.LunarYear) } // GanZhiYear 获取当天的日干支 func (d *Day) GanZhiDay() string { return GetDayGanZhi(d.Year, d.Month, d.Day) } // YearZodiac 获取当天的生肖 func (d *Day) YearZodiac() string { return GetYearZodiac(d.LunarYear) } go-lib-5.6.0.9/calendar/lunar/day_test.go000664 000000 000000 00000011751 13753517240 020073 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "testing" . "github.com/smartystreets/goconvey/convey" ) func TestDay(t *testing.T) { Convey("year 2012", t, func(c C) { cc := New(2012) c.Convey("01-01", func(c C) { day := cc.SolarDayToLunarDay(1, 1) c.So(day.MonthName(), ShouldEqual, "腊月") c.So(day.DayName(), ShouldEqual, "初八") c.So(day.GanZhiYear(), ShouldEqual, "辛卯") c.So(day.GanZhiMonth(), ShouldEqual, "庚子") c.So(day.GanZhiDay(), ShouldEqual, "辛酉") c.So(day.YearZodiac(), ShouldEqual, "兔") c.So(day.Festival(), ShouldEqual, "腊八节") c.So(day.SolarTermName(), ShouldEqual, "") }) c.Convey("02-04", func(c C) { day := cc.SolarDayToLunarDay(2, 4) c.So(day.MonthName(), ShouldEqual, "正月") c.So(day.DayName(), ShouldEqual, "十三") c.So(day.GanZhiYear(), ShouldEqual, "壬辰") c.So(day.GanZhiMonth(), ShouldEqual, "壬寅") c.So(day.GanZhiDay(), ShouldEqual, "乙未") c.So(day.YearZodiac(), ShouldEqual, "龙") c.So(day.Festival(), ShouldEqual, "") c.So(day.SolarTermName(), ShouldEqual, "立春") }) c.Convey("05-20", func(c C) { day := cc.SolarDayToLunarDay(5, 20) c.So(day.MonthName(), ShouldEqual, "四月") c.So(day.DayName(), ShouldEqual, "三十") c.So(day.GanZhiYear(), ShouldEqual, "壬辰") c.So(day.GanZhiMonth(), ShouldEqual, "乙巳") c.So(day.GanZhiDay(), ShouldEqual, "辛巳") c.So(day.YearZodiac(), ShouldEqual, "龙") c.So(day.Festival(), ShouldEqual, "") c.So(day.SolarTermName(), ShouldEqual, "小满") }) c.Convey("06-10", func(c C) { day := cc.SolarDayToLunarDay(6, 10) c.So(day.MonthName(), ShouldEqual, "闰四月") c.So(day.DayName(), ShouldEqual, "廿一") c.So(day.GanZhiYear(), ShouldEqual, "壬辰") c.So(day.GanZhiMonth(), ShouldEqual, "丙午") c.So(day.GanZhiDay(), ShouldEqual, "壬寅") c.So(day.YearZodiac(), ShouldEqual, "龙") c.So(day.Festival(), ShouldEqual, "") c.So(day.SolarTermName(), ShouldEqual, "") }) }) Convey("year 2016", t, func(c C) { cc := New(2016) c.Convey("01-01", func(c C) { day := cc.SolarDayToLunarDay(1, 1) c.So(day.MonthName(), ShouldEqual, "冬月") // 十一月 c.So(day.DayName(), ShouldEqual, "廿二") c.So(day.GanZhiYear(), ShouldEqual, "乙未") c.So(day.GanZhiMonth(), ShouldEqual, "戊子") c.So(day.GanZhiDay(), ShouldEqual, "壬午") c.So(day.YearZodiac(), ShouldEqual, "羊") c.So(day.Festival(), ShouldEqual, "") c.So(day.SolarTermName(), ShouldEqual, "") }) c.Convey("02-26", func(c C) { day := cc.SolarDayToLunarDay(2, 26) c.So(day.MonthName(), ShouldEqual, "正月") c.So(day.DayName(), ShouldEqual, "十九") c.So(day.GanZhiYear(), ShouldEqual, "丙申") c.So(day.GanZhiMonth(), ShouldEqual, "庚寅") c.So(day.GanZhiDay(), ShouldEqual, "戊寅") c.So(day.YearZodiac(), ShouldEqual, "猴") c.So(day.Festival(), ShouldEqual, "") c.So(day.SolarTermName(), ShouldEqual, "") }) c.Convey("03-05", func(c C) { day := cc.SolarDayToLunarDay(3, 5) c.So(day.MonthName(), ShouldEqual, "正月") c.So(day.DayName(), ShouldEqual, "廿七") c.So(day.GanZhiYear(), ShouldEqual, "丙申") c.So(day.GanZhiMonth(), ShouldEqual, "辛卯") c.So(day.GanZhiDay(), ShouldEqual, "丙戌") c.So(day.YearZodiac(), ShouldEqual, "猴") c.So(day.Festival(), ShouldEqual, "") c.So(day.SolarTermName(), ShouldEqual, "惊蛰") }) c.Convey("06-09", func(c C) { day := cc.SolarDayToLunarDay(6, 9) c.So(day.MonthName(), ShouldEqual, "五月") c.So(day.DayName(), ShouldEqual, "初五") c.So(day.GanZhiYear(), ShouldEqual, "丙申") c.So(day.GanZhiMonth(), ShouldEqual, "甲午") c.So(day.GanZhiDay(), ShouldEqual, "壬戌") c.So(day.YearZodiac(), ShouldEqual, "猴") c.So(day.Festival(), ShouldEqual, "端午节") c.So(day.SolarTermName(), ShouldEqual, "") }) c.Convey("12-31", func(c C) { day := cc.SolarDayToLunarDay(12, 31) c.So(day.MonthName(), ShouldEqual, "腊月") c.So(day.DayName(), ShouldEqual, "初三") c.So(day.GanZhiYear(), ShouldEqual, "丙申") c.So(day.GanZhiMonth(), ShouldEqual, "庚子") c.So(day.GanZhiDay(), ShouldEqual, "丁亥") c.So(day.YearZodiac(), ShouldEqual, "猴") c.So(day.Festival(), ShouldEqual, "") c.So(day.SolarTermName(), ShouldEqual, "") }) }) } go-lib-5.6.0.9/calendar/lunar/elp82.go000664 000000 000000 00000006253 13753517240 017212 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "math" "pkg.deepin.io/lib/calendar/util" ) // 参数 T 儒略世纪数 // 返回 弧度 func GetMoonEclipticParameter(T float64) (Lp, D, M, Mp, F, E float64) { T2 := T * T T3 := T2 * T T4 := T3 * T /*月球平黄经*/ Lp = Mod2Pi(ToRadians(218.3164591 + 481267.88134236*T - 0.0013268*T2 + T3/538841.0 - T4/65194000.0)) /*月日距角*/ D = Mod2Pi(ToRadians(297.8502042 + 445267.1115168*T - 0.0016300*T2 + T3/545868.0 - T4/113065000.0)) /*太阳平近点角*/ M = Mod2Pi(ToRadians(357.5291092 + 35999.0502909*T - 0.0001536*T2 + T3/24490000.0)) /*月亮平近点角*/ Mp = Mod2Pi(ToRadians(134.9634114 + 477198.8676313*T + 0.0089970*T2 + T3/69699.0 - T4/14712000.0)) /*月球经度参数(到升交点的平角距离)*/ F = Mod2Pi(ToRadians(93.2720993 + 483202.0175273*T - 0.0034029*T2 - T3/3526000.0 + T4/863310000.0)) /* 反映地球轨道偏心率变化的辅助参量 */ E = 1 - 0.002516*T - 0.0000074*T2 return } /*计算月球地心黄经周期项的和*/ func CalcMoonECLongitudePeriodic(D, M, Mp, F, E float64) float64 { var EI float64 for _, l := range MoonLongitude { theta := l.D*D + l.M*M + l.Mp*Mp + l.F*F EI += l.EiA * math.Sin(theta) * math.Pow(E, math.Abs(l.M)) } // fmt.Printf("EI = %f\n", EI) return EI } /*计算金星摄动,木星摄动以及地球扁率摄动对月球地心黄经的影响, T 是儒略世纪数,Lp和F单位是弧度*/ // A1 = 119.75 + 131.849 * T (4.13式) // A2 = 53.09 + 479264.290 * T (4.14式) // A3 = 313.45 + 481266.484 * T (4.15式) func CalcMoonLongitudePerturbation(T, Lp, F float64) float64 { A1 := Mod2Pi(ToRadians(119.75 + 131.849*T)) A2 := Mod2Pi(ToRadians(53.09 + 479264.290*T)) return 3958.0*math.Sin(A1) + 1962.0*math.Sin(Lp-F) + 318.0*math.Sin(A2) } /*计算月球地心黄经*/ // jd 儒略日 // 返回 弧度 func GetMoonEclipticLongitudeEC(jd float64) float64 { T := util.GetJulianCentury(jd) Lp, D, M, Mp, F, E := GetMoonEclipticParameter(T) // Lp 计算是正确的 // fmt.Printf("Lp = %f\n", Lp) /*计算月球地心黄经周期项*/ EI := CalcMoonECLongitudePeriodic(D, M, Mp, F, E) /*修正金星,木星以及地球扁率摄动*/ EI += CalcMoonLongitudePerturbation(T, Lp, F) longitude := Lp + ToRadians(EI/1000000.0) /*计算天体章动干扰*/ longitude += CalcEarthLongitudeNutation(T) return longitude } go-lib-5.6.0.9/calendar/lunar/elp82_const.go000664 000000 000000 00000005706 13753517240 020422 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar // 月地心黄经系数 type MoonEclipticLongitudeCoeff struct { D float64 M float64 Mp float64 F float64 EiA float64 ErA float64 } /* 月球黄经周期项(ΣI)及距离(Σr). 黄经单位:0.000001度,距离单位:0.001千米. -------------------------------------------------- 角度的组合系数 ΣI的各项振幅A Σr的各项振幅A D M M' F (正弦振幅) (余弦振幅) -------------------------------------------------- */ var MoonLongitude = [60]MoonEclipticLongitudeCoeff{ {0, 0, 1, 0, 6288744, -20905355}, {2, 0, -1, 0, 1274027, -3699111}, {2, 0, 0, 0, 658314, -2955968}, {0, 0, 2, 0, 213618, -569925}, {0, 1, 0, 0, -185116, 48888}, {0, 0, 0, 2, -114332, -3149}, {2, 0, -2, 0, 58793, 246158}, {2, -1, -1, 0, 57066, -152138}, {2, 0, 1, 0, 53322, -170733}, {2, -1, 0, 0, 45758, -204586}, {0, 1, -1, 0, -40923, -129620}, {1, 0, 0, 0, -34720, 108743}, {0, 1, 1, 0, -30383, 104755}, {2, 0, 0, -2, 15327, 10321}, {0, 0, 1, 2, -12528, 0}, {0, 0, 1, -2, 10980, 79661}, {4, 0, -1, 0, 10675, -34782}, {0, 0, 3, 0, 10034, -23210}, {4, 0, -2, 0, 8548, -21636}, {2, 1, -1, 0, -7888, 24208}, {2, 1, 0, 0, -6766, 30824}, {1, 0, -1, 0, -5163, -8379}, {1, 1, 0, 0, 4987, -16675}, {2, -1, 1, 0, 4036, -12831}, {2, 0, 2, 0, 3994, -10445}, {4, 0, 0, 0, 3861, -11650}, {2, 0, -3, 0, 3665, 14403}, {0, 1, -2, 0, -2689, -7003}, {2, 0, -1, 2, -2602, 0}, {2, -1, -2, 0, 2390, 10056}, {1, 0, 1, 0, -2348, 6322}, {2, -2, 0, 0, 2236, -9884}, {0, 1, 2, 0, -2120, 5751}, {0, 2, 0, 0, -2069, 0}, {2, -2, -1, 0, 2048, -4950}, {2, 0, 1, -2, -1773, 4130}, {2, 0, 0, 2, -1595, 0}, {4, -1, -1, 0, 1215, -3958}, {0, 0, 2, 2, -1110, 0}, {3, 0, -1, 0, -892, 3258}, {2, 1, 1, 0, -810, 2616}, {4, -1, -2, 0, 759, -1897}, {0, 2, -1, 0, -713, -2117}, {2, 2, -1, 0, -700, 2354}, {2, 1, -2, 0, 691, 0}, {2, -1, 0, -2, 596, 0}, {4, 0, 1, 0, 549, -1423}, {0, 0, 4, 0, 537, -1117}, {4, -1, 0, 0, 520, -1571}, {1, 0, -2, 0, -487, -1739}, {2, 1, 0, -2, -399, 0}, {0, 0, 2, -2, -381, -4421}, {1, 1, 1, 0, 351, 0}, {3, 0, -2, 0, -340, 0}, {4, 0, -3, 0, 330, 0}, {2, -1, 2, 0, 327, 0}, {0, 2, 1, 0, -323, 1165}, {1, 1, -1, 0, 299, 0}, {2, 0, 3, 0, 294, 0}, {2, 0, -1, -2, 0, 8752}, } go-lib-5.6.0.9/calendar/lunar/elp82_test.go000664 000000 000000 00000002454 13753517240 020250 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "testing" ) func Test_GetMoonEclipticParameter(t *testing.T) { Lp, D, M, Mp, F, E := GetMoonEclipticParameter(1.2345) t.Log(Lp) t.Log(D) t.Log(M) t.Log(Mp) t.Log(F) t.Log(E) } func Test_CalcMoonECLongitudePeriodic(t *testing.T) { Lp, D, M, Mp, F, E := GetMoonEclipticParameter(1.2345) EI := CalcMoonECLongitudePeriodic(D, M, Mp, F, E) t.Log(Lp) t.Log(EI) } func Test_GetMoonEclipticLongitudeEC(t *testing.T) { rad := GetMoonEclipticLongitudeEC(2448724.5) t.Log(rad) // 目标 2.3242072713306796 deg := ToDegrees(rad) t.Log(deg) } go-lib-5.6.0.9/calendar/lunar/iau1980.go000664 000000 000000 00000011527 13753517240 017360 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "math" ) // T 是 儒略世纪数 // 返回 弧度 func GetEarthNutationParameter(T float64) (D, M, Mp, F, Omega float64) { T2 := T * T T3 := T2 * T /*平距角(如月对地心的角距离)*/ D = ToRadians(297.85036 + 445267.111480*T - 0.0019142*T2 + T3/189474.0) /*太阳(地球)平近点角*/ M = ToRadians(357.52772 + 35999.050340*T - 0.0001603*T2 - T3/300000.0) /*月亮平近点角*/ Mp = ToRadians(134.96298 + 477198.867398*T + 0.0086972*T2 + T3/56250.0) /*月亮纬度参数*/ F = ToRadians(93.27191 + 483202.017538*T - 0.0036825*T2 + T3/327270.0) /*黄道与月亮平轨道升交点黄经*/ Omega = ToRadians(125.04452 - 1934.136261*T + 0.0020708*T2 + T3/450000.0) return } //天体章动系数类型变量 type NuationCoefficient struct { D float64 M float64 Mp float64 F float64 Omega float64 Sine1 float64 Sine2 float64 Cosine1 float64 Cosine2 float64 } var nuation = []NuationCoefficient{ {0, 0, 0, 0, 1, -171996, -174.2, 92025, 8.9}, {-2, 0, 0, 2, 2, -13187, -1.6, 5736, -3.1}, {0, 0, 0, 2, 2, -2274, -0.2, 977, -0.5}, {0, 0, 0, 0, 2, 2062, 0.2, -895, 0.5}, {0, 1, 0, 0, 0, 1426, -3.4, 54, -0.1}, {0, 0, 1, 0, 0, 712, 0.1, -7, 0}, {-2, 1, 0, 2, 2, -517, 1.2, 224, -0.6}, {0, 0, 0, 2, 1, -386, -0.4, 200, 0}, {0, 0, 1, 2, 2, -301, 0, 129, -0.1}, {-2, -1, 0, 2, 2, 217, -0.5, -95, 0.3}, {-2, 0, 1, 0, 0, -158, 0, 0, 0}, {-2, 0, 0, 2, 1, 129, 0.1, -70, 0}, {0, 0, -1, 2, 2, 123, 0, -53, 0}, {2, 0, 0, 0, 0, 63, 0, 0, 0}, {0, 0, 1, 0, 1, 63, 0.1, -33, 0}, {2, 0, -1, 2, 2, -59, 0, 26, 0}, {0, 0, -1, 0, 1, -58, -0.1, 32, 0}, {0, 0, 1, 2, 1, -51, 0, 27, 0}, {-2, 0, 2, 0, 0, 48, 0, 0, 0}, {0, 0, -2, 2, 1, 46, 0, -24, 0}, {2, 0, 0, 2, 2, -38, 0, 16, 0}, {0, 0, 2, 2, 2, -31, 0, 13, 0}, {0, 0, 2, 0, 0, 29, 0, 0, 0}, {-2, 0, 1, 2, 2, 29, 0, -12, 0}, {0, 0, 0, 2, 0, 26, 0, 0, 0}, {-2, 0, 0, 2, 0, -22, 0, 0, 0}, {0, 0, -1, 2, 1, 21, 0, -10, 0}, {0, 2, 0, 0, 0, 17, -0.1, 0, 0}, {2, 0, -1, 0, 1, 16, 0, -8, 0}, {-2, 2, 0, 2, 2, -16, 0.1, 7, 0}, {0, 1, 0, 0, 1, -15, 0, 9, 0}, {-2, 0, 1, 0, 1, -13, 0, 7, 0}, {0, -1, 0, 0, 1, -12, 0, 6, 0}, {0, 0, 2, -2, 0, 11, 0, 0, 0}, {2, 0, -1, 2, 1, -10, 0, 5, 0}, {2, 0, 1, 2, 2, -8, 0, 3, 0}, {0, 1, 0, 2, 2, 7, 0, -3, 0}, {-2, 1, 1, 0, 0, -7, 0, 0, 0}, {0, -1, 0, 2, 2, -7, 0, 3, 0}, {2, 0, 0, 2, 1, -7, 0, 3, 0}, {2, 0, 1, 0, 0, 6, 0, 0, 0}, {-2, 0, 2, 2, 2, 6, 0, -3, 0}, {-2, 0, 1, 2, 1, 6, 0, -3, 0}, {2, 0, -2, 0, 1, -6, 0, 3, 0}, {2, 0, 0, 0, 1, -6, 0, 3, 0}, {0, -1, 1, 0, 0, 5, 0, 0, 0}, {-2, -1, 0, 2, 1, -5, 0, 3, 0}, {-2, 0, 0, 0, 1, -5, 0, 3, 0}, {0, 0, 2, 2, 1, -5, 0, 3, 0}, {-2, 0, 2, 0, 1, 4, 0, 0, 0}, {-2, 1, 0, 2, 1, 4, 0, 0, 0}, {0, 0, 1, -2, 0, 4, 0, 0, 0}, {-1, 0, 1, 0, 0, -4, 0, 0, 0}, {-2, 1, 0, 0, 0, -4, 0, 0, 0}, {1, 0, 0, 0, 0, -4, 0, 0, 0}, {0, 0, 1, 2, 0, 3, 0, 0, 0}, {0, 0, -2, 2, 2, -3, 0, 0, 0}, {-1, -1, 1, 0, 0, -3, 0, 0, 0}, {0, 1, 1, 0, 0, -3, 0, 0, 0}, {0, -1, 1, 2, 2, -3, 0, 0, 0}, {2, -1, -1, 2, 2, -3, 0, 0, 0}, {0, 0, 3, 2, 2, -3, 0, 0, 0}, {2, -1, 0, 2, 2, -3, 0, 0, 0}, } var coefficient = SecondsToRadians(0.0001) //计算某时刻的黄经章动干扰量 // T 儒略世纪数 // 返回弧度 func CalcEarthLongitudeNutation(T float64) float64 { D, M, Mp, F, Omega := GetEarthNutationParameter(T) var result float64 for _, n := range nuation { theta := n.D*D + n.M*M + n.Mp*Mp + n.F*F + n.Omega*Omega result += (n.Sine1 + n.Sine2*T) * math.Sin(theta) } //乘以章动表的系数 0.0001 角秒 return result * coefficient } /*计算某时刻的黄赤交角章动干扰量,dt是儒略千年数,返回值单位是度*/ // 计算某时刻的黄赤交角章动干扰量 // dt 是儒略世纪数 // 返回弧度 func CalcEarthObliquityNutation(dt float64) float64 { D, M, Mp, F, Omega := GetEarthNutationParameter(dt) var result float64 len_nuation := len(nuation) for i := 0; i < len_nuation; i++ { // sita 弧度 n := nuation[i] theta := n.D*D + n.M*M + n.Mp*Mp + n.F*F + n.Omega*Omega result += (n.Cosine1 + n.Cosine2*dt) * math.Cos(theta) } //乘以章动表的系数 0.0001 角秒 return result * coefficient } go-lib-5.6.0.9/calendar/lunar/iau1980_test.go000664 000000 000000 00000001751 13753517240 020415 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "testing" ) func Test_CalcEarthLongitudeNutation(t *testing.T) { n := CalcEarthLongitudeNutation(1.2345) t.Log(n) } func Test_CalcEarthObliquityNutation(t *testing.T) { n := CalcEarthObliquityNutation(1.2345) t.Log(n) } go-lib-5.6.0.9/calendar/lunar/lunar.go000664 000000 000000 00000020043 13753517240 017372 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "fmt" "time" "pkg.deepin.io/lib/calendar/util" ) // Calendar 保存公历年内计算农历所需的信息 type Calendar struct { Year int // 公历年份 SolarTermJDs *[25]float64 // 相关的 25 节气 北京时间 儒略日 SolarTermTimes *[25]time.Time // 对应 SolarTermJDs 转换为 time.Time 的时间 NewMoonJDs *[15]float64 // 相关的 15 个朔日 北京时间 儒略日 Months []*Month // 月 solarTermYearDays []int // 十二节的 yearDay 列表 } // Month 保存农历月信息 type Month struct { LunarYear int // 农历年 Name int // 农历月名 Days int // 本月天数 ShuoJD float64 // 本月朔日时间 北京时间 儒略日 ShuoTime time.Time // 本月朔日时间 北京时间 IsLeap bool // 是否为闰月 } func (m *Month) String() string { return fmt.Sprintf("Month{ LunnarYear: %d, Name: %d, Days: %d, ShuoJD: %f, ShuoTime: %v, IsLeap: %v }", m.LunarYear, m.Name, m.Days, m.ShuoJD, m.ShuoTime, m.IsLeap) } func newCalendar(year int) *Calendar { cc := &Calendar{Year: year} cc.Months = make([]*Month, 0, 13) cc.calcProcData() cc.fillMonths() cc.calcLeapMonth() return cc } var ccCache = make(map[int]*Calendar) // New 从缓存获取 Calendar 对象,没有则先创建 func New(year int) *Calendar { if cc, ok := ccCache[year]; ok { return cc } else { cc := newCalendar(year) ccCache[year] = cc return cc } } func (cc *Calendar) calcProcData() { //计算从上一年冬至开始到当年冬至全部25个节气 cc.SolarTermJDs = get25SolarTermJDs(cc.Year-1, DongZhi) var solarTermTimes [25]time.Time for i := 0; i < 25; i++ { solarTermTimes[i] = util.GetDateTimeFromJulianDay(cc.SolarTermJDs[i]) } cc.SolarTermTimes = &solarTermTimes var solarTermYearDays []int for i := 1; i < 25; i += 2 { yd := cc.SolarTermTimes[i].YearDay() solarTermYearDays = append(solarTermYearDays, yd) } cc.solarTermYearDays = solarTermYearDays tmpNewMoonJD := getNewMoonJD(util.JDBeijingTime2UTC(cc.SolarTermJDs[0])) if tmpNewMoonJD > cc.SolarTermJDs[0] { tmpNewMoonJD -= 29.53 } cc.NewMoonJDs = get15NewMoonJDs(tmpNewMoonJD) } func get25SolarTermJDs(year, start int) *[25]float64 { // 从某一年的某个节气开始,连续计算25个节气,返回各节气的儒略日 // year 年份 // start 起始的节气 // 返回 25 个节气的 儒略日北京时间 stOrder := start var list [25]float64 for i := 0; i < 25; i++ { jd := GetSolarTermJD(year, stOrder) list[i] = util.JDUTC2BeijingTime(jd) if stOrder == DongZhi { year++ } stOrder = (stOrder + 1) % 24 } return &list } func get15NewMoonJDs(jd float64) *[15]float64 { // 计算从某个时间之后的连续15个朔日 // 参数: jd 开始时间的 儒略日 // 返回 15个朔日时间 数组指针 儒略日北京时间 var list [15]float64 for i := 0; i < 15; i++ { newMoonJD := getNewMoonJD(jd) list[i] = util.JDUTC2BeijingTime(newMoonJD) // 转到下一个最接近朔日的时间 jd = newMoonJD + 29.53 } return &list } func deltaDays(t1, t2 time.Time) int { // 计算两个时间相差的天数 // t2 > t1 结果为正数 date1 := time.Date(t1.Year(), t1.Month(), t1.Day(), 0, 0, 0, 0, time.UTC) date2 := time.Date(t2.Year(), t2.Month(), t2.Day(), 0, 0, 0, 0, time.UTC) dd := int((date2.Unix() - date1.Unix()) / 86400) // fmt.Printf("%v <=> %v dd %v\n", t2, t1, dd) return dd } func (cc *Calendar) fillMonths() { //采用夏历建寅,冬至所在月份为农历11月(冬月) yuejian := 11 for i := 0; i < 14; i++ { info := new(Month) if yuejian <= 12 { info.Name = yuejian info.LunarYear = cc.Year - 1 } else { info.Name = yuejian - 12 info.LunarYear = cc.Year } info.ShuoJD = cc.NewMoonJDs[i] info.ShuoTime = util.GetDateTimeFromJulianDay(info.ShuoJD) nextShuoJD := cc.NewMoonJDs[i+1] nextShuoTime := util.GetDateTimeFromJulianDay(nextShuoJD) info.Days = deltaDays(info.ShuoTime, nextShuoTime) cc.Months = append(cc.Months, info) yuejian++ } } func (cc *Calendar) calcLeapMonth() { // 根据节气计算是否有闰月,如果有闰月,根据农历月命名规则,调整月名称 if int(cc.NewMoonJDs[13]+0.5) <= int(cc.SolarTermJDs[24]+0.5) { // 第13月的月末没有超过冬至,说明今年需要闰一个月 i := 1 for i < 14 { if int(cc.NewMoonJDs[i+1]+0.5) <= int(cc.SolarTermJDs[2*i]+0.5) { /* cc.NewMoonJDs[i + 1] 是第i个农历月的下一个月的月首 本该属于第i个月的中气如果比下一个月的月首还晚,或者与下个月的月首是同一天(民间历法),则说明第 i 个月没有中气, 是闰月 */ break } i++ } if i < 14 { // 找到闰月 // fmt.Println("找到闰月 ", i) cc.Months[i].IsLeap = true // 对后面的农历月调整月名 for i < 14 { cc.Months[i].Name-- i++ } } } } // SolarDayToLunarDay 指定年份内公历日期转换为农历日 func (cc *Calendar) SolarDayToLunarDay(month, day int) *Day { dt := time.Date(cc.Year, time.Month(month), day, 0, 0, 0, 0, time.UTC) yd := dt.YearDay() // 求月地支 monthZhi := 0 for monthZhi < len(cc.solarTermYearDays) { if yd >= cc.solarTermYearDays[monthZhi] { monthZhi++ } else { break } } // 求农历年、月、日 var lunarYear int var lunarMonth *Month var lunarDay int for _, m := range cc.Months { dd := deltaDays(m.ShuoTime, dt) + 1 if 1 <= dd && dd <= m.Days { lunarYear = m.LunarYear lunarMonth = m lunarDay = dd break } } // 求二十四节气 solarTerm := -1 solarTermInfos := cc.getMonthSolarTerms(month) if day == solarTermInfos[0].Day { solarTerm = solarTermInfos[0].SolarTerm } else if day == solarTermInfos[1].Day { solarTerm = solarTermInfos[1].SolarTerm } return &Day{ Year: cc.Year, Month: month, Day: day, LunarYear: lunarYear, LunarDay: lunarDay, LunarMonth: lunarMonth, MonthZhi: monthZhi, SolarTerm: solarTerm, } } type solarTermInfo struct { Day int SolarTerm int } func (cc *Calendar) getSolarTermInfo(index int) *solarTermInfo { dt := cc.SolarTermTimes[index] day := dt.Day() stIndex := (index + DongZhi) % 24 return &solarTermInfo{day, stIndex} } func (cc *Calendar) getMonthSolarTerms(month int) [2]*solarTermInfo { var list [2]*solarTermInfo index := 2*month - 1 list[0] = cc.getSolarTermInfo(index) list[1] = cc.getSolarTermInfo(index + 1) return list } var ( // 十二生肖 Animals = []string{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"} // 天干 Gan = []string{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"} // 地支 Zhi = []string{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"} ) // GetYearZodiac 计算年份的生肖 func GetYearZodiac(year int) string { return Animals[(year-4)%12] } func cyclical(num int) string { // 将数字转换为天干地支表示 return Gan[num%10] + Zhi[num%12] } // GetYearGanZhi 计算年份的干支 func GetYearGanZhi(year int) string { return cyclical(year - 1864) } // GetDayGanZhi 计算日干支 func GetDayGanZhi(year, month, day int) string { unixTime := time.Date(int(year), time.Month(month), int(day), 0, 0, 0, 0, time.UTC).Unix() dayCyclical := int(unixTime/86400) + 29219 + 18 return cyclical(dayCyclical) } go-lib-5.6.0.9/calendar/lunar/lunar_test.go000664 000000 000000 00000007504 13753517240 020440 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( . "github.com/smartystreets/goconvey/convey" "strings" "testing" ) func Test_New(t *testing.T) { Convey("New 2012", t, func(c C) { cc := New(2012) const dateTimeFormatStr = "2006-01-02 15:04:05" c.Convey("month Shuo Times", func(c C) { var dtList []string for _, month := range cc.Months { dtList = append(dtList, month.ShuoTime.Format(dateTimeFormatStr)) } dtListStr := strings.Join(dtList, ",") const testDtListStr = "2011-11-25 14:09:41,2011-12-25 02:06:27,2012-01-23 15:39:24,2012-02-22 06:34:40,2012-03-22 22:37:08,2012-04-21 15:18:22,2012-05-21 07:46:59,2012-06-19 23:02:06,2012-07-19 12:24:02,2012-08-17 23:54:27,2012-09-16 10:10:36,2012-10-15 20:02:30,2012-11-14 06:08:05,2012-12-13 16:41:37" // t.Logf("%q\n", dtListStr) c.So(dtListStr, ShouldEqual, testDtListStr) }) c.Convey("Solar Term Times", func(c C) { var dtList []string for _, stTime := range cc.SolarTermTimes { dtList = append(dtList, stTime.Format(dateTimeFormatStr)) } const testDtListStr = "2011-12-22 13:30:01,2012-01-06 06:43:54,2012-01-21 00:09:48,2012-02-04 18:22:22,2012-02-19 14:17:35,2012-03-05 12:21:01,2012-03-20 13:14:23,2012-04-04 17:05:34,2012-04-20 00:12:02,2012-05-05 10:19:39,2012-05-20 23:15:30,2012-06-05 14:25:52,2012-06-21 07:08:46,2012-07-07 00:40:42,2012-07-22 18:00:50,2012-08-07 10:30:31,2012-08-23 01:06:48,2012-09-07 13:28:59,2012-09-22 22:48:56,2012-10-08 05:11:41,2012-10-23 08:13:32,2012-11-07 08:25:56,2012-11-22 05:50:07,2012-12-07 01:18:55,2012-12-21 19:11:35" dtListStr := strings.Join(dtList, ",") // t.Logf("%q\n", dtListStr) c.So(dtListStr, ShouldEqual, testDtListStr) }) }) } func Test_GetYearZodiac(t *testing.T) { Convey("GetYearZodiac", t, func(c C) { c.So(GetYearZodiac(2012), ShouldEqual, "龙") c.So(GetYearZodiac(2014), ShouldEqual, "马") c.So(GetYearZodiac(2015), ShouldEqual, "羊") c.So(GetYearZodiac(2016), ShouldEqual, "猴") c.So(GetYearZodiac(2017), ShouldEqual, "鸡") }) } func Test_cyclical(t *testing.T) { Convey("cyclical", t, func(c C) { var ganZhiList []string for i := 0; i < 80; i++ { ganZhiList = append(ganZhiList, cyclical(i)) } ganzhiListStr := strings.Join(ganZhiList, ",") // t.Logf("%q\n", ganzhiListStr ) const testGanzhiListStr = "甲子,乙丑,丙寅,丁卯,戊辰,己巳,庚午,辛未,壬申,癸酉,甲戌,乙亥,丙子,丁丑,戊寅,己卯,庚辰,辛巳,壬午,癸未,甲申,乙酉,丙戌,丁亥,戊子,己丑,庚寅,辛卯,壬辰,癸巳,甲午,乙未,丙申,丁酉,戊戌,己亥,庚子,辛丑,壬寅,癸卯,甲辰,乙巳,丙午,丁未,戊申,己酉,庚戌,辛亥,壬子,癸丑,甲寅,乙卯,丙辰,丁巳,戊午,己未,庚申,辛酉,壬戌,癸亥,甲子,乙丑,丙寅,丁卯,戊辰,己巳,庚午,辛未,壬申,癸酉,甲戌,乙亥,丙子,丁丑,戊寅,己卯,庚辰,辛巳,壬午,癸未" c.So(ganzhiListStr, ShouldEqual, testGanzhiListStr) }) } func Test_GetYearGanZhi(t *testing.T) { Convey("GetYearGanZhi", t, func(c C) { c.So(GetYearGanZhi(2012), ShouldEqual, "壬辰") c.So(GetYearGanZhi(2016), ShouldEqual, "丙申") c.So(GetYearGanZhi(2020), ShouldEqual, "庚子") }) } go-lib-5.6.0.9/calendar/lunar/mathutil.go000664 000000 000000 00000004646 13753517240 020113 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "math" ) // ToRadians 角度转换为弧度 func ToRadians(degrees float64) float64 { return degrees * math.Pi / 180 } // ToDegrees 弧度转换为角度 func ToDegrees(rad float64) float64 { return rad * 180 / math.Pi } // SecondsToRadians 把角秒换算成弧度 func SecondsToRadians(seconds float64) float64 { return ToRadians(SecondsToDegrees(seconds)) } // Mod2Pi 把角度限制在[0, 2π]之间 func Mod2Pi(r float64) float64 { for r < 0 { r += math.Pi * 2 } for r > 2*math.Pi { r -= math.Pi * 2 } return r } // ModPi 把角度限制在[-π, π]之间 func ModPi(r float64) float64 { for r < -math.Pi { r += math.Pi * 2 } for r > math.Pi { r -= math.Pi * 2 } return r } // SecondsToDegrees 把角秒换算成角度 func SecondsToDegrees(seconds float64) float64 { return seconds / 3600 } // DmsToDegrees 把度分秒表示的角度换算成度 func DmsToDegrees(degrees int, mintues int, seconds float64) float64 { return float64(degrees) + float64(mintues)/60 + seconds/3600 } // DmsToSeconds 把度分秒表示的角度换算成角秒(arcsecond) func DmsToSeconds(d int, m int, s float64) float64 { return float64(d)*3600 + float64(m)*60 + s } // DmsToRadians 把度分秒表示的角度换算成弧度(rad) func DmsToRadians(d int, m int, s float64) float64 { return ToRadians(DmsToDegrees(d, m, s)) } // NewtonIteration 牛顿迭代法求解方程的根 func NewtonIteration(f func(float64) float64, x0 float64) float64 { const Epsilon = 1e-7 const Delta = 5e-6 var x float64 for { x = x0 fx := f(x) // 导数 fpx := (f(x+Delta) - f(x-Delta)) / Delta / 2 x0 = x - fx/fpx if math.Abs(x0-x) <= Epsilon { break } } return x } go-lib-5.6.0.9/calendar/lunar/mathutil_test.go000664 000000 000000 00000004037 13753517240 021144 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( . "github.com/smartystreets/goconvey/convey" "math" "testing" ) func TestMathUtil(t *testing.T) { Convey("convert", t, func(c C) { c.Convey("ToRadians", func(c C) { c.So(ToRadians(90), ShouldEqual, math.Pi/2) }) c.Convey("SecondsToRadians", func(c C) { c.So(SecondsToRadians(648000), ShouldEqual, math.Pi) }) c.Convey("SecondsToDegrees", func(c C) { c.So(SecondsToDegrees(648000), ShouldEqual, 180) }) c.Convey("DmsToDegrees", func(c C) { c.So(DmsToDegrees(40, 11, 15), ShouldEqual, 40.1875) }) c.Convey("DmsToSeconds", func(c C) { c.So(DmsToSeconds(40, 11, 15), ShouldEqual, 144675) }) c.Convey("DmsToRadians", func(c C) { c.So(DmsToRadians(40, 11, 15), ShouldAlmostEqual, 0.7014041931452) }) }) Convey("modpi", t, func(c C) { c.Convey("Mod2Pi", func(c C) { rad := Mod2Pi(3 * math.Pi) c.So(rad, ShouldEqual, math.Pi) rad = Mod2Pi(-math.Pi) c.So(rad, ShouldEqual, math.Pi) }) c.Convey("ModPi", func(c C) { rad := ModPi(2 * math.Pi) c.So(rad, ShouldEqual, 0) rad = ModPi(-2 * math.Pi) c.So(rad, ShouldEqual, 0) }) }) Convey("NewtonIteration", t, func(c C) { var n float64 = 2 x := NewtonIteration( func(x float64) float64 { return x*x - n }, 1.4) c.So(x, ShouldAlmostEqual, math.Sqrt(2), 1e-7) }) } go-lib-5.6.0.9/calendar/lunar/newmoon.go000664 000000 000000 00000001705 13753517240 017737 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar func getNewMoonJD(jd0 float64) float64 { jd := NewtonIteration( func(x float64) float64 { return ModPi(GetEarthEclipticLongitudeForSun(x) - GetMoonEclipticLongitudeEC(x)) }, jd0) return jd } go-lib-5.6.0.9/calendar/lunar/newmoon_test.go000664 000000 000000 00000001765 13753517240 021004 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "pkg.deepin.io/lib/calendar/util" "testing" ) func Test_getNewMoonJD(t *testing.T) { jd0 := float64(util.ToJulianDate(2012, 1, 10)) t.Logf("jd0: %f", jd0) jd := getNewMoonJD(jd0) dt := util.GetDateTimeFromJulianDay(jd) t.Log(dt) } go-lib-5.6.0.9/calendar/lunar/solarterms.go000664 000000 000000 00000004164 13753517240 020452 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "math" "pkg.deepin.io/lib/calendar/util" ) var SolarTermNames = []string{ "春分", "清明", "谷雨", "立夏", "小满", "芒种", "夏至", "小暑", "大暑", "立秋", "处暑", "白露", "秋分", "寒露", "霜降", "立冬", "小雪", "大雪", "冬至", "小寒", "大寒", "立春", "雨水", "惊蛰", } const ( ChunFen int = iota QingMing GuYu LiXia XiaoMan MangZhong XiaZhi XiaoShu DaShu LiQiu ChuShu BaiLu QiuFen HanLu ShuangJiang LiDong XiaoXue DaXue DongZhi XiaoHan DaHan LiChun YuShui JingZhe ) // GetSolarTermName 获取二十四节气名 func GetSolarTermName(order int) string { if 0 <= order && order <= 23 { return SolarTermNames[order] } return "" } // GetSolarTermJD 使用牛顿迭代法计算24节气的时间 // f(x) = Vsop87dEarthUtil.getEarthEclipticLongitudeForSun(x) - angle = 0 // year 年 // order 节气序号 // 返回 节气的儒略日力学时间 TD func GetSolarTermJD(year, order int) float64 { const RADIANS_PER_TERM = math.Pi / 12.0 angle := float64(order) * RADIANS_PER_TERM month := ((order+1)/2+2)%12 + 1 // 春分 order 0 // 3 月 20 号 var day int = 6 if order%2 == 0 { day = 20 } jd0 := util.ToJulianDateHMS(year, month, day, 12, 0, 0.0) jd := NewtonIteration(func(x float64) float64 { return ModPi(GetEarthEclipticLongitudeForSun(x) - angle) }, jd0) return jd } go-lib-5.6.0.9/calendar/lunar/solarterms_test.go000664 000000 000000 00000003200 13753517240 021477 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( . "github.com/smartystreets/goconvey/convey" "pkg.deepin.io/lib/calendar/util" "strings" "testing" ) func TestSolarTerms(t *testing.T) { Convey("GetSolarTermName", t, func(c C) { c.So(GetSolarTermName(DongZhi), ShouldEqual, "冬至") var stNameList []string for i := -1; i < 25; i++ { name := GetSolarTermName(i) stNameList = append(stNameList, name) } stNameListStr := strings.Join(stNameList, ",") const testStNameListStr = ",春分,清明,谷雨,立夏,小满,芒种,夏至,小暑,大暑,立秋,处暑,白露,秋分,寒露,霜降,立冬,小雪,大雪,冬至,小寒,大寒,立春,雨水,惊蛰," c.So(stNameListStr, ShouldEqual, testStNameListStr) }) Convey("GetSolarTermJD", t, func(c C) { dongZhiJD := GetSolarTermJD(2016, DongZhi) dt := util.GetDateTimeFromJulianDay(dongZhiJD) c.So(dt.String(), ShouldEqual, "2016-12-21 10:44:08 +0000 UTC") }) } go-lib-5.6.0.9/calendar/lunar/vsop87earthd.go000664 000000 000000 00000006476 13753517240 020625 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "math" "pkg.deepin.io/lib/calendar/util" ) /** * 按儒略日计算地球的日心黄经 * * 参数: jd 儒略日 * 返回 地球的日心黄经,单位是弧度(rad) */ func GetSunEclipticLongitudeForEarth(jd float64) float64 { t := util.GetJulianThousandYears(jd) L0 := GetEarthL0(t) L1 := GetEarthL1(t) L2 := GetEarthL2(t) L3 := GetEarthL3(t) L4 := GetEarthL4(t) L5 := GetEarthL5(t) L := ((((L5*t+L4)*t+L3)*t+L2)*t+L1)*t + L0 return Mod2Pi(L) } /** * 按儒略日计算地球的日心黄纬 * * 参数 jd 儒略日 * 返回 地球的日心黄纬,单位是弧度(rad) */ func GetSunEclipticLatitudeForEarth(jd float64) float64 { t := util.GetJulianThousandYears(jd) B0 := GetEarthB0(t) B1 := GetEarthB1(t) B2 := GetEarthB2(t) B3 := GetEarthB3(t) B4 := GetEarthB4(t) B := ((((B4*t)+B3)*t+B2)*t+B1)*t + B0 return B } /** * 按照儒略日计算地球和太阳的距离 * * 参数 jd 儒略日 * 返回 地球和太阳的距离,单位是天文单位(au) */ func GetSunRadiusForEarth(jd float64) float64 { t := util.GetJulianThousandYears(jd) R0 := GetEarthR0(t) R1 := GetEarthR1(t) R2 := GetEarthR2(t) R3 := GetEarthR3(t) R4 := GetEarthR4(t) R5 := GetEarthR5(t) R := ((((R5*t+R4)*t+R3)*t+R2)*t+R1)*t + R0 return R } /** * 用于把vsop87理论算出来的经度转换成fk5目视系统的经度的修正值,参考 Jean Meeus 的 Astronomical * Algorithms 第二版(1998)第32章219页(32.3)式 * * 参数 l * vsop87经度(rad) * 参数 b * vsop87纬度(rad) * 参数 jd * 儒略日 * 返回 修正量(rad) */ func Vsop2Fk5LongitudeCorrection(l float64, b float64, jd float64) float64 { t := util.GetJulianCentury(jd) lp := l - ToRadians(1.397)*t - ToRadians(0.00031)*t*t return SecondsToRadians(-0.09033 + 0.03916*(math.Cos(lp)+math.Sin(lp))*math.Tan(b)) } /** * 计算修正后的太阳的地心视黄经 * * 参数 jd * 儒略日 * 返回 修正后的地心黄经(rad) */ // 常量 var lightAberration = SecondsToRadians(20.4898) func GetEarthEclipticLongitudeForSun(jd float64) float64 { // 计算地球的日心黄经 l := GetSunEclipticLongitudeForEarth(jd) // 计算地球的日心黄纬 b := GetSunEclipticLatitudeForEarth(jd) // 修正章动 l += CalcEarthLongitudeNutation(util.GetJulianCentury(jd)) // 转换到fk5 l += Vsop2Fk5LongitudeCorrection(l, b, jd) // 转换成太阳的地心黄经 l = Mod2Pi(l + math.Pi) // 计算光行差 // 计算日地距离 r := GetSunRadiusForEarth(jd) // 太阳到地球的光行差参数 l -= lightAberration / r return l } go-lib-5.6.0.9/calendar/lunar/vsop87earthd_const.go000664 000000 000000 00000461535 13753517240 022034 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "math" ) func GetEarthL0(t float64) float64 { var result float64 = 0.0 result += 1.75347045673 result += 0.03341656456 * math.Cos(4.66925680417+6283.0758499914*t) result += 0.00034894275 * math.Cos(4.62610241759+12566.1516999828*t) result += 3.417571e-05 * math.Cos(2.82886579606+3.523118349*t) result += 3.497056e-05 * math.Cos(2.74411800971+5753.3848848968*t) result += 3.135896e-05 * math.Cos(3.62767041758+77713.7714681205*t) result += 2.676218e-05 * math.Cos(4.41808351397+7860.4193924392*t) result += 2.342687e-05 * math.Cos(6.13516237631+3930.2096962196*t) result += 1.273166e-05 * math.Cos(2.03709655772+529.6909650946*t) result += 1.324292e-05 * math.Cos(0.74246356352+11506.7697697936*t) result += 9.01855e-06 * math.Cos(2.04505443513+26.2983197998*t) result += 1.199167e-05 * math.Cos(1.10962944315+1577.3435424478*t) result += 8.57223e-06 * math.Cos(3.50849156957+398.1490034082*t) result += 7.79786e-06 * math.Cos(1.17882652114+5223.6939198022*t) result += 9.9025e-06 * math.Cos(5.23268129594+5884.9268465832*t) result += 7.53141e-06 * math.Cos(2.53339053818+5507.5532386674*t) result += 5.05264e-06 * math.Cos(4.58292563052+18849.2275499742*t) result += 4.92379e-06 * math.Cos(4.20506639861+775.522611324*t) result += 3.56655e-06 * math.Cos(2.91954116867+0.0673103028*t) result += 2.84125e-06 * math.Cos(1.89869034186+796.2980068164*t) result += 2.4281e-06 * math.Cos(0.34481140906+5486.777843175*t) result += 3.17087e-06 * math.Cos(5.84901952218+11790.6290886588*t) result += 2.71039e-06 * math.Cos(0.31488607649+10977.078804699*t) result += 2.0616e-06 * math.Cos(4.80646606059+2544.3144198834*t) result += 2.05385e-06 * math.Cos(1.86947813692+5573.1428014331*t) result += 2.02261e-06 * math.Cos(2.45767795458+6069.7767545534*t) result += 1.26184e-06 * math.Cos(1.0830263021+20.7753954924*t) result += 1.55516e-06 * math.Cos(0.83306073807+213.299095438*t) result += 1.15132e-06 * math.Cos(0.64544911683+0.9803210682*t) result += 1.02851e-06 * math.Cos(0.63599846727+4694.0029547076*t) result += 1.01724e-06 * math.Cos(4.26679821365+7.1135470008*t) result += 9.9206e-07 * math.Cos(6.20992940258+2146.1654164752*t) result += 1.32212e-06 * math.Cos(3.41118275555+2942.4634232916*t) result += 9.7607e-07 * math.Cos(0.6810127227+155.4203994342*t) result += 8.5128e-07 * math.Cos(1.29870743025+6275.9623029906*t) result += 7.4651e-07 * math.Cos(1.75508916159+5088.6288397668*t) result += 1.01895e-06 * math.Cos(0.97569221824+15720.8387848784*t) result += 8.4711e-07 * math.Cos(3.67080093025+71430.6956181291*t) result += 7.3547e-07 * math.Cos(4.67926565481+801.8209311238*t) result += 7.3874e-07 * math.Cos(3.50319443167+3154.6870848956*t) result += 7.8756e-07 * math.Cos(3.03698313141+12036.4607348882*t) result += 7.9637e-07 * math.Cos(1.807913307+17260.1546546904*t) result += 8.5803e-07 * math.Cos(5.98322631256+161000.685737674*t) result += 5.6963e-07 * math.Cos(2.78430398043+6286.5989683404*t) result += 6.1148e-07 * math.Cos(1.81839811024+7084.8967811152*t) result += 6.9627e-07 * math.Cos(0.83297596966+9437.762934887*t) result += 5.6116e-07 * math.Cos(4.38694880779+14143.4952424306*t) result += 6.2449e-07 * math.Cos(3.97763880587+8827.3902698748*t) result += 5.1145e-07 * math.Cos(0.28306864501+5856.4776591154*t) result += 5.5577e-07 * math.Cos(3.47006009062+6279.5527316424*t) result += 4.1036e-07 * math.Cos(5.36817351402+8429.2412664666*t) result += 5.1605e-07 * math.Cos(1.33282746983+1748.016413067*t) result += 5.1992e-07 * math.Cos(0.18914945834+12139.5535091068*t) result += 4.9e-07 * math.Cos(0.48735065033+1194.4470102246*t) result += 3.92e-07 * math.Cos(6.16832995016+10447.3878396044*t) result += 3.5566e-07 * math.Cos(1.77597314691+6812.766815086*t) result += 3.677e-07 * math.Cos(6.04133859347+10213.285546211*t) result += 3.6596e-07 * math.Cos(2.56955238628+1059.3819301892*t) result += 3.3291e-07 * math.Cos(0.59309499459+17789.845619785*t) result += 3.5954e-07 * math.Cos(1.70876111898+2352.8661537718*t) result += 4.0938e-07 * math.Cos(2.39850881707+19651.048481098*t) result += 3.0047e-07 * math.Cos(2.73975123935+1349.8674096588*t) result += 3.0412e-07 * math.Cos(0.44294464135+83996.8473181119*t) result += 2.3663e-07 * math.Cos(0.48473567763+8031.0922630584*t) result += 2.3574e-07 * math.Cos(2.06527720049+3340.6124266998*t) result += 2.1089e-07 * math.Cos(4.14825464101+951.7184062506*t) result += 2.4738e-07 * math.Cos(0.21484762138+3.5904286518*t) result += 2.5352e-07 * math.Cos(3.16470953405+4690.4798363586*t) result += 2.282e-07 * math.Cos(5.22197888032+4705.7323075436*t) result += 2.1419e-07 * math.Cos(1.42563735525+16730.4636895958*t) result += 2.1891e-07 * math.Cos(5.55594302562+553.5694028424*t) result += 1.7481e-07 * math.Cos(4.56052900359+135.0650800354*t) result += 1.9925e-07 * math.Cos(5.22208471269+12168.0026965746*t) result += 1.986e-07 * math.Cos(5.77470167653+6309.3741697912*t) result += 2.03e-07 * math.Cos(0.37133792946+283.8593188652*t) result += 1.4421e-07 * math.Cos(4.19315332546+242.728603974*t) result += 1.6225e-07 * math.Cos(5.98837722564+11769.8536931664*t) result += 1.5077e-07 * math.Cos(4.19567181073+6256.7775301916*t) result += 1.9124e-07 * math.Cos(3.82219996949+23581.2581773176*t) result += 1.8888e-07 * math.Cos(5.38626880969+149854.400134808*t) result += 1.4346e-07 * math.Cos(3.72355084422+38.0276726358*t) result += 1.7898e-07 * math.Cos(2.21490735647+13367.9726311066*t) result += 1.2054e-07 * math.Cos(2.62229588349+955.5997416086*t) result += 1.1287e-07 * math.Cos(0.17739328092+4164.311989613*t) result += 1.3971e-07 * math.Cos(4.40138139996+6681.2248533996*t) result += 1.3621e-07 * math.Cos(1.88934471407+7632.9432596502*t) result += 1.2503e-07 * math.Cos(1.13052412208+5.5229243074*t) result += 1.0498e-07 * math.Cos(5.35909518669+1592.5960136328*t) result += 9.803e-08 * math.Cos(0.99947478995+11371.7046897582*t) result += 9.22e-08 * math.Cos(4.57138609781+4292.3308329504*t) result += 1.0327e-07 * math.Cos(6.19982566125+6438.4962494256*t) result += 1.2003e-07 * math.Cos(1.003514567+632.7837393132*t) result += 1.0827e-07 * math.Cos(0.32734520222+103.0927742186*t) result += 8.356e-08 * math.Cos(4.53902685948+25132.3033999656*t) result += 1.0005e-07 * math.Cos(6.0291496328+5746.271337896*t) result += 8.409e-08 * math.Cos(3.29946744189+7234.794256242*t) result += 8.006e-08 * math.Cos(5.82145271907+28.4491874678*t) result += 1.0523e-07 * math.Cos(0.93871805506+11926.2544136688*t) result += 7.686e-08 * math.Cos(3.12142363172+7238.6755916*t) result += 9.378e-08 * math.Cos(2.62414241032+5760.4984318976*t) result += 8.127e-08 * math.Cos(6.11228001785+4732.0306273434*t) result += 9.232e-08 * math.Cos(0.48343968736+522.5774180938*t) result += 9.802e-08 * math.Cos(5.24413991147+27511.4678735372*t) result += 7.871e-08 * math.Cos(0.99590177926+5643.1785636774*t) result += 8.123e-08 * math.Cos(6.2705301365+426.598190876*t) result += 9.048e-08 * math.Cos(5.33686335897+6386.16862421*t) result += 8.62e-08 * math.Cos(4.16538210888+7058.5984613154*t) result += 6.297e-08 * math.Cos(4.71724819317+6836.6452528338*t) result += 7.575e-08 * math.Cos(3.97382858911+11499.6562227928*t) result += 7.756e-08 * math.Cos(2.95729056763+23013.5395395872*t) result += 7.314e-08 * math.Cos(0.60652505806+11513.8833167944*t) result += 5.955e-08 * math.Cos(2.87641047971+6283.14316029419*t) result += 6.534e-08 * math.Cos(5.79072926033+18073.7049386502*t) result += 7.188e-08 * math.Cos(3.99831508699+74.7815985673*t) result += 7.346e-08 * math.Cos(4.38582365437+316.3918696566*t) result += 5.413e-08 * math.Cos(5.39199024641+419.4846438752*t) result += 5.127e-08 * math.Cos(2.36062848786+10973.55568635*t) result += 7.056e-08 * math.Cos(0.32258441903+263.0839233728*t) result += 6.625e-08 * math.Cos(3.66475158672+17298.1823273262*t) result += 6.762e-08 * math.Cos(5.91132535899+90955.5516944961*t) result += 4.938e-08 * math.Cos(5.73672165674+9917.6968745098*t) result += 5.547e-08 * math.Cos(2.45152597661+12352.8526045448*t) result += 5.958e-08 * math.Cos(3.32051344676+6283.0085396886*t) result += 4.471e-08 * math.Cos(2.06385999536+7079.3738568078*t) result += 6.153e-08 * math.Cos(1.45823331144+233141.314404362*t) result += 4.348e-08 * math.Cos(4.4234217548+5216.5803728014*t) result += 6.123e-08 * math.Cos(1.07494905258+19804.8272915828*t) result += 4.488e-08 * math.Cos(3.6528503715+206.1855484372*t) result += 4.02e-08 * math.Cos(0.83995823171+20.3553193988*t) result += 5.188e-08 * math.Cos(4.06503864016+6208.2942514241*t) result += 5.307e-08 * math.Cos(0.38217636096+31441.6775697568*t) result += 3.785e-08 * math.Cos(2.34369213733+3.881335358*t) result += 4.497e-08 * math.Cos(3.27230796845+11015.1064773348*t) result += 4.132e-08 * math.Cos(0.92128915753+3738.761430108*t) result += 3.521e-08 * math.Cos(5.97844807108+3894.1818295422*t) result += 4.215e-08 * math.Cos(1.90601120623+245.8316462294*t) result += 3.701e-08 * math.Cos(5.03069397926+536.8045120954*t) result += 3.865e-08 * math.Cos(1.82634360607+11856.2186514245*t) result += 3.652e-08 * math.Cos(1.01838584934+16200.7727245012*t) result += 3.39e-08 * math.Cos(0.97785123922+8635.9420037632*t) result += 3.737e-08 * math.Cos(2.95380107829+3128.3887650958*t) result += 3.507e-08 * math.Cos(3.71291946325+6290.1893969922*t) result += 3.086e-08 * math.Cos(3.64646921512+10.6366653498*t) result += 3.397e-08 * math.Cos(1.10590684017+14712.317116458*t) result += 3.334e-08 * math.Cos(0.83684924911+6496.3749454294*t) result += 2.805e-08 * math.Cos(2.58504514144+14314.1681130498*t) result += 3.65e-08 * math.Cos(1.08344142571+88860.0570709867*t) result += 3.388e-08 * math.Cos(3.20185096055+5120.6011455836*t) result += 3.252e-08 * math.Cos(3.47859752062+6133.5126528568*t) result += 2.553e-08 * math.Cos(3.94869034189+1990.745017041*t) result += 3.52e-08 * math.Cos(2.05559692878+244287.600007228*t) result += 2.565e-08 * math.Cos(1.560717849+23543.2305046818*t) result += 2.621e-08 * math.Cos(3.85639359951+266.6070417218*t) result += 2.955e-08 * math.Cos(3.39692949667+9225.539273283*t) result += 2.876e-08 * math.Cos(6.02635617464+154717.609887683*t) result += 2.395e-08 * math.Cos(1.16131956403+10984.1923516998*t) result += 3.161e-08 * math.Cos(1.32798718453+10873.9860304804*t) result += 3.163e-08 * math.Cos(5.08946464629+21228.3920235458*t) result += 2.361e-08 * math.Cos(4.27212906992+6040.3472460174*t) result += 3.03e-08 * math.Cos(1.80209931347+35371.8872659764*t) result += 2.343e-08 * math.Cos(3.576898605+10969.9652576982*t) result += 2.618e-08 * math.Cos(2.57870156528+22483.8485744926*t) result += 2.113e-08 * math.Cos(3.71393780256+65147.6197681377*t) result += 2.019e-08 * math.Cos(0.81393923319+170.6728706192*t) result += 2.003e-08 * math.Cos(0.38091017375+6172.869528772*t) result += 2.506e-08 * math.Cos(3.74379142438+10575.4066829418*t) result += 2.381e-08 * math.Cos(0.10581361289+7.046236698*t) result += 1.949e-08 * math.Cos(4.86892513469+36.0278666774*t) result += 2.074e-08 * math.Cos(4.2279477457+5650.2921106782*t) result += 1.924e-08 * math.Cos(5.5946054986+6282.0955289232*t) result += 1.949e-08 * math.Cos(1.07002512703+5230.807466803*t) result += 1.988e-08 * math.Cos(5.19736046771+6262.300454499*t) result += 1.887e-08 * math.Cos(3.74365662683+23.8784377478*t) result += 1.787e-08 * math.Cos(1.25929682929+12559.038152982*t) result += 1.883e-08 * math.Cos(1.90364058477+15.252471185*t) result += 1.816e-08 * math.Cos(3.68083868442+15110.4661198662*t) result += 1.701e-08 * math.Cos(4.4110589538+110.2063212194*t) result += 1.99e-08 * math.Cos(3.93295788548+6206.8097787158*t) result += 2.103e-08 * math.Cos(0.75354917468+13521.7514415914*t) result += 1.774e-08 * math.Cos(0.48747535361+1551.045222648*t) result += 1.882e-08 * math.Cos(0.86684493432+22003.9146348698*t) result += 1.924e-08 * math.Cos(1.22898324132+709.9330485583*t) result += 2.009e-08 * math.Cos(4.6285092198+6037.244203762*t) result += 1.924e-08 * math.Cos(0.60231842508+6284.0561710596*t) result += 1.596e-08 * math.Cos(3.98332956992+13916.0191096416*t) result += 1.664e-08 * math.Cos(4.41939715469+8662.240323563*t) result += 1.971e-08 * math.Cos(1.04560500503+18209.3302636602*t) result += 1.942e-08 * math.Cos(4.31335979989+6244.9428143536*t) result += 1.476e-08 * math.Cos(0.93271367331+2379.1644735716*t) result += 1.81e-08 * math.Cos(0.49112137707+1.4844727083*t) result += 1.346e-08 * math.Cos(1.51574702235+4136.9104335162*t) result += 1.528e-08 * math.Cos(5.61835711404+6127.6554505572*t) result += 1.791e-08 * math.Cos(3.22187270126+39302.096962196*t) result += 1.747e-08 * math.Cos(3.05638656738+18319.5365848796*t) result += 1.431e-08 * math.Cos(4.51153808594+20426.571092422*t) result += 1.695e-08 * math.Cos(0.22047718414+25158.6017197654*t) result += 1.242e-08 * math.Cos(4.46665769933+17256.6315363414*t) result += 1.463e-08 * math.Cos(4.69242679213+14945.3161735544*t) result += 1.205e-08 * math.Cos(1.86912144659+4590.910180489*t) result += 1.192e-08 * math.Cos(2.74227166898+12569.6748183318*t) result += 1.222e-08 * math.Cos(5.18120087482+5333.9002410216*t) result += 1.39e-08 * math.Cos(5.42894648983+143571.324284816*t) result += 1.473e-08 * math.Cos(1.70479245805+11712.9553182308*t) result += 1.362e-08 * math.Cos(2.61069503292+6062.6632075526*t) result += 1.148e-08 * math.Cos(6.0300180054+3634.6210245184*t) result += 1.198e-08 * math.Cos(5.15294130422+10177.2576795336*t) result += 1.266e-08 * math.Cos(0.11421493643+18422.6293590982*t) result += 1.411e-08 * math.Cos(1.09908857534+3496.032826134*t) result += 1.349e-08 * math.Cos(2.99805109633+17654.7805397496*t) result += 1.253e-08 * math.Cos(2.79850152848+167283.761587666*t) result += 1.311e-08 * math.Cos(1.60942984879+5481.2549188676*t) result += 1.079e-08 * math.Cos(6.20304501787+3.2863574178*t) result += 1.181e-08 * math.Cos(1.20653776978+131.5419616864*t) result += 1.254e-08 * math.Cos(5.45103277798+6076.8903015542*t) result += 1.035e-08 * math.Cos(2.32142722747+7342.4577801806*t) result += 1.117e-08 * math.Cos(0.38838354256+949.1756089698*t) result += 9.66e-09 * math.Cos(3.18341890851+11087.2851259184*t) result += 1.171e-08 * math.Cos(3.39635049962+12562.6285816338*t) result += 1.121e-08 * math.Cos(0.72627490378+220.4126424388*t) result += 1.024e-08 * math.Cos(2.19378315386+11403.676995575*t) result += 8.88e-09 * math.Cos(3.91173199285+4686.8894077068*t) result += 9.1e-09 * math.Cos(1.98802695087+735.8765135318*t) result += 8.3e-09 * math.Cos(0.48984915507+24072.9214697764*t) result += 1.096e-08 * math.Cos(6.17377835617+5436.9930152402*t) result += 9.08e-09 * math.Cos(0.44959639433+7477.522860216*t) result += 9.74e-09 * math.Cos(1.52996238356+9623.6882766912*t) result += 8.4e-09 * math.Cos(1.79543266333+5429.8794682394*t) result += 7.78e-09 * math.Cos(6.17699177946+38.1330356378*t) result += 7.76e-09 * math.Cos(4.09855402433+14.2270940016*t) result += 1.068e-08 * math.Cos(4.64200173735+43232.3066584156*t) result += 9.54e-09 * math.Cos(1.49988435748+1162.4747044078*t) result += 9.07e-09 * math.Cos(0.86986870809+10344.2950653858*t) result += 9.31e-09 * math.Cos(4.06044689031+28766.924424484*t) result += 7.39e-09 * math.Cos(5.04368197372+639.897286314*t) result += 9.37e-09 * math.Cos(3.4688469896+1589.0728952838*t) result += 7.63e-09 * math.Cos(5.86304932998+16858.4825329332*t) result += 9.53e-09 * math.Cos(4.20801492835+11190.377900137*t) result += 7.08e-09 * math.Cos(1.7289998894+13095.8426650774*t) result += 9.69e-09 * math.Cos(1.64439522215+29088.811415985*t) result += 7.17e-09 * math.Cos(0.16688678895+11.729352836*t) result += 9.62e-09 * math.Cos(3.53092337542+12416.5885028482*t) result += 7.47e-09 * math.Cos(5.77866940346+12592.4500197826*t) result += 6.72e-09 * math.Cos(1.91095796194+3.9321532631*t) result += 6.71e-09 * math.Cos(5.46240843677+18052.9295431578*t) result += 6.75e-09 * math.Cos(6.28311558823+4535.0594369244*t) result += 6.84e-09 * math.Cos(0.3997501208+5849.3641121146*t) result += 7.99e-09 * math.Cos(0.29851185294+12132.439962106*t) result += 7.58e-09 * math.Cos(0.96370823331+1052.2683831884*t) result += 7.82e-09 * math.Cos(5.33878339919+13517.8701062334*t) result += 7.3e-09 * math.Cos(1.70106160291+17267.2682016912*t) result += 7.49e-09 * math.Cos(2.59599901875+11609.8625440122*t) result += 7.34e-09 * math.Cos(2.78417782952+640.8776073822*t) result += 6.88e-09 * math.Cos(5.15048287468+16496.3613962024*t) result += 7.7e-09 * math.Cos(1.62469589333+4701.1165017084*t) result += 6.33e-09 * math.Cos(2.20587893893+25934.1243310894*t) result += 7.6e-09 * math.Cos(4.21317219403+377.3736079158*t) result += 5.84e-09 * math.Cos(2.13420121623+10557.5941608238*t) result += 5.74e-09 * math.Cos(0.24250054587+9779.1086761254*t) result += 5.73e-09 * math.Cos(3.16435264609+533.2140834436*t) result += 6.85e-09 * math.Cos(3.19344289472+12146.6670561076*t) result += 6.75e-09 * math.Cos(0.96179233959+10454.5013866052*t) result += 6.48e-09 * math.Cos(1.46327342555+6268.8487559898*t) result += 5.89e-09 * math.Cos(2.50543543638+3097.88382272579*t) result += 5.51e-09 * math.Cos(5.28099026956+9388.0059094152*t) result += 6.96e-09 * math.Cos(3.65342150016+4804.209275927*t) result += 6.69e-09 * math.Cos(2.51030077026+2388.8940204492*t) result += 5.5e-09 * math.Cos(0.06883864342+20199.094959633*t) result += 6.29e-09 * math.Cos(4.13350995675+45892.730433157*t) result += 6.78e-09 * math.Cos(6.09190163533+135.62532501*t) result += 5.93e-09 * math.Cos(1.50136257618+226858.23855437*t) result += 5.42e-09 * math.Cos(3.58573645173+6148.010769956*t) result += 6.82e-09 * math.Cos(5.02203067788+17253.0411076896*t) result += 5.65e-09 * math.Cos(4.2930923861+11933.3679606696*t) result += 4.86e-09 * math.Cos(0.77746204893+27.4015560968*t) result += 5.03e-09 * math.Cos(0.58963565969+15671.0817594066*t) result += 6.16e-09 * math.Cos(4.06539884128+227.476132789*t) result += 5.83e-09 * math.Cos(6.12695541996+18875.525869774*t) result += 5.37e-09 * math.Cos(2.1505644098+21954.157609398*t) result += 6.69e-09 * math.Cos(6.06986269566+47162.5163546352*t) result += 4.75e-09 * math.Cos(0.4034384211+6915.8595893046*t) result += 5.4e-09 * math.Cos(2.83444222174+5326.7866940208*t) result += 5.3e-09 * math.Cos(5.26359885263+10988.808157535*t) result += 5.82e-09 * math.Cos(3.24533095664+153.7788104848*t) result += 6.41e-09 * math.Cos(3.24711791371+2107.0345075424*t) result += 6.21e-09 * math.Cos(3.09698523779+33019.0211122046*t) result += 4.66e-09 * math.Cos(3.14982372198+10440.2742926036*t) result += 4.66e-09 * math.Cos(0.90708835657+5966.6839803348*t) result += 5.28e-09 * math.Cos(0.8192645447+813.5502839598*t) result += 6.03e-09 * math.Cos(3.81378921927+316428.228673915*t) result += 5.59e-09 * math.Cos(1.81894804124+17996.0311682222*t) result += 4.37e-09 * math.Cos(2.28625594435+6303.8512454838*t) result += 5.18e-09 * math.Cos(4.86069178322+20597.2439630412*t) result += 4.24e-09 * math.Cos(6.23520018693+6489.2613984286*t) result += 5.18e-09 * math.Cos(6.17617826756+0.2438174835*t) result += 4.04e-09 * math.Cos(5.72804304258+5642.1982426092*t) result += 4.58e-09 * math.Cos(1.34117773915+6287.0080032545*t) result += 5.48e-09 * math.Cos(5.6845445832+155427.542936241*t) result += 5.47e-09 * math.Cos(1.03391472061+3646.3503773544*t) result += 4.28e-09 * math.Cos(4.69800981138+846.0828347512*t) result += 4.13e-09 * math.Cos(6.02520699406+6279.4854213396*t) result += 5.34e-09 * math.Cos(3.03030638223+66567.4858652543*t) result += 3.83e-09 * math.Cos(1.49056949125+19800.9459562248*t) result += 4.1e-09 * math.Cos(5.28319622279+18451.078546566*t) result += 3.52e-09 * math.Cos(4.68891600359+4907.3020501456*t) result += 4.8e-09 * math.Cos(5.36572651091+348.924420448*t) result += 3.44e-09 * math.Cos(5.89157452896+6546.1597733642*t) result += 3.4e-09 * math.Cos(0.3755742644+13119.7211028252*t) result += 4.34e-09 * math.Cos(4.98417785901+6702.5604938666*t) result += 3.32e-09 * math.Cos(2.68902519126+29296.6153895786*t) result += 4.48e-09 * math.Cos(2.16478480251+5905.7022420756*t) result += 3.44e-09 * math.Cos(2.06546633735+49.7570254718*t) result += 3.15e-09 * math.Cos(1.24023811803+4061.2192153944*t) result += 3.24e-09 * math.Cos(2.30897526929+5017.508371365*t) result += 4.13e-09 * math.Cos(0.17171692962+6286.6662786432*t) result += 4.31e-09 * math.Cos(3.86601101393+12489.8856287072*t) result += 3.49e-09 * math.Cos(4.55372342974+4933.2084403326*t) result += 3.23e-09 * math.Cos(0.41971136084+10770.8932562618*t) result += 3.41e-09 * math.Cos(2.68612860807+11.0457002639*t) result += 3.16e-09 * math.Cos(3.52936906658+17782.7320727842*t) result += 3.15e-09 * math.Cos(5.63357264999+568.8218740274*t) result += 3.4e-09 * math.Cos(3.83571212349+10660.6869350424*t) result += 2.97e-09 * math.Cos(0.62691416712+20995.3929664494*t) result += 4.05e-09 * math.Cos(1.00085779471+16460.333529525*t) result += 4.14e-09 * math.Cos(1.21998752076+51092.7260508548*t) result += 3.36e-09 * math.Cos(4.71465945226+6179.9830757728*t) result += 3.61e-09 * math.Cos(3.71227508354+28237.2334593894*t) result += 3.85e-09 * math.Cos(6.21925225757+24356.7807886416*t) result += 3.27e-09 * math.Cos(1.05606504715+11919.140866668*t) result += 3.27e-09 * math.Cos(6.14222420989+6254.6266625236*t) result += 2.68e-09 * math.Cos(2.47224339737+664.75604513*t) result += 2.69e-09 * math.Cos(1.86207884109+23141.5583829246*t) result += 3.45e-09 * math.Cos(0.93461290184+6058.7310542895*t) result += 2.96e-09 * math.Cos(4.5168755718+6418.1409300268*t) result += 3.53e-09 * math.Cos(4.50033653082+36949.2308084242*t) result += 2.6e-09 * math.Cos(4.04963546305+6525.8044539654*t) result += 2.98e-09 * math.Cos(2.20046722622+156137.475984799*t) result += 2.53e-09 * math.Cos(3.49900838384+29864.334027309*t) result += 2.54e-09 * math.Cos(2.44901693835+5331.3574437408*t) result += 2.96e-09 * math.Cos(0.84347588787+5729.506447149*t) result += 2.98e-09 * math.Cos(1.29194706125+22805.7355659936*t) result += 2.41e-09 * math.Cos(2.00721280805+16737.5772365966*t) result += 3.11e-09 * math.Cos(1.23668016334+6281.5913772831*t) result += 2.4e-09 * math.Cos(2.51650377121+6245.0481773556*t) result += 3.32e-09 * math.Cos(3.55576945724+7668.6374249425*t) result += 2.64e-09 * math.Cos(4.44052061202+12964.300703391*t) result += 2.57e-09 * math.Cos(1.79654471948+11080.1715789176*t) result += 2.6e-09 * math.Cos(3.3307759842+5888.4499649322*t) result += 2.85e-09 * math.Cos(0.3088636143+11823.1616394502*t) result += 2.9e-09 * math.Cos(5.70141882483+77.673770428*t) result += 2.55e-09 * math.Cos(4.0093966444+5881.4037282342*t) result += 2.53e-09 * math.Cos(4.73318493678+16723.350142595*t) result += 2.28e-09 * math.Cos(0.95333661324+5540.0857894588*t) result += 3.19e-09 * math.Cos(1.38633229189+163096.180361183*t) result += 2.24e-09 * math.Cos(1.65156322696+10027.9031957292*t) result += 2.26e-09 * math.Cos(0.34106460604+17796.9591667858*t) result += 2.36e-09 * math.Cos(4.19817431922+19.66976089979*t) result += 2.8e-09 * math.Cos(4.1408026897+12539.853380183*t) result += 2.75e-09 * math.Cos(5.50306930248+32.5325507914*t) result += 2.23e-09 * math.Cos(5.23334210294+56.8983749356*t) result += 2.17e-09 * math.Cos(6.08587881787+6805.6532680852*t) result += 2.8e-09 * math.Cos(4.52472044653+6016.4688082696*t) result += 2.27e-09 * math.Cos(5.06509843737+6277.552925684*t) result += 2.26e-09 * math.Cos(5.17755154305+11720.0688652316*t) result += 2.45e-09 * math.Cos(3.96486270306+22.7752014508*t) result += 2.2e-09 * math.Cos(4.7207808197+6.62855890001*t) result += 2.07e-09 * math.Cos(5.71701403951+41.5507909848*t) result += 2.04e-09 * math.Cos(3.9122741125+2699.7348193176*t) result += 2.09e-09 * math.Cos(0.86881969011+6321.1035226272*t) result += 2e-09 * math.Cos(2.11984445273+4274.5183108324*t) result += 2e-09 * math.Cos(5.39839888163+6019.9919266186*t) result += 2.09e-09 * math.Cos(5.67606291663+11293.4706743556*t) result += 2.52e-09 * math.Cos(1.64965729351+9380.9596727172*t) result += 2.75e-09 * math.Cos(5.04826903506+73.297125859*t) result += 2.08e-09 * math.Cos(1.88207277133+11300.5842213564*t) result += 2.72e-09 * math.Cos(0.74640926842+1975.492545856*t) result += 1.99e-09 * math.Cos(3.30836672397+22743.4093795164*t) result += 2.69e-09 * math.Cos(4.48560812155+64471.9912417449*t) result += 1.92e-09 * math.Cos(2.17464236325+5863.5912061162*t) result += 2.28e-09 * math.Cos(5.85373115869+128.0188433374*t) result += 2.61e-09 * math.Cos(2.64321183295+55022.9357470744*t) result += 2.2e-09 * math.Cos(5.75012110079+29.429508536*t) result += 1.87e-09 * math.Cos(4.03230554718+467.9649903544*t) result += 2e-09 * math.Cos(5.60556112058+1066.49547719*t) result += 2.31e-09 * math.Cos(1.09802712785+12341.8069042809*t) result += 1.99e-09 * math.Cos(0.295006252+149.5631971346*t) result += 2.49e-09 * math.Cos(5.10473210814+7875.6718636242*t) result += 2.08e-09 * math.Cos(0.93013835019+14919.0178537546*t) result += 1.79e-09 * math.Cos(0.87104393079+12721.572099417*t) result += 2.03e-09 * math.Cos(1.56920753653+28286.9904848612*t) result += 1.79e-09 * math.Cos(2.47036386443+16062.1845261168*t) result += 1.98e-09 * math.Cos(3.54061588502+30.914125635*t) result += 1.71e-09 * math.Cos(3.45356518113+5327.4761083828*t) result += 1.83e-09 * math.Cos(0.72325421604+6272.0301497275*t) result += 2.16e-09 * math.Cos(2.97174580686+19402.7969528166*t) result += 1.68e-09 * math.Cos(2.51550550242+23937.856389741*t) result += 1.95e-09 * math.Cos(0.09045393425+156.4007205024*t) result += 1.79e-09 * math.Cos(4.4947179809+31415.379249957*t) result += 2.16e-09 * math.Cos(0.42177594328+23539.7073863328*t) result += 1.89e-09 * math.Cos(0.37542530191+9814.6041002912*t) result += 2.18e-09 * math.Cos(2.36835880025+16627.3709153772*t) result += 1.66e-09 * math.Cos(4.23182968446+16840.6700108152*t) result += 2e-09 * math.Cos(2.02153258098+16097.6799502826*t) result += 1.69e-09 * math.Cos(0.91318727+95.9792272178*t) result += 2.11e-09 * math.Cos(5.73370637657+151.8972810852*t) result += 2.04e-09 * math.Cos(0.42643085174+515.463871093*t) result += 2.12e-09 * math.Cos(3.00233538977+12043.574281889*t) result += 1.92e-09 * math.Cos(5.46153589821+6379.0550772092*t) result += 1.65e-09 * math.Cos(1.38698167064+4171.4255366138*t) result += 1.6e-09 * math.Cos(6.23798383332+202.2533951741*t) result += 2.15e-09 * math.Cos(0.20889073407+5621.8429232104*t) result += 1.81e-09 * math.Cos(4.12439203622+13341.6743113068*t) result += 1.53e-09 * math.Cos(1.24460848836+29826.3063546732*t) result += 1.5e-09 * math.Cos(3.12999753018+799.8211251654*t) result += 1.75e-09 * math.Cos(4.55671604437+239424.390254353*t) result += 1.92e-09 * math.Cos(1.33928820063+394.6258850592*t) result += 1.49e-09 * math.Cos(2.65697593276+21.335640467*t) result += 1.46e-09 * math.Cos(5.58021191726+412.3710968744*t) result += 1.56e-09 * math.Cos(3.75650175503+12323.4230960088*t) result += 1.43e-09 * math.Cos(3.75708566606+58864.5439181463*t) result += 1.43e-09 * math.Cos(3.28248547724+29.8214381488*t) result += 1.44e-09 * math.Cos(1.07862546598+1265.5674786264*t) result += 1.48e-09 * math.Cos(0.23389236655+10021.8372800994*t) result += 1.93e-09 * math.Cos(5.92751083086+40879.4405046438*t) result += 1.4e-09 * math.Cos(4.97612440269+158.9435177832*t) result += 1.48e-09 * math.Cos(2.61640453469+17157.0618804718*t) result += 1.41e-09 * math.Cos(3.66871308723+26084.0218062162*t) result += 1.47e-09 * math.Cos(5.09968173403+661.232926781*t) result += 1.46e-09 * math.Cos(4.96885605695+57375.8019008462*t) result += 1.42e-09 * math.Cos(0.78678347839+12779.4507954208*t) result += 1.34e-09 * math.Cos(4.79432636012+111.1866422876*t) result += 1.4e-09 * math.Cos(1.27748013377+107.6635239386*t) result += 1.69e-09 * math.Cos(2.74893543762+26735.9452622132*t) result += 1.65e-09 * math.Cos(3.95288000638+6357.8574485587*t) result += 1.83e-09 * math.Cos(5.43418358741+369.6998159404*t) result += 1.34e-09 * math.Cos(3.09132862833+17.812522118*t) result += 1.32e-09 * math.Cos(3.05633896779+22490.9621214934*t) result += 1.34e-09 * math.Cos(4.09472795832+6599.467719648*t) result += 1.81e-09 * math.Cos(4.22950689891+966.9708774356*t) result += 1.52e-09 * math.Cos(5.28885894415+12669.2444742014*t) result += 1.5e-09 * math.Cos(5.86819430908+97238.6275444875*t) result += 1.42e-09 * math.Cos(5.87266532526+22476.7350274918*t) result += 1.45e-09 * math.Cos(5.07330784304+87.30820453981*t) result += 1.33e-09 * math.Cos(5.65471067133+31.9723058168*t) result += 1.24e-09 * math.Cos(2.83326217072+12566.2190102856*t) result += 1.35e-09 * math.Cos(3.12861731644+32217.2001810808*t) result += 1.37e-09 * math.Cos(0.86487461904+9924.8104215106*t) result += 1.72e-09 * math.Cos(1.98369595114+174242.46596405*t) result += 1.7e-09 * math.Cos(4.41115280254+327574.514276781*t) result += 1.51e-09 * math.Cos(0.46542099527+39609.6545831656*t) result += 1.48e-09 * math.Cos(2.13439571118+491.6632924588*t) result += 1.53e-09 * math.Cos(3.78801830344+17363.247428909*t) result += 1.65e-09 * math.Cos(5.31654110459+16943.7627850338*t) result += 1.65e-09 * math.Cos(4.06747587817+58953.145443294*t) result += 1.18e-09 * math.Cos(0.63846333239+6.0659156298*t) result += 1.59e-09 * math.Cos(0.86086959274+221995.028801495*t) result += 1.19e-09 * math.Cos(5.96432932413+1385.8952763362*t) result += 1.14e-09 * math.Cos(5.16516114595+25685.872802808*t) result += 1.12e-09 * math.Cos(3.39403722178+21393.5419698576*t) result += 1.12e-09 * math.Cos(4.92889233335+56.8032621698*t) result += 1.19e-09 * math.Cos(2.40637635942+18635.9284545362*t) result += 1.15e-09 * math.Cos(0.23374479051+418.9243989006*t) result += 1.22e-09 * math.Cos(0.93575234049+24492.4061136516*t) result += 1.15e-09 * math.Cos(4.58880032176+26709.6469424134*t) result += 1.3e-09 * math.Cos(4.85539251+22345.2603761082*t) result += 1.4e-09 * math.Cos(1.09413073202+44809.6502008634*t) result += 1.12e-09 * math.Cos(6.05401806281+433.7117378768*t) result += 1.04e-09 * math.Cos(1.54931540602+127.9515330346*t) result += 1.05e-09 * math.Cos(4.82620858888+33794.5437235286*t) result += 1.02e-09 * math.Cos(4.12448497391+15664.0355227086*t) result += 1.07e-09 * math.Cos(4.67919356465+77690.7595057385*t) result += 1.18e-09 * math.Cos(4.5232017012+19004.6479494084*t) result += 1.07e-09 * math.Cos(5.71774478555+77736.7834305025*t) result += 1.43e-09 * math.Cos(1.81201813018+4214.0690150848*t) result += 1.25e-09 * math.Cos(1.14419195615+625.6701923124*t) result += 1.24e-09 * math.Cos(3.27736514057+12566.08438968*t) result += 1.1e-09 * math.Cos(1.08682570828+2787.0430238574*t) result += 1.05e-09 * math.Cos(1.78318141871+18139.2945014159*t) result += 1.02e-09 * math.Cos(4.75119578149+12242.6462833254*t) result += 1.37e-09 * math.Cos(1.43510636754+86464.6133168312*t) result += 1.01e-09 * math.Cos(4.91289409429+401.6721217572*t) result += 1.29e-09 * math.Cos(1.23567904485+12029.3471878874*t) result += 1.38e-09 * math.Cos(2.45654707999+7576.560073574*t) result += 1.03e-09 * math.Cos(0.40004073416+90279.9231681033*t) result += 1.08e-09 * math.Cos(0.9898977494+5636.0650166766*t) result += 1.17e-09 * math.Cos(5.17362872063+34520.3093093808*t) result += 1e-09 * math.Cos(3.95534628189+5547.1993364596*t) result += 9.8e-10 * math.Cos(1.28118280598+21548.9623692918*t) result += 9.7e-10 * math.Cos(3.34717130592+16310.9790457206*t) result += 9.8e-10 * math.Cos(4.37041908717+34513.2630726828*t) result += 1.25e-09 * math.Cos(2.7216443296+24065.8079227756*t) result += 1.02e-09 * math.Cos(0.66938025772+10239.5838660108*t) result += 1.19e-09 * math.Cos(1.21689479331+1478.8665740644*t) result += 9.4e-10 * math.Cos(1.99595224256+13362.4497067992*t) result += 9.4e-10 * math.Cos(4.30965982872+26880.3198130326*t) result += 9.5e-10 * math.Cos(2.89807657534+34911.412076091*t) result += 1.06e-09 * math.Cos(1.0015665359+16522.6597160022*t) result += 9.7e-10 * math.Cos(0.89642320201+71980.6335747312*t) result += 1.16e-09 * math.Cos(4.19967201116+206.7007372966*t) result += 9.9e-10 * math.Cos(1.37437847718+1039.0266107904*t) result += 1.26e-09 * math.Cos(3.21642544972+305281.943071049*t) result += 9.4e-10 * math.Cos(0.6899787606+7834.1210726394*t) result += 9.4e-10 * math.Cos(5.58132218606+3104.9300594238*t) result += 9.5e-10 * math.Cos(3.0382374111+8982.810669309*t) result += 1.08e-09 * math.Cos(0.52696637156+276.7457718644*t) result += 1.24e-09 * math.Cos(3.43899862683+172146.97134054*t) result += 1.02e-09 * math.Cos(1.04031728553+95143.1329209781*t) result += 1.04e-09 * math.Cos(3.39218586218+290.972865866*t) result += 1.1e-09 * math.Cos(3.68205877433+22380.755800274*t) result += 1.17e-09 * math.Cos(0.78475956902+83286.9142695536*t) result += 8.3e-10 * math.Cos(0.18241793425+15141.390794312*t) result += 8.9e-10 * math.Cos(4.45371820659+792.7748884674*t) result += 8.2e-10 * math.Cos(4.80703651241+6819.8803620868*t) result += 8.7e-10 * math.Cos(3.43122851097+27707.5424942948*t) result += 1.01e-09 * math.Cos(5.32081603011+2301.58581590939*t) result += 8.2e-10 * math.Cos(0.87060089842+10241.2022911672*t) result += 8.6e-10 * math.Cos(4.61919461931+36147.4098773004*t) result += 9.5e-10 * math.Cos(2.87032884659+23020.653086588*t) result += 8.8e-10 * math.Cos(3.2113316569+33326.5787331742*t) result += 8e-10 * math.Cos(1.84900424847+21424.4666443034*t) result += 1.01e-09 * math.Cos(4.18796434479+30666.1549584328*t) result += 1.07e-09 * math.Cos(5.77864921649+34115.1140692746*t) result += 1.04e-09 * math.Cos(1.08739495962+6288.5987742988*t) result += 1.1e-09 * math.Cos(3.32898859416+72140.6286666874*t) result += 8.7e-10 * math.Cos(4.40657711727+142.1786270362*t) result += 1.09e-09 * math.Cos(1.94546030825+24279.1070182136*t) result += 8.7e-10 * math.Cos(4.32472045435+742.9900605326*t) result += 1.07e-09 * math.Cos(4.91580912547+277.0349937414*t) result += 8.8e-10 * math.Cos(2.10180220766+26482.1708096244*t) result += 8.6e-10 * math.Cos(4.01887374432+12491.3701014155*t) result += 1.06e-09 * math.Cos(5.49092372854+62883.3551395136*t) result += 8e-10 * math.Cos(6.19781316983+6709.6740408674*t) result += 8.8e-10 * math.Cos(2.09872810657+238004.524157236*t) result += 8.3e-10 * math.Cos(4.90662164029+51.28033786241*t) result += 9.5e-10 * math.Cos(4.13387406591+18216.443810661*t) result += 7.8e-10 * math.Cos(6.0694939168+148434.534037691*t) result += 7.9e-10 * math.Cos(3.03048221644+838.9692877504*t) result += 7.4e-10 * math.Cos(5.49813051211+29026.4852295078*t) result += 7.3e-10 * math.Cos(3.05008665738+567.7186377304*t) result += 8.4e-10 * math.Cos(0.46604373274+45.1412196366*t) result += 9.3e-10 * math.Cos(2.52267536308+48739.859897083*t) result += 7.6e-10 * math.Cos(1.76418124905+41654.9631159678*t) result += 6.7e-10 * math.Cos(5.77851227793+6311.5250374592*t) result += 6.2e-10 * math.Cos(3.32967880172+15508.6151232744*t) result += 7.9e-10 * math.Cos(5.59773841328+71960.3865832237*t) result += 5.7e-10 * math.Cos(3.90629505268+5999.2165311262*t) result += 6.1e-10 * math.Cos(0.05695043232+7856.89627409019*t) result += 6.1e-10 * math.Cos(5.63297958433+7863.9425107882*t) result += 6.5e-10 * math.Cos(3.72178394016+12573.2652469836*t) result += 5.7e-10 * math.Cos(4.18217219541+26087.9031415742*t) result += 6.6e-10 * math.Cos(3.92262333487+69853.3520756813*t) result += 5.3e-10 * math.Cos(5.51119362045+77710.2483497715*t) result += 5.3e-10 * math.Cos(4.88573986961+77717.2945864695*t) result += 6.2e-10 * math.Cos(2.88876342225+9411.4646150872*t) result += 5.1e-10 * math.Cos(1.12657183874+82576.9812209953*t) result += 4.5e-10 * math.Cos(2.95671076719+24602.612434871*t) result += 4e-10 * math.Cos(5.55145719241+12565.1713789146*t) result += 3.9e-10 * math.Cos(1.20838190039+18842.1140029734*t) result += 4.5e-10 * math.Cos(3.18590558749+45585.1728121874*t) result += 4.9e-10 * math.Cos(2.44790934886+13613.804277336*t) return result } func GetEarthL1(t float64) float64 { var result float64 = 0.0 result += 6283.31966747491 result += 0.00206058863 * math.Cos(2.67823455584+6283.0758499914*t) result += 4.30343e-05 * math.Cos(2.63512650414+12566.1516999828*t) result += 4.25264e-06 * math.Cos(1.59046980729+3.523118349*t) result += 1.08977e-06 * math.Cos(2.96618001993+1577.3435424478*t) result += 9.3478e-07 * math.Cos(2.59212835365+18849.2275499742*t) result += 1.19261e-06 * math.Cos(5.79557487799+26.2983197998*t) result += 7.2122e-07 * math.Cos(1.13846158196+529.6909650946*t) result += 6.7768e-07 * math.Cos(1.87472304791+398.1490034082*t) result += 6.7327e-07 * math.Cos(4.40918235168+5507.5532386674*t) result += 5.9027e-07 * math.Cos(2.8879703846+5223.6939198022*t) result += 5.5976e-07 * math.Cos(2.17471680261+155.4203994342*t) result += 4.5407e-07 * math.Cos(0.39803079805+796.2980068164*t) result += 3.6369e-07 * math.Cos(0.46624739835+775.522611324*t) result += 2.8958e-07 * math.Cos(2.64707383882+7.1135470008*t) result += 1.9097e-07 * math.Cos(1.84628332577+5486.777843175*t) result += 2.0844e-07 * math.Cos(5.34138275149+0.9803210682*t) result += 1.8508e-07 * math.Cos(4.96855124577+213.299095438*t) result += 1.6233e-07 * math.Cos(0.03216483047+2544.3144198834*t) result += 1.7293e-07 * math.Cos(2.99116864949+6275.9623029906*t) result += 1.5832e-07 * math.Cos(1.43049285325+2146.1654164752*t) result += 1.4615e-07 * math.Cos(1.20532366323+10977.078804699*t) result += 1.1877e-07 * math.Cos(3.25804815607+5088.6288397668*t) result += 1.1514e-07 * math.Cos(2.07502418155+4694.0029547076*t) result += 9.721e-08 * math.Cos(4.23925472239+1349.8674096588*t) result += 9.969e-08 * math.Cos(1.30262991097+6286.5989683404*t) result += 9.452e-08 * math.Cos(2.69957062864+242.728603974*t) result += 1.2461e-07 * math.Cos(2.83432285512+1748.016413067*t) result += 1.1808e-07 * math.Cos(5.2737979048+1194.4470102246*t) result += 8.577e-08 * math.Cos(5.64475868067+951.7184062506*t) result += 1.0641e-07 * math.Cos(0.76614199202+553.5694028424*t) result += 7.576e-08 * math.Cos(5.30062664886+2352.8661537718*t) result += 5.834e-08 * math.Cos(1.76649917904+1059.3819301892*t) result += 6.385e-08 * math.Cos(2.65033984967+9437.762934887*t) result += 5.223e-08 * math.Cos(5.66135767624+71430.6956181291*t) result += 5.305e-08 * math.Cos(0.90857521574+3154.6870848956*t) result += 6.101e-08 * math.Cos(4.66632584188+4690.4798363586*t) result += 4.33e-08 * math.Cos(0.24102555403+6812.766815086*t) result += 5.041e-08 * math.Cos(1.42490103709+6438.4962494256*t) result += 4.259e-08 * math.Cos(0.77355900599+10447.3878396044*t) result += 5.198e-08 * math.Cos(1.85353197345+801.8209311238*t) result += 3.744e-08 * math.Cos(2.00119516488+8031.0922630584*t) result += 3.558e-08 * math.Cos(2.42901552681+14143.4952424306*t) result += 3.372e-08 * math.Cos(3.86210700128+1592.5960136328*t) result += 3.374e-08 * math.Cos(0.88776219727+12036.4607348882*t) result += 3.175e-08 * math.Cos(3.18785710594+4705.7323075436*t) result += 3.221e-08 * math.Cos(0.61599835472+8429.2412664666*t) result += 4.132e-08 * math.Cos(5.23992859705+7084.8967811152*t) result += 2.97e-08 * math.Cos(6.07026318493+4292.3308329504*t) result += 2.9e-08 * math.Cos(2.32464208411+20.3553193988*t) result += 3.504e-08 * math.Cos(4.79975694359+6279.5527316424*t) result += 2.95e-08 * math.Cos(1.43108874817+5746.271337896*t) result += 2.697e-08 * math.Cos(4.80368225199+7234.794256242*t) result += 2.531e-08 * math.Cos(6.22290682655+6836.6452528338*t) result += 2.745e-08 * math.Cos(0.93466065396+5760.4984318976*t) result += 3.25e-08 * math.Cos(3.39954640038+7632.9432596502*t) result += 2.277e-08 * math.Cos(5.00277837672+17789.845619785*t) result += 2.075e-08 * math.Cos(3.95534978634+10213.285546211*t) result += 2.061e-08 * math.Cos(2.22411683077+5856.4776591154*t) result += 2.252e-08 * math.Cos(5.67166499885+11499.6562227928*t) result += 2.148e-08 * math.Cos(5.20184578235+11513.8833167944*t) result += 1.886e-08 * math.Cos(0.53198320577+3340.6124266998*t) result += 1.875e-08 * math.Cos(4.73511970207+83996.8473181119*t) result += 2.06e-08 * math.Cos(2.54987293999+25132.3033999656*t) result += 1.794e-08 * math.Cos(1.47435409831+4164.311989613*t) result += 1.778e-08 * math.Cos(3.02473091781+5.5229243074*t) result += 2.029e-08 * math.Cos(0.90960209983+6256.7775301916*t) result += 2.075e-08 * math.Cos(2.26767270157+522.5774180938*t) result += 1.772e-08 * math.Cos(3.02622802353+5753.3848848968*t) result += 1.569e-08 * math.Cos(6.12410242782+5216.5803728014*t) result += 1.59e-08 * math.Cos(4.63713748247+3.2863574178*t) result += 1.542e-08 * math.Cos(4.20004448567+13367.9726311066*t) result += 1.427e-08 * math.Cos(1.19088061711+3894.1818295422*t) result += 1.375e-08 * math.Cos(3.09301252193+135.0650800354*t) result += 1.359e-08 * math.Cos(4.24532506641+426.598190876*t) result += 1.34e-08 * math.Cos(5.76511818622+6040.3472460174*t) result += 1.284e-08 * math.Cos(3.08524663344+5643.1785636774*t) result += 1.25e-08 * math.Cos(3.07748157144+11926.2544136688*t) result += 1.551e-08 * math.Cos(3.07665451458+6681.2248533996*t) result += 1.268e-08 * math.Cos(2.09196018331+6290.1893969922*t) result += 1.144e-08 * math.Cos(3.24444699514+12168.0026965746*t) result += 1.248e-08 * math.Cos(3.44504937285+536.8045120954*t) result += 1.118e-08 * math.Cos(2.31829670425+16730.4636895958*t) result += 1.105e-08 * math.Cos(5.31966001019+23.8784377478*t) result += 1.051e-08 * math.Cos(3.75015946014+7860.4193924392*t) result += 1.025e-08 * math.Cos(2.44688534235+1990.745017041*t) result += 9.62e-09 * math.Cos(0.81771017882+3.881335358*t) result += 9.1e-09 * math.Cos(0.41727865299+7079.3738568078*t) result += 8.83e-09 * math.Cos(5.16833917651+11790.6290886588*t) result += 9.57e-09 * math.Cos(4.07673573735+6127.6554505572*t) result += 1.11e-08 * math.Cos(3.90096793825+11506.7697697936*t) result += 8.02e-09 * math.Cos(3.88778875582+10973.55568635*t) result += 7.8e-09 * math.Cos(2.39934293755+1589.0728952838*t) result += 7.58e-09 * math.Cos(1.30034364248+103.0927742186*t) result += 7.49e-09 * math.Cos(4.962758033+6496.3749454294*t) result += 7.65e-09 * math.Cos(3.36312388424+36.0278666774*t) result += 9.15e-09 * math.Cos(5.41543742089+206.1855484372*t) result += 7.76e-09 * math.Cos(2.57589093871+11371.7046897582*t) result += 7.72e-09 * math.Cos(3.98369209464+955.5997416086*t) result += 7.49e-09 * math.Cos(5.17890001805+10969.9652576982*t) result += 8.06e-09 * math.Cos(0.34218864254+9917.6968745098*t) result += 7.28e-09 * math.Cos(5.20962563787+38.0276726358*t) result += 6.85e-09 * math.Cos(2.77592961854+20.7753954924*t) result += 6.36e-09 * math.Cos(4.28242193632+28.4491874678*t) result += 6.08e-09 * math.Cos(5.63278508906+10984.1923516998*t) result += 7.04e-09 * math.Cos(5.60738823665+3738.761430108*t) result += 6.85e-09 * math.Cos(0.38876148682+15.252471185*t) result += 6.01e-09 * math.Cos(0.73489602442+419.4846438752*t) result += 7.16e-09 * math.Cos(2.65279791438+6309.3741697912*t) result += 5.84e-09 * math.Cos(5.54502568227+17298.1823273262*t) result += 6.5e-09 * math.Cos(1.13379656406+7058.5984613154*t) result += 6.88e-09 * math.Cos(2.59683891779+3496.032826134*t) result += 4.85e-09 * math.Cos(0.44467180946+12352.8526045448*t) result += 5.28e-09 * math.Cos(2.74936967681+3930.2096962196*t) result += 5.97e-09 * math.Cos(5.27668281777+10575.4066829418*t) result += 5.83e-09 * math.Cos(3.1892906781+4732.0306273434*t) result += 5.26e-09 * math.Cos(5.01697321546+5884.9268465832*t) result += 5.4e-09 * math.Cos(1.29175137075+640.8776073822*t) result += 4.73e-09 * math.Cos(5.4995330697+5230.807466803*t) result += 4.06e-09 * math.Cos(5.21248452189+220.4126424388*t) result += 3.95e-09 * math.Cos(1.87474483222+16200.7727245012*t) result += 3.7e-09 * math.Cos(3.84921354713+18073.7049386502*t) result += 3.67e-09 * math.Cos(0.88533542778+6283.14316029419*t) result += 3.79e-09 * math.Cos(0.37983009325+10177.2576795336*t) result += 3.56e-09 * math.Cos(3.84145204913+11712.9553182308*t) result += 3.74e-09 * math.Cos(5.01577520608+7.046236698*t) result += 3.81e-09 * math.Cos(4.30250406634+6062.6632075526*t) result += 4.71e-09 * math.Cos(0.86381834647+6069.7767545534*t) result += 3.67e-09 * math.Cos(1.32943839763+6283.0085396886*t) result += 4.6e-09 * math.Cos(5.19667219575+6284.0561710596*t) result += 3.33e-09 * math.Cos(5.54256205741+4686.8894077068*t) result += 3.41e-09 * math.Cos(4.36522989934+7238.6755916*t) result += 3.36e-09 * math.Cos(4.00205876835+3097.88382272579*t) result += 3.59e-09 * math.Cos(6.22679790284+245.8316462294*t) result += 3.07e-09 * math.Cos(2.35299010924+170.6728706192*t) result += 3.43e-09 * math.Cos(3.77164927143+6076.8903015542*t) result += 2.96e-09 * math.Cos(5.44152227481+17260.1546546904*t) result += 3.28e-09 * math.Cos(0.13837875384+11015.1064773348*t) result += 2.68e-09 * math.Cos(1.1390455063+12569.6748183318*t) result += 2.63e-09 * math.Cos(0.00538633678+4136.9104335162*t) result += 2.82e-09 * math.Cos(5.0439983748+7477.522860216*t) result += 2.88e-09 * math.Cos(3.13401177517+12559.038152982*t) result += 2.59e-09 * math.Cos(0.93882269387+5642.1982426092*t) result += 2.92e-09 * math.Cos(1.98420020514+12132.439962106*t) result += 2.47e-09 * math.Cos(3.84244798532+5429.8794682394*t) result += 2.45e-09 * math.Cos(5.70467521726+65147.6197681377*t) result += 2.41e-09 * math.Cos(0.99480969552+3634.6210245184*t) result += 2.46e-09 * math.Cos(3.06168069935+110.2063212194*t) result += 2.39e-09 * math.Cos(6.11855909114+11856.2186514245*t) result += 2.63e-09 * math.Cos(0.66348415419+21228.3920235458*t) result += 2.62e-09 * math.Cos(1.51070507866+12146.6670561076*t) result += 2.3e-09 * math.Cos(1.75927314884+9779.1086761254*t) result += 2.23e-09 * math.Cos(2.00967043606+6172.869528772*t) result += 2.46e-09 * math.Cos(1.10411690865+6282.0955289232*t) result += 2.21e-09 * math.Cos(3.03945240854+8635.9420037632*t) result += 2.14e-09 * math.Cos(4.03840869663+14314.1681130498*t) result += 2.36e-09 * math.Cos(5.4691507058+13916.0191096416*t) result += 2.24e-09 * math.Cos(4.68408089456+24072.9214697764*t) result += 2.12e-09 * math.Cos(2.13695625494+5849.3641121146*t) result += 2.07e-09 * math.Cos(3.07724246401+11.729352836*t) result += 2.07e-09 * math.Cos(6.10306282747+23543.2305046818*t) result += 2.66e-09 * math.Cos(1.00709566823+2388.8940204492*t) result += 2.17e-09 * math.Cos(6.27837036335+17267.2682016912*t) result += 2.04e-09 * math.Cos(2.34615348695+266.6070417218*t) result += 1.95e-09 * math.Cos(5.55015549753+6133.5126528568*t) result += 1.88e-09 * math.Cos(2.52667166175+6525.8044539654*t) result += 1.85e-09 * math.Cos(0.90960768344+18319.5365848796*t) result += 1.77e-09 * math.Cos(1.73429218289+154717.609887683*t) result += 1.87e-09 * math.Cos(4.76483647432+4535.0594369244*t) result += 1.86e-09 * math.Cos(4.63080493407+10440.2742926036*t) result += 2.15e-09 * math.Cos(2.8125545456+7342.4577801806*t) result += 1.72e-09 * math.Cos(1.45551888559+9225.539273283*t) result += 1.62e-09 * math.Cos(3.30661909388+639.897286314*t) result += 1.68e-09 * math.Cos(2.17671416605+27.4015560968*t) result += 1.6e-09 * math.Cos(1.68164180475+15110.4661198662*t) result += 1.58e-09 * math.Cos(0.13519771874+13095.8426650774*t) result += 1.83e-09 * math.Cos(0.56281322071+13517.8701062334*t) result += 1.79e-09 * math.Cos(3.58450811616+87.30820453981*t) result += 1.52e-09 * math.Cos(2.84070476818+5650.2921106782*t) result += 1.82e-09 * math.Cos(0.44065530624+17253.0411076896*t) result += 1.6e-09 * math.Cos(5.95767264171+4701.1165017084*t) result += 1.42e-09 * math.Cos(1.4629013752+11087.2851259184*t) result += 1.42e-09 * math.Cos(2.04464036087+20426.571092422*t) result += 1.31e-09 * math.Cos(5.40912137746+2699.7348193176*t) result += 1.44e-09 * math.Cos(2.07312090485+25158.6017197654*t) result += 1.47e-09 * math.Cos(6.15106982168+9623.6882766912*t) result += 1.41e-09 * math.Cos(5.55739979498+10454.5013866052*t) result += 1.35e-09 * math.Cos(0.06098110407+16723.350142595*t) result += 1.24e-09 * math.Cos(5.81218025669+17256.6315363414*t) result += 1.24e-09 * math.Cos(2.36293551623+4933.2084403326*t) result += 1.26e-09 * math.Cos(3.47435905118+22483.8485744926*t) result += 1.59e-09 * math.Cos(5.63954754618+5729.506447149*t) result += 1.23e-09 * math.Cos(3.92815963256+17996.0311682222*t) result += 1.48e-09 * math.Cos(3.02509280598+1551.045222648*t) result += 1.2e-09 * math.Cos(5.91904349732+6206.8097787158*t) result += 1.34e-09 * math.Cos(3.11122937825+21954.157609398*t) result += 1.19e-09 * math.Cos(5.5214112345+709.9330485583*t) result += 1.22e-09 * math.Cos(3.00813429479+19800.9459562248*t) result += 1.27e-09 * math.Cos(1.37618620001+14945.3161735544*t) result += 1.41e-09 * math.Cos(2.56889468729+1052.2683831884*t) result += 1.23e-09 * math.Cos(2.83671175442+11919.140866668*t) result += 1.18e-09 * math.Cos(0.81934438215+5331.3574437408*t) result += 1.51e-09 * math.Cos(2.68731829165+11769.8536931664*t) result += 1.19e-09 * math.Cos(5.08835797638+5481.2549188676*t) result += 1.53e-09 * math.Cos(2.46021790779+11933.3679606696*t) result += 1.08e-09 * math.Cos(1.04936452145+11403.676995575*t) result += 1.28e-09 * math.Cos(0.99794735107+8827.3902698748*t) result += 1.44e-09 * math.Cos(2.54869747042+227.476132789*t) result += 1.5e-09 * math.Cos(4.50631437136+2379.1644735716*t) result += 1.07e-09 * math.Cos(1.79272017026+13119.7211028252*t) result += 1.07e-09 * math.Cos(4.43556814486+18422.6293590982*t) result += 1.09e-09 * math.Cos(0.29269062317+16737.5772365966*t) result += 1.41e-09 * math.Cos(3.18979826258+6262.300454499*t) result += 1.22e-09 * math.Cos(4.23040027813+29.429508536*t) result += 1.11e-09 * math.Cos(5.16954029551+17782.7320727842*t) result += 1e-09 * math.Cos(3.52213872761+18052.9295431578*t) result += 1.08e-09 * math.Cos(1.08514212991+16858.4825329332*t) result += 1.06e-09 * math.Cos(1.9608524841+74.7815985673*t) result += 1.1e-09 * math.Cos(2.30582372873+16460.333529525*t) result += 9.7e-10 * math.Cos(3.5091894021+5333.9002410216*t) result += 9.9e-10 * math.Cos(3.56417337974+735.8765135318*t) result += 9.4e-10 * math.Cos(5.01857894228+3128.3887650958*t) result += 9.7e-10 * math.Cos(1.65579893894+533.2140834436*t) result += 9.2e-10 * math.Cos(0.89217162285+29296.6153895786*t) result += 1.23e-09 * math.Cos(3.16062050433+9380.9596727172*t) result += 1.02e-09 * math.Cos(1.20493500565+23020.653086588*t) result += 8.8e-10 * math.Cos(2.21296088224+12721.572099417*t) result += 8.9e-10 * math.Cos(1.5426472031+20199.094959633*t) result += 1.13e-09 * math.Cos(4.8332070787+16496.3613962024*t) result += 1.21e-09 * math.Cos(6.19860353182+9388.0059094152*t) result += 8.9e-10 * math.Cos(4.08082274765+22805.7355659936*t) result += 9.8e-10 * math.Cos(1.0918183283+12043.574281889*t) result += 8.6e-10 * math.Cos(1.13655027605+143571.324284816*t) result += 8.8e-10 * math.Cos(5.96980472191+107.6635239386*t) result += 8.2e-10 * math.Cos(5.01340404594+22003.9146348698*t) result += 9.4e-10 * math.Cos(1.69615700473+23006.4259925864*t) result += 8.1e-10 * math.Cos(3.00657814365+2118.7638603784*t) result += 9.8e-10 * math.Cos(1.39215287161+8662.240323563*t) result += 7.7e-10 * math.Cos(3.3355519084+15720.8387848784*t) result += 8.2e-10 * math.Cos(5.86880116464+2787.0430238574*t) result += 7.6e-10 * math.Cos(5.67183650604+14.2270940016*t) result += 8.1e-10 * math.Cos(6.16619455699+1039.0266107904*t) result += 7.6e-10 * math.Cos(3.21449884756+111.1866422876*t) result += 7.8e-10 * math.Cos(1.37531518377+21947.1113727*t) result += 7.4e-10 * math.Cos(3.58814195051+11609.8625440122*t) result += 7.7e-10 * math.Cos(4.84846488388+22743.4093795164*t) result += 9e-10 * math.Cos(1.48869013606+15671.0817594066*t) result += 8.2e-10 * math.Cos(3.48618399109+29088.811415985*t) result += 6.9e-10 * math.Cos(3.55746476593+4590.910180489*t) result += 6.9e-10 * math.Cos(1.93625656075+135.62532501*t) result += 7e-10 * math.Cos(2.66548322237+18875.525869774*t) result += 6.9e-10 * math.Cos(5.41478093731+26735.9452622132*t) result += 7.9e-10 * math.Cos(5.15154513662+12323.4230960088*t) result += 9.4e-10 * math.Cos(3.62899392448+77713.7714681205*t) result += 7.8e-10 * math.Cos(4.17011182047+1066.49547719*t) result += 7.1e-10 * math.Cos(3.89435637865+22779.4372461938*t) result += 6.3e-10 * math.Cos(4.53968787714+8982.810669309*t) result += 6.9e-10 * math.Cos(0.96028230548+14919.0178537546*t) result += 7.6e-10 * math.Cos(3.29092216589+2942.4634232916*t) result += 6.3e-10 * math.Cos(4.09167842893+16062.1845261168*t) result += 6.5e-10 * math.Cos(3.34580407184+51.28033786241*t) result += 6.5e-10 * math.Cos(5.75757544877+52670.0695933026*t) result += 6.8e-10 * math.Cos(5.75884067555+21424.4666443034*t) result += 5.7e-10 * math.Cos(5.4512239985+12592.4500197826*t) result += 5.7e-10 * math.Cos(5.25043362558+20995.3929664494*t) result += 7.3e-10 * math.Cos(0.53299090807+2301.58581590939*t) result += 7e-10 * math.Cos(4.31243357502+19402.7969528166*t) result += 6.7e-10 * math.Cos(2.53852336668+377.3736079158*t) result += 5.6e-10 * math.Cos(3.20816844695+24889.5747959916*t) result += 5.3e-10 * math.Cos(3.17816599142+18451.078546566*t) result += 5.3e-10 * math.Cos(3.61529270216+77.673770428*t) result += 5.3e-10 * math.Cos(0.45467549335+30666.1549584328*t) result += 6.1e-10 * math.Cos(0.14807288453+23013.5395395872*t) result += 5.1e-10 * math.Cos(3.32803972907+56.8983749356*t) result += 5.2e-10 * math.Cos(3.41177624177+23141.5583829246*t) result += 5.8e-10 * math.Cos(3.13638677202+309.2783226558*t) result += 7e-10 * math.Cos(2.50592323465+31415.379249957*t) result += 5.2e-10 * math.Cos(5.10673376738+17796.9591667858*t) result += 6.7e-10 * math.Cos(6.27917920454+22345.2603761082*t) result += 5e-10 * math.Cos(0.42577644151+25685.872802808*t) result += 4.8e-10 * math.Cos(0.70204553333+1162.4747044078*t) result += 6.6e-10 * math.Cos(3.64350022359+15265.8865193004*t) result += 5e-10 * math.Cos(5.7438291744+19.66976089979*t) result += 5e-10 * math.Cos(4.69825387775+28237.2334593894*t) result += 4.7e-10 * math.Cos(5.74015846442+12139.5535091068*t) result += 5.4e-10 * math.Cos(1.97301333704+23581.2581773176*t) result += 4.9e-10 * math.Cos(4.98223579027+10021.8372800994*t) result += 4.6e-10 * math.Cos(5.41431705539+33019.0211122046*t) result += 5.1e-10 * math.Cos(1.23882053879+12539.853380183*t) result += 4.6e-10 * math.Cos(2.41369976086+98068.5367163054*t) result += 4.4e-10 * math.Cos(0.80750593746+167283.761587666*t) result += 4.5e-10 * math.Cos(4.39613584445+433.7117378768*t) result += 4.4e-10 * math.Cos(2.57358208785+12964.300703391*t) result += 4.6e-10 * math.Cos(0.26142733448+11.0457002639*t) result += 4.5e-10 * math.Cos(2.46230645202+51868.2486621788*t) result += 4.8e-10 * math.Cos(0.89551707131+56600.2792895222*t) result += 5.7e-10 * math.Cos(1.8641670701+25287.7237993998*t) result += 4.2e-10 * math.Cos(5.26377513431+26084.0218062162*t) result += 4.9e-10 * math.Cos(3.17757670611+6303.8512454838*t) result += 5.2e-10 * math.Cos(3.65266055509+7872.1487452752*t) result += 4e-10 * math.Cos(1.81891629936+34596.3646546524*t) result += 4.3e-10 * math.Cos(1.94164978061+1903.4368125012*t) result += 4.1e-10 * math.Cos(0.74461854136+23937.856389741*t) result += 4.8e-10 * math.Cos(6.26034008181+28286.9904848612*t) result += 4.5e-10 * math.Cos(5.4557501753+60530.4889857418*t) result += 4e-10 * math.Cos(2.92105728682+21548.9623692918*t) result += 4e-10 * math.Cos(0.04502010161+38526.574350872*t) result += 5.3e-10 * math.Cos(3.64791042082+11925.2740926006*t) result += 4.1e-10 * math.Cos(5.04048954693+27832.0382192832*t) result += 4.2e-10 * math.Cos(5.19292937193+19004.6479494084*t) result += 4e-10 * math.Cos(2.57120233428+24356.7807886416*t) result += 3.8e-10 * math.Cos(3.49190341464+226858.23855437*t) result += 3.9e-10 * math.Cos(4.61184303844+95.9792272178*t) result += 4.3e-10 * math.Cos(2.20648228147+13521.7514415914*t) result += 4e-10 * math.Cos(5.83461945819+16193.6591775004*t) result += 4.5e-10 * math.Cos(3.73714372195+7875.6718636242*t) result += 4.3e-10 * math.Cos(1.14078465002+49.7570254718*t) result += 3.7e-10 * math.Cos(1.29390383811+310.8407988684*t) result += 3.8e-10 * math.Cos(0.9597092595+664.75604513*t) result += 3.7e-10 * math.Cos(4.27532649462+6709.6740408674*t) result += 3.8e-10 * math.Cos(2.20108541046+28628.3362260996*t) result += 3.9e-10 * math.Cos(0.85957361635+16522.6597160022*t) result += 4e-10 * math.Cos(4.35214003837+48739.859897083*t) result += 3.6e-10 * math.Cos(1.68167662194+10344.2950653858*t) result += 4e-10 * math.Cos(5.13217319067+15664.0355227086*t) result += 3.6e-10 * math.Cos(3.72187132496+30774.5016425748*t) result += 3.6e-10 * math.Cos(3.32158458257+16207.886271502*t) result += 4.5e-10 * math.Cos(3.94202418608+10988.808157535*t) result += 3.9e-10 * math.Cos(1.51948786199+12029.3471878874*t) result += 2.6e-10 * math.Cos(3.8768588318+6262.7205305926*t) result += 2.4e-10 * math.Cos(4.91804163466+19651.048481098*t) result += 2.3e-10 * math.Cos(0.29300197709+13362.4497067992*t) result += 2.1e-10 * math.Cos(3.18605672363+6277.552925684*t) result += 2.1e-10 * math.Cos(6.07546891132+18139.2945014159*t) result += 2.2e-10 * math.Cos(2.31199937177+6303.4311693902*t) result += 2.1e-10 * math.Cos(3.58418394393+18209.3302636602*t) result += 2.6e-10 * math.Cos(2.068012969+12573.2652469836*t) result += 2.1e-10 * math.Cos(1.56857722317+13341.6743113068*t) result += 2.4e-10 * math.Cos(5.72605158675+29864.334027309*t) result += 2.4e-10 * math.Cos(1.40237993205+14712.317116458*t) result += 2.5e-10 * math.Cos(5.71466092822+25934.1243310894*t) return result } func GetEarthL2(t float64) float64 { var result float64 = 0.0 result += 0.0005291887 result += 8.719837e-05 * math.Cos(1.07209665242+6283.0758499914*t) result += 3.09125e-06 * math.Cos(0.86728818832+12566.1516999828*t) result += 2.7339e-07 * math.Cos(0.05297871691+3.523118349*t) result += 1.6334e-07 * math.Cos(5.18826691036+26.2983197998*t) result += 1.5752e-07 * math.Cos(3.6845788943+155.4203994342*t) result += 9.541e-08 * math.Cos(0.75742297675+18849.2275499742*t) result += 8.937e-08 * math.Cos(2.05705419118+77713.7714681205*t) result += 6.952e-08 * math.Cos(0.8267330541+775.522611324*t) result += 5.064e-08 * math.Cos(4.66284525271+1577.3435424478*t) result += 4.061e-08 * math.Cos(1.03057162962+7.1135470008*t) result += 3.463e-08 * math.Cos(5.14074632811+796.2980068164*t) result += 3.169e-08 * math.Cos(6.05291851171+5507.5532386674*t) result += 3.02e-08 * math.Cos(1.19246506441+242.728603974*t) result += 2.886e-08 * math.Cos(6.11652627155+529.6909650946*t) result += 3.81e-08 * math.Cos(3.4405080349+5573.1428014331*t) result += 2.714e-08 * math.Cos(0.30637881025+398.1490034082*t) result += 2.371e-08 * math.Cos(4.38118838167+5223.6939198022*t) result += 2.538e-08 * math.Cos(2.27992810679+553.5694028424*t) result += 2.079e-08 * math.Cos(3.75435330484+0.9803210682*t) result += 1.675e-08 * math.Cos(0.90216407959+951.7184062506*t) result += 1.534e-08 * math.Cos(5.75900462759+1349.8674096588*t) result += 1.224e-08 * math.Cos(2.97328088405+2146.1654164752*t) result += 1.449e-08 * math.Cos(4.3641591397+1748.016413067*t) result += 1.341e-08 * math.Cos(3.72061130861+1194.4470102246*t) result += 1.254e-08 * math.Cos(2.94846826628+6438.4962494256*t) result += 9.99e-09 * math.Cos(5.98640014468+6286.5989683404*t) result += 9.17e-09 * math.Cos(4.79788687522+5088.6288397668*t) result += 8.28e-09 * math.Cos(3.31321076572+213.299095438*t) result += 1.103e-08 * math.Cos(1.27104454479+161000.685737674*t) result += 7.62e-09 * math.Cos(3.41582762988+5486.777843175*t) result += 1.044e-08 * math.Cos(0.60409577691+3154.6870848956*t) result += 8.87e-09 * math.Cos(5.23465144638+7084.8967811152*t) result += 6.45e-09 * math.Cos(1.60096192515+2544.3144198834*t) result += 6.81e-09 * math.Cos(3.43155669169+4694.0029547076*t) result += 6.05e-09 * math.Cos(2.47806340546+10977.078804699*t) result += 7.06e-09 * math.Cos(6.19393222575+4690.4798363586*t) result += 6.43e-09 * math.Cos(1.98042503148+801.8209311238*t) result += 5.02e-09 * math.Cos(1.44394375363+6836.6452528338*t) result += 4.9e-09 * math.Cos(2.34129524194+1592.5960136328*t) result += 4.58e-09 * math.Cos(1.30876448575+4292.3308329504*t) result += 4.31e-09 * math.Cos(0.03526421494+7234.794256242*t) result += 3.79e-09 * math.Cos(3.17030522615+6309.3741697912*t) result += 3.48e-09 * math.Cos(0.99049550009+6040.3472460174*t) result += 3.86e-09 * math.Cos(1.57019797263+71430.6956181291*t) result += 3.47e-09 * math.Cos(0.67013291338+1059.3819301892*t) result += 4.58e-09 * math.Cos(3.81499443681+149854.400134808*t) result += 3.02e-09 * math.Cos(1.91760044838+10447.3878396044*t) result += 3.07e-09 * math.Cos(3.55343347416+8031.0922630584*t) result += 3.95e-09 * math.Cos(4.93701776616+7632.9432596502*t) result += 3.14e-09 * math.Cos(3.18093696547+2352.8661537718*t) result += 2.82e-09 * math.Cos(4.41936437052+9437.762934887*t) result += 2.76e-09 * math.Cos(2.71314254553+3894.1818295422*t) result += 2.98e-09 * math.Cos(2.5203747421+6127.6554505572*t) result += 2.3e-09 * math.Cos(1.37790215549+4705.7323075436*t) result += 2.52e-09 * math.Cos(0.55330133471+6279.5527316424*t) result += 2.55e-09 * math.Cos(5.26570187369+6812.766815086*t) result += 2.75e-09 * math.Cos(0.67264264272+25132.3033999656*t) result += 1.78e-09 * math.Cos(0.92820785174+1990.745017041*t) result += 2.21e-09 * math.Cos(0.63897368842+6256.7775301916*t) result += 1.55e-09 * math.Cos(0.77319790838+14143.4952424306*t) result += 1.5e-09 * math.Cos(2.40470465561+426.598190876*t) result += 1.96e-09 * math.Cos(6.06877865012+640.8776073822*t) result += 1.37e-09 * math.Cos(2.21679460145+8429.2412664666*t) result += 1.27e-09 * math.Cos(3.26094223174+17789.845619785*t) result += 1.28e-09 * math.Cos(5.47237279946+12036.4607348882*t) result += 1.22e-09 * math.Cos(2.16291082757+10213.285546211*t) result += 1.18e-09 * math.Cos(0.45789822268+7058.5984613154*t) result += 1.41e-09 * math.Cos(2.34932647403+11506.7697697936*t) result += 1e-09 * math.Cos(0.85621569847+6290.1893969922*t) result += 9.2e-10 * math.Cos(5.10587476002+7079.3738568078*t) result += 1.26e-09 * math.Cos(2.65428307012+88860.0570709867*t) result += 1.06e-09 * math.Cos(5.85646710022+7860.4193924392*t) result += 8.4e-10 * math.Cos(3.57457554262+16730.4636895958*t) result += 8.9e-10 * math.Cos(4.21433259618+83996.8473181119*t) result += 9.7e-10 * math.Cos(5.57938280855+13367.9726311066*t) result += 1.02e-09 * math.Cos(2.05853060226+87.30820453981*t) result += 8e-10 * math.Cos(4.73792651816+11926.2544136688*t) result += 8e-10 * math.Cos(5.41418965044+10973.55568635*t) result += 1.06e-09 * math.Cos(4.10978997399+3496.032826134*t) result += 1.02e-09 * math.Cos(3.62650006043+244287.600007228*t) result += 7.5e-10 * math.Cos(4.89483161769+5643.1785636774*t) result += 8.7e-10 * math.Cos(0.42863750683+11015.1064773348*t) result += 6.9e-10 * math.Cos(1.8890876072+10177.2576795336*t) result += 8.9e-10 * math.Cos(1.35567273119+6681.2248533996*t) result += 6.6e-10 * math.Cos(0.99455837265+6525.8044539654*t) result += 6.7e-10 * math.Cos(5.5124099707+3097.88382272579*t) result += 7.6e-10 * math.Cos(2.72016814799+4164.311989613*t) result += 6.3e-10 * math.Cos(1.4434990254+9917.6968745098*t) result += 7.8e-10 * math.Cos(3.51469733747+11856.2186514245*t) result += 8.5e-10 * math.Cos(0.50956043858+10575.4066829418*t) result += 6.7e-10 * math.Cos(3.62043033405+16496.3613962024*t) result += 5.5e-10 * math.Cos(5.24637517308+3340.6124266998*t) result += 4.8e-10 * math.Cos(5.43966777314+20426.571092422*t) result += 6.4e-10 * math.Cos(5.79535817813+2388.8940204492*t) result += 4.6e-10 * math.Cos(5.43499966519+6275.9623029906*t) result += 5e-10 * math.Cos(3.86263598617+5729.506447149*t) result += 4.4e-10 * math.Cos(1.52269529228+12168.0026965746*t) result += 5.7e-10 * math.Cos(4.96352373486+14945.3161735544*t) result += 4.5e-10 * math.Cos(1.0086123016+8635.9420037632*t) result += 4.3e-10 * math.Cos(3.30685683359+9779.1086761254*t) result += 4.2e-10 * math.Cos(0.6348125893+2699.7348193176*t) result += 4.1e-10 * math.Cos(5.67996766641+11712.9553182308*t) result += 5.6e-10 * math.Cos(4.34024451468+90955.5516944961*t) result += 4.1e-10 * math.Cos(5.81722212845+709.9330485583*t) result += 5.3e-10 * math.Cos(6.17052087143+233141.314404362*t) result += 3.7e-10 * math.Cos(3.12495025087+16200.7727245012*t) result += 3.5e-10 * math.Cos(5.76973458495+12569.6748183318*t) result += 3.7e-10 * math.Cos(0.31656444326+24356.7807886416*t) result += 3.5e-10 * math.Cos(0.96229051027+17298.1823273262*t) result += 3.3e-10 * math.Cos(5.23130355867+5331.3574437408*t) result += 3.5e-10 * math.Cos(0.62517020593+25158.6017197654*t) result += 3.5e-10 * math.Cos(0.80004512129+13916.0191096416*t) result += 3.7e-10 * math.Cos(2.89336088688+12721.572099417*t) result += 3e-10 * math.Cos(4.50198402401+23543.2305046818*t) result += 3e-10 * math.Cos(5.31355708693+18319.5365848796*t) result += 2.9e-10 * math.Cos(3.47275229977+13119.7211028252*t) result += 2.9e-10 * math.Cos(3.11002782516+4136.9104335162*t) result += 3.2e-10 * math.Cos(5.52273255667+5753.3848848968*t) result += 3.5e-10 * math.Cos(3.7969999668+143571.324284816*t) result += 2.6e-10 * math.Cos(1.50634201907+154717.609887683*t) result += 3e-10 * math.Cos(3.53519084118+6284.0561710596*t) result += 2.3e-10 * math.Cos(4.41808025967+5884.9268465832*t) result += 2.5e-10 * math.Cos(1.38477355808+65147.6197681377*t) result += 2.3e-10 * math.Cos(3.49782549797+7477.522860216*t) result += 1.9e-10 * math.Cos(3.14329413716+6496.3749454294*t) result += 1.9e-10 * math.Cos(2.20135125199+18073.7049386502*t) result += 1.9e-10 * math.Cos(4.95020255309+3930.2096962196*t) result += 1.9e-10 * math.Cos(0.57998702747+31415.379249957*t) result += 2.1e-10 * math.Cos(1.75474323399+12139.5535091068*t) result += 1.9e-10 * math.Cos(3.92233070499+19651.048481098*t) result += 1.4e-10 * math.Cos(0.98131213224+12559.038152982*t) result += 1.9e-10 * math.Cos(4.93309333729+2942.4634232916*t) result += 1.6e-10 * math.Cos(5.55997534558+8827.3902698748*t) result += 1.3e-10 * math.Cos(1.68808165516+4535.0594369244*t) result += 1.3e-10 * math.Cos(0.33982116161+4933.2084403326*t) result += 1.2e-10 * math.Cos(1.85426309994+5856.4776591154*t) result += 1e-10 * math.Cos(4.82763996845+13095.8426650774*t) result += 1.1e-10 * math.Cos(5.38005490571+11790.6290886588*t) result += 1e-10 * math.Cos(1.40815507226+10988.808157535*t) result += 1.1e-10 * math.Cos(3.05005267431+17260.1546546904*t) result += 1e-10 * math.Cos(4.93364992366+12352.8526045448*t) return result } func GetEarthL3(t float64) float64 { var result float64 = 0.0 result += 2.89226e-06 * math.Cos(5.84384198723+6283.0758499914*t) result += 3.4955e-07 result += 1.6819e-07 * math.Cos(5.48766912348+12566.1516999828*t) result += 2.962e-08 * math.Cos(5.19577265202+155.4203994342*t) result += 1.288e-08 * math.Cos(4.72200252235+3.523118349*t) result += 6.35e-09 * math.Cos(5.96925937141+242.728603974*t) result += 7.14e-09 * math.Cos(5.30045809128+18849.2275499742*t) result += 4.02e-09 * math.Cos(3.78682982419+553.5694028424*t) result += 7.2e-10 * math.Cos(4.2976812618+6286.5989683404*t) result += 6.7e-10 * math.Cos(0.90721687647+6127.6554505572*t) result += 3.6e-10 * math.Cos(5.24029648014+6438.4962494256*t) result += 2.4e-10 * math.Cos(5.16003960716+25132.3033999656*t) result += 2.3e-10 * math.Cos(3.01921570335+6309.3741697912*t) result += 1.7e-10 * math.Cos(5.82863573502+6525.8044539654*t) result += 1.7e-10 * math.Cos(3.6777286393+71430.6956181291*t) result += 9e-11 * math.Cos(4.58467294499+1577.3435424478*t) result += 8e-11 * math.Cos(1.40626662824+11856.2186514245*t) result += 8e-11 * math.Cos(5.07561257196+6256.7775301916*t) result += 7e-11 * math.Cos(2.82473374405+83996.8473181119*t) result += 5e-11 * math.Cos(2.71488713339+10977.078804699*t) result += 5e-11 * math.Cos(3.76879847273+12036.4607348882*t) result += 5e-11 * math.Cos(4.28412873331+6275.9623029906*t) return result } func GetEarthL4(t float64) float64 { var result float64 = 0.0 result -= -1.14084e-06 result += 7.717e-08 * math.Cos(4.13446589358+6283.0758499914*t) result += 7.65e-09 * math.Cos(3.83803776214+12566.1516999828*t) result += 4.2e-09 * math.Cos(0.41925861858+155.4203994342*t) result += 4e-10 * math.Cos(3.5984758584+18849.2275499742*t) result += 4.1e-10 * math.Cos(3.14398414077+3.523118349*t) result += 3.5e-10 * math.Cos(5.00298940826+5573.1428014331*t) result += 1.3e-10 * math.Cos(0.48794833701+77713.7714681205*t) result += 1e-10 * math.Cos(5.6480176635+6127.6554505572*t) result += 8e-11 * math.Cos(2.84160570605+161000.685737674*t) result += 2e-11 * math.Cos(0.54912904658+6438.4962494256*t) return result } func GetEarthL5(t float64) float64 { var result float64 = 0.0 result -= -8.78e-09 result += 1.72e-09 * math.Cos(2.7657906951+6283.0758499914*t) result += 5e-10 * math.Cos(2.01353298182+155.4203994342*t) result += 2.8e-10 * math.Cos(2.21496423926+12566.1516999828*t) result += 5e-11 * math.Cos(1.75600058765+18849.2275499742*t) return result } func GetEarthB0(t float64) float64 { var result float64 = 0.0 result += 2.7962e-06 * math.Cos(3.19870156017+84334.6615813083*t) result += 1.01643e-06 * math.Cos(5.42248619256+5507.5532386674*t) result += 8.0445e-07 * math.Cos(3.88013204458+5223.6939198022*t) result += 4.3806e-07 * math.Cos(3.70444689758+2352.8661537718*t) result += 3.1933e-07 * math.Cos(4.00026369781+1577.3435424478*t) result += 2.2724e-07 * math.Cos(3.9847383156+1047.7473117547*t) result += 1.6392e-07 * math.Cos(3.56456119782+5856.4776591154*t) result += 1.8141e-07 * math.Cos(4.98367470263+6283.0758499914*t) result += 1.4443e-07 * math.Cos(3.70275614914+9437.762934887*t) result += 1.4304e-07 * math.Cos(3.41117857525+10213.285546211*t) result += 1.1246e-07 * math.Cos(4.8282069053+14143.4952424306*t) result += 1.09e-07 * math.Cos(2.08574562327+6812.766815086*t) result += 9.714e-08 * math.Cos(3.47303947752+4694.0029547076*t) result += 1.0367e-07 * math.Cos(4.05663927946+71092.8813549327*t) result += 8.775e-08 * math.Cos(4.44016515669+5753.3848848968*t) result += 8.366e-08 * math.Cos(4.9925151218+7084.8967811152*t) result += 6.921e-08 * math.Cos(4.32559054073+6275.9623029906*t) result += 9.145e-08 * math.Cos(1.14182646613+6620.8901131878*t) result += 7.194e-08 * math.Cos(3.60193205752+529.6909650946*t) result += 7.698e-08 * math.Cos(5.55425745881+167621.575850862*t) result += 5.285e-08 * math.Cos(2.48446991566+4705.7323075436*t) result += 5.208e-08 * math.Cos(6.24992674537+18073.7049386502*t) result += 4.529e-08 * math.Cos(2.33827747356+6309.3741697912*t) result += 5.579e-08 * math.Cos(4.41023653738+7860.4193924392*t) result += 4.743e-08 * math.Cos(0.70995680136+5884.9268465832*t) result += 4.301e-08 * math.Cos(1.10255777773+6681.2248533996*t) result += 3.849e-08 * math.Cos(1.82229412531+5486.777843175*t) result += 4.093e-08 * math.Cos(5.11700141207+13367.9726311066*t) result += 3.681e-08 * math.Cos(0.43793170356+3154.6870848956*t) result += 3.42e-08 * math.Cos(5.42034800952+6069.7767545534*t) result += 3.617e-08 * math.Cos(6.04641937526+3930.2096962196*t) result += 3.67e-08 * math.Cos(4.58210192227+12194.0329146209*t) result += 2.918e-08 * math.Cos(1.95463881126+10977.078804699*t) result += 2.797e-08 * math.Cos(5.61259275048+11790.6290886588*t) result += 2.502e-08 * math.Cos(0.60499729367+6496.3749454294*t) result += 2.319e-08 * math.Cos(5.01648216014+1059.3819301892*t) result += 2.684e-08 * math.Cos(1.39470396488+22003.9146348698*t) result += 2.428e-08 * math.Cos(3.24183056052+78051.5857313169*t) result += 2.12e-08 * math.Cos(4.30691000285+5643.1785636774*t) result += 2.257e-08 * math.Cos(3.15557225618+90617.7374312997*t) result += 1.813e-08 * math.Cos(3.75574218285+3340.6124266998*t) result += 2.226e-08 * math.Cos(2.79699346659+12036.4607348882*t) result += 1.888e-08 * math.Cos(0.86991545823+8635.9420037632*t) result += 1.517e-08 * math.Cos(1.95852055701+398.1490034082*t) result += 1.581e-08 * math.Cos(3.19976230948+5088.6288397668*t) result += 1.421e-08 * math.Cos(6.25530883827+2544.3144198834*t) result += 1.595e-08 * math.Cos(0.25619915135+17298.1823273262*t) result += 1.391e-08 * math.Cos(4.69964175561+7058.5984613154*t) result += 1.478e-08 * math.Cos(2.81808207569+25934.1243310894*t) result += 1.481e-08 * math.Cos(3.65823554806+11506.7697697936*t) result += 1.693e-08 * math.Cos(4.95689385293+156475.290247996*t) result += 1.183e-08 * math.Cos(1.29343061246+775.522611324*t) result += 1.114e-08 * math.Cos(2.37889311846+3738.761430108*t) result += 9.94e-09 * math.Cos(4.30088900425+9225.539273283*t) result += 9.24e-09 * math.Cos(3.06451026812+4164.311989613*t) result += 8.67e-09 * math.Cos(0.55606931068+8429.2412664666*t) result += 9.88e-09 * math.Cos(5.97286104208+7079.3738568078*t) result += 8.24e-09 * math.Cos(1.50984806173+10447.3878396044*t) result += 9.15e-09 * math.Cos(0.12635654592+11015.1064773348*t) result += 7.42e-09 * math.Cos(1.99159139281+26087.9031415742*t) result -= -1.039e-08 result += 8.5e-09 * math.Cos(4.24120016095+29864.334027309*t) result += 7.55e-09 * math.Cos(2.8963187332+4732.0306273434*t) result += 7.14e-09 * math.Cos(1.37548118603+2146.1654164752*t) result += 7.08e-09 * math.Cos(1.91406542362+8031.0922630584*t) result += 7.46e-09 * math.Cos(0.57893808616+796.2980068164*t) result += 8.02e-09 * math.Cos(5.1233913723+2942.4634232916*t) result += 7.51e-09 * math.Cos(1.67479850166+21228.3920235458*t) result += 6.02e-09 * math.Cos(4.09976538826+64809.8055049413*t) result += 5.94e-09 * math.Cos(3.49580704962+16496.3613962024*t) result += 5.92e-09 * math.Cos(4.59481504319+4690.4798363586*t) result += 5.3e-09 * math.Cos(5.739792952+8827.3902698748*t) result += 5.03e-09 * math.Cos(5.66433137112+33794.5437235286*t) result += 4.83e-09 * math.Cos(1.57106522411+801.8209311238*t) result += 4.38e-09 * math.Cos(0.06707733767+3128.3887650958*t) result += 4.23e-09 * math.Cos(2.86944595927+12566.1516999828*t) result += 5.04e-09 * math.Cos(3.2620766916+7632.9432596502*t) result += 5.52e-09 * math.Cos(1.02926440457+239762.204517549*t) result += 4.27e-09 * math.Cos(3.6743437821+213.299095438*t) result += 4.04e-09 * math.Cos(1.46193297142+15720.8387848784*t) result += 5.03e-09 * math.Cos(4.85802444134+6290.1893969922*t) result += 4.17e-09 * math.Cos(0.81920713533+5216.5803728014*t) result += 3.65e-09 * math.Cos(0.01002966162+12168.0026965746*t) result += 3.63e-09 * math.Cos(1.28376436579+6206.8097787158*t) result += 3.53e-09 * math.Cos(4.7005913311+7234.794256242*t) result += 4.15e-09 * math.Cos(0.96862624175+4136.9104335162*t) result += 3.87e-09 * math.Cos(3.09145061418+25158.6017197654*t) result += 3.73e-09 * math.Cos(2.65119262792+7342.4577801806*t) result += 3.61e-09 * math.Cos(2.97762937739+9623.6882766912*t) result += 4.18e-09 * math.Cos(3.75759994446+5230.807466803*t) result += 3.96e-09 * math.Cos(1.22507712354+6438.4962494256*t) result += 3.22e-09 * math.Cos(1.21162178805+8662.240323563*t) result += 2.84e-09 * math.Cos(5.64170320068+1589.0728952838*t) result += 3.79e-09 * math.Cos(1.72248432748+14945.3161735544*t) result += 3.2e-09 * math.Cos(3.94161159962+7330.8231617461*t) result += 3.13e-09 * math.Cos(5.47602376446+1194.4470102246*t) result += 2.92e-09 * math.Cos(1.38971327603+11769.8536931664*t) result += 3.05e-09 * math.Cos(0.80429352049+37724.7534197482*t) result += 2.57e-09 * math.Cos(5.81382809757+426.598190876*t) result += 2.65e-09 * math.Cos(6.10358507671+6836.6452528338*t) result += 2.5e-09 * math.Cos(4.56452895547+7477.522860216*t) result += 2.66e-09 * math.Cos(2.62926282354+7238.6755916*t) result += 2.63e-09 * math.Cos(6.22089501237+6133.5126528568*t) result += 3.06e-09 * math.Cos(2.79682380531+1748.016413067*t) result += 2.36e-09 * math.Cos(2.46093023714+11371.7046897582*t) result += 3.16e-09 * math.Cos(1.62662805006+250908.490120415*t) result += 2.16e-09 * math.Cos(3.68721275185+5849.3641121146*t) result += 2.3e-09 * math.Cos(0.36165162947+5863.5912061162*t) result += 2.33e-09 * math.Cos(5.03509933858+20426.571092422*t) result += 2e-09 * math.Cos(5.86073159059+4535.0594369244*t) result += 2.77e-09 * math.Cos(4.65400292395+82239.1669577989*t) result += 2.09e-09 * math.Cos(3.72323200804+10973.55568635*t) result += 1.99e-09 * math.Cos(5.05186622555+5429.8794682394*t) result += 2.56e-09 * math.Cos(2.4092327977+19651.048481098*t) result += 2.1e-09 * math.Cos(4.50691909144+29088.811415985*t) result += 1.81e-09 * math.Cos(6.00294783127+4292.3308329504*t) result += 2.49e-09 * math.Cos(0.12900984422+154379.795624486*t) result += 2.09e-09 * math.Cos(3.87759458598+17789.845619785*t) result += 2.25e-09 * math.Cos(3.18339652605+18875.525869774*t) result += 1.91e-09 * math.Cos(4.53897489299+18477.1087646123*t) result += 1.72e-09 * math.Cos(2.09694183014+13095.8426650774*t) result += 1.82e-09 * math.Cos(3.161079435+16730.4636895958*t) result += 1.88e-09 * math.Cos(2.22746128596+41654.9631159678*t) result += 1.64e-09 * math.Cos(5.18686275017+5481.2549188676*t) result += 1.6e-09 * math.Cos(2.49298855159+12592.4500197826*t) result += 1.55e-09 * math.Cos(1.5959543823+10021.8372800994*t) result += 1.35e-09 * math.Cos(0.21349051064+10988.808157535*t) result += 1.78e-09 * math.Cos(3.8037517797+23581.2581773176*t) result += 1.23e-09 * math.Cos(1.66800739151+15110.4661198662*t) result += 1.22e-09 * math.Cos(2.72678272244+18849.2275499742*t) result += 1.26e-09 * math.Cos(1.1767551291+14919.0178537546*t) result += 1.42e-09 * math.Cos(3.95053441332+337.8142631964*t) result += 1.16e-09 * math.Cos(6.06340906229+6709.6740408674*t) result += 1.37e-09 * math.Cos(3.52143246757+12139.5535091068*t) result += 1.36e-09 * math.Cos(2.92179113542+32217.2001810808*t) result += 1.1e-09 * math.Cos(3.51203379263+18052.9295431578*t) result += 1.47e-09 * math.Cos(4.63371971408+22805.7355659936*t) result += 1.08e-09 * math.Cos(5.45280814878+7.1135470008*t) result += 1.48e-09 * math.Cos(0.65447253687+95480.9471841745*t) result += 1.19e-09 * math.Cos(5.92110458985+33019.0211122046*t) result += 1.1e-09 * math.Cos(5.34824206306+639.897286314*t) result += 1.06e-09 * math.Cos(3.71081682629+14314.1681130498*t) result += 1.39e-09 * math.Cos(6.17607198418+24356.7807886416*t) result += 1.18e-09 * math.Cos(5.5973871267+161338.50000087*t) result += 1.17e-09 * math.Cos(3.6506527164+45585.1728121874*t) result += 1.27e-09 * math.Cos(4.74596574209+49515.382508407*t) result += 1.2e-09 * math.Cos(1.04211499785+6915.8595893046*t) result += 1.2e-09 * math.Cos(5.60638811846+5650.2921106782*t) result += 1.15e-09 * math.Cos(3.10668213289+14712.317116458*t) result += 9.9e-10 * math.Cos(0.69018940049+12779.4507954208*t) result += 9.7e-10 * math.Cos(1.07908724794+9917.6968745098*t) result += 9.3e-10 * math.Cos(2.62295197319+17260.1546546904*t) result += 9.9e-10 * math.Cos(4.45774681732+4933.2084403326*t) result += 1.23e-09 * math.Cos(1.37488922089+28286.9904848612*t) result += 1.21e-09 * math.Cos(5.19767249813+27511.4678735372*t) result += 1.05e-09 * math.Cos(0.87192267806+77375.9572049241*t) result += 8.7e-10 * math.Cos(3.9363781295+17654.7805397496*t) result += 1.22e-09 * math.Cos(2.2395606868+83997.0911355954*t) result += 8.7e-10 * math.Cos(4.18201600952+22779.4372461938*t) result += 1.04e-09 * math.Cos(4.59580877295+1349.8674096588*t) result += 1.02e-09 * math.Cos(2.83545248411+12352.8526045448*t) result += 1.02e-09 * math.Cos(3.97386522171+10818.1352869158*t) result += 1.01e-09 * math.Cos(4.32892825857+36147.4098773004*t) result += 9.4e-10 * math.Cos(5.00001709261+150192.214398004*t) result += 7.7e-10 * math.Cos(3.97199369296+1592.5960136328*t) result += 1e-09 * math.Cos(6.07733097102+26735.9452622132*t) result += 8.6e-10 * math.Cos(5.2602963825+28313.288804661*t) result += 9.3e-10 * math.Cos(4.31900620254+44809.6502008634*t) result += 7.6e-10 * math.Cos(6.22743405935+13521.7514415914*t) result += 7.2e-10 * math.Cos(1.55820597747+6256.7775301916*t) result += 8.2e-10 * math.Cos(4.95202664555+10575.4066829418*t) result += 8.2e-10 * math.Cos(1.69647647075+1990.745017041*t) result += 7.5e-10 * math.Cos(2.29836095644+3634.6210245184*t) result += 7.5e-10 * math.Cos(2.66367876557+16200.7727245012*t) result += 8.7e-10 * math.Cos(0.26630214764+31441.6775697568*t) result += 7.7e-10 * math.Cos(2.25530954137+5235.3285382367*t) result += 7.6e-10 * math.Cos(1.09869730846+12903.9659631792*t) result += 5.8e-10 * math.Cos(4.28246138307+12559.038152982*t) result += 6.4e-10 * math.Cos(5.51112830114+173904.651700853*t) result += 5.6e-10 * math.Cos(2.60133794851+73188.3759784421*t) result += 5.5e-10 * math.Cos(5.81483150022+143233.51002162*t) result += 5.4e-10 * math.Cos(3.38482031504+323049.118787103*t) result += 3.9e-10 * math.Cos(3.28500401343+71768.5098813255*t) result += 3.9e-10 * math.Cos(3.1123991069+96900.8132812911*t) return result } func GetEarthB1(t float64) float64 { var result float64 = 0.0 result += 9.03e-08 * math.Cos(3.8972906189+5507.5532386674*t) result += 6.177e-08 * math.Cos(1.73038850355+5223.6939198022*t) result += 3.8e-08 * math.Cos(5.24404145734+2352.8661537718*t) result += 2.834e-08 * math.Cos(2.4734503745+1577.3435424478*t) result += 1.817e-08 * math.Cos(0.41874743765+6283.0758499914*t) result += 1.499e-08 * math.Cos(1.83320979291+5856.4776591154*t) result += 1.466e-08 * math.Cos(5.69401926017+5753.3848848968*t) result += 1.301e-08 * math.Cos(2.18890066314+9437.762934887*t) result += 1.233e-08 * math.Cos(4.95222451476+10213.285546211*t) result += 1.021e-08 * math.Cos(0.12866660208+7860.4193924392*t) result += 9.82e-09 * math.Cos(0.09005453285+14143.4952424306*t) result += 8.65e-09 * math.Cos(1.73949953555+3930.2096962196*t) result += 5.81e-09 * math.Cos(2.26949174067+5884.9268465832*t) result += 5.24e-09 * math.Cos(5.65662503159+529.6909650946*t) result += 4.73e-09 * math.Cos(6.22750969242+6309.3741697912*t) result += 4.51e-09 * math.Cos(1.53288619213+18073.7049386502*t) result += 3.64e-09 * math.Cos(3.61614477374+13367.9726311066*t) result += 3.72e-09 * math.Cos(3.2247072132+6275.9623029906*t) result += 2.68e-09 * math.Cos(2.34341267879+11790.6290886588*t) result += 3.22e-09 * math.Cos(0.94084045832+6069.7767545534*t) result += 2.32e-09 * math.Cos(0.26781182579+7058.5984613154*t) result += 2.16e-09 * math.Cos(6.05952221329+10977.078804699*t) result += 2.32e-09 * math.Cos(2.93325646109+22003.9146348698*t) result += 2.04e-09 * math.Cos(3.86264841382+6496.3749454294*t) result += 2.02e-09 * math.Cos(2.81892511133+15720.8387848784*t) result += 1.85e-09 * math.Cos(4.93512381859+12036.4607348882*t) result += 2.2e-09 * math.Cos(3.99305643742+6812.766815086*t) result += 1.66e-09 * math.Cos(1.74970002999+11506.7697697936*t) result += 2.12e-09 * math.Cos(1.57166285369+4694.0029547076*t) result += 1.57e-09 * math.Cos(1.08259734788+5643.1785636774*t) result += 1.54e-09 * math.Cos(5.99434678412+5486.777843175*t) result += 1.44e-09 * math.Cos(5.23285656085+78051.5857313169*t) result += 1.44e-09 * math.Cos(1.16454655948+90617.7374312997*t) result += 1.37e-09 * math.Cos(2.67760436027+6290.1893969922*t) result += 1.8e-09 * math.Cos(2.06509026215+7084.8967811152*t) result += 1.21e-09 * math.Cos(5.90212574947+9225.539273283*t) result += 1.5e-09 * math.Cos(2.00175038718+5230.807466803*t) result += 1.49e-09 * math.Cos(5.06157254516+17298.1823273262*t) result += 1.18e-09 * math.Cos(5.39979058038+3340.6124266998*t) result += 1.61e-09 * math.Cos(3.32421999691+6283.3196674749*t) result += 1.21e-09 * math.Cos(4.36722193162+19651.048481098*t) result += 1.16e-09 * math.Cos(5.83462858507+4705.7323075436*t) result += 1.28e-09 * math.Cos(4.35489873365+25934.1243310894*t) result += 1.43e-09 result += 1.09e-09 * math.Cos(2.52157834166+6438.4962494256*t) result += 9.9e-10 * math.Cos(2.70727488041+5216.5803728014*t) result += 1.03e-09 * math.Cos(0.93782340879+8827.3902698748*t) result += 8.2e-10 * math.Cos(4.2921468039+8635.9420037632*t) result += 7.9e-10 * math.Cos(2.24085737326+1059.3819301892*t) result += 9.7e-10 * math.Cos(5.50959692365+29864.334027309*t) result += 7.2e-10 * math.Cos(0.21891639822+21228.3920235458*t) result += 7.1e-10 * math.Cos(2.86755026812+6681.2248533996*t) result += 7.4e-10 * math.Cos(2.20184828895+37724.7534197482*t) result += 6.3e-10 * math.Cos(4.45586625948+7079.3738568078*t) result += 6.1e-10 * math.Cos(0.63918772258+33794.5437235286*t) result += 4.7e-10 * math.Cos(2.09070235724+3128.3887650958*t) result += 4.7e-10 * math.Cos(3.325438433+26087.9031415742*t) result += 4.9e-10 * math.Cos(1.60680905005+6702.5604938666*t) result += 5.7e-10 * math.Cos(0.11215813438+29088.811415985*t) result += 5.6e-10 * math.Cos(5.47982934911+775.522611324*t) result += 5e-10 * math.Cos(1.89396788463+12139.5535091068*t) result += 4.7e-10 * math.Cos(2.9721490724+20426.571092422*t) result += 4.1e-10 * math.Cos(5.5532939489+11015.1064773348*t) result += 4.1e-10 * math.Cos(5.91861144924+23581.2581773176*t) result += 4.5e-10 * math.Cos(4.95273290181+5863.5912061162*t) result += 5e-10 * math.Cos(3.62740835096+41654.9631159678*t) result += 3.7e-10 * math.Cos(6.09033460601+64809.8055049413*t) result += 3.7e-10 * math.Cos(5.86153655431+12566.1516999828*t) result += 4.6e-10 * math.Cos(1.65798680284+25158.6017197654*t) result += 3.8e-10 * math.Cos(2.00673650251+426.598190876*t) result += 3.6e-10 * math.Cos(6.24373396652+6283.14316029419*t) result += 3.6e-10 * math.Cos(0.40465162918+6283.0085396886*t) result += 3.2e-10 * math.Cos(6.03707103538+2942.4634232916*t) result += 4.1e-10 * math.Cos(4.86809570283+1592.5960136328*t) result += 2.8e-10 * math.Cos(4.38359423735+7632.9432596502*t) result += 2.8e-10 * math.Cos(6.03334294232+17789.845619785*t) result += 2.6e-10 * math.Cos(3.88971333608+5331.3574437408*t) result += 2.6e-10 * math.Cos(5.94932724051+16496.3613962024*t) result += 3.1e-10 * math.Cos(1.44666331503+16730.4636895958*t) result += 2.6e-10 * math.Cos(6.26376705837+23543.2305046818*t) result += 3.3e-10 * math.Cos(0.93797239147+213.299095438*t) result += 2.6e-10 * math.Cos(3.71858432944+13095.8426650774*t) result += 2.7e-10 * math.Cos(0.60565274405+10988.808157535*t) result += 2.3e-10 * math.Cos(4.4438898555+18849.2275499742*t) result += 2.8e-10 * math.Cos(1.53862289477+6279.4854213396*t) result += 2.8e-10 * math.Cos(1.96831814872+6286.6662786432*t) result += 2.8e-10 * math.Cos(5.78094918529+15110.4661198662*t) result += 2.6e-10 * math.Cos(2.48165809843+5729.506447149*t) result += 2e-10 * math.Cos(3.85655029499+9623.6882766912*t) result += 2.1e-10 * math.Cos(5.83006047147+7234.794256242*t) result += 2.1e-10 * math.Cos(0.69628570421+398.1490034082*t) result += 2.2e-10 * math.Cos(5.02222806555+6127.6554505572*t) result += 2e-10 * math.Cos(3.4761126529+6148.010769956*t) result += 2e-10 * math.Cos(0.90769829044+5481.2549188676*t) result += 2e-10 * math.Cos(0.03081589303+6418.1409300268*t) result += 2e-10 * math.Cos(3.74220084927+1589.0728952838*t) result += 2.1e-10 * math.Cos(4.00149269576+3154.6870848956*t) result += 1.8e-10 * math.Cos(1.58348238359+2118.7638603784*t) result += 1.9e-10 * math.Cos(0.85407021371+14712.317116458*t) return result } func GetEarthB2(t float64) float64 { var result float64 = 0.0 result += 1.662e-08 * math.Cos(1.62703209173+84334.6615813083*t) result += 4.92e-09 * math.Cos(2.41382223971+1047.7473117547*t) result += 3.44e-09 * math.Cos(2.24353004539+5507.5532386674*t) result += 2.58e-09 * math.Cos(6.00906896311+5223.6939198022*t) result += 1.31e-09 * math.Cos(0.9544734524+6283.0758499914*t) result += 8.6e-10 * math.Cos(1.67530247303+7860.4193924392*t) result += 9e-10 * math.Cos(0.97606804452+1577.3435424478*t) result += 9e-10 * math.Cos(0.37899871725+2352.8661537718*t) result += 8.9e-10 * math.Cos(6.25807507963+10213.285546211*t) result += 7.5e-10 * math.Cos(0.84213523741+167621.575850862*t) result += 5.2e-10 * math.Cos(1.70501566089+14143.4952424306*t) result += 5.7e-10 * math.Cos(6.15295833679+12194.0329146209*t) result += 5.1e-10 * math.Cos(1.2761601674+5753.3848848968*t) result += 5.1e-10 * math.Cos(5.37229738682+6812.766815086*t) result += 3.4e-10 * math.Cos(1.73672994279+7058.5984613154*t) result += 3.8e-10 * math.Cos(2.77761031485+10988.808157535*t) result += 4.6e-10 * math.Cos(3.38617099014+156475.290247996*t) result += 2.1e-10 * math.Cos(1.95248349228+8827.3902698748*t) result += 1.8e-10 * math.Cos(3.33419222028+8429.2412664666*t) result += 1.9e-10 * math.Cos(4.32945160287+17789.845619785*t) result += 1.7e-10 * math.Cos(0.66191210656+6283.0085396886*t) result += 1.8e-10 * math.Cos(3.74885333072+11769.8536931664*t) result += 1.7e-10 * math.Cos(4.23058370776+10977.078804699*t) result += 1.7e-10 * math.Cos(1.78116162721+5486.777843175*t) result += 2.1e-10 * math.Cos(1.36972913918+12036.4607348882*t) result += 1.7e-10 * math.Cos(2.79601092529+796.2980068164*t) result += 1.5e-10 * math.Cos(0.4308784885+11790.6290886588*t) result += 1.7e-10 * math.Cos(1.35132152761+78051.5857313169*t) result += 1.5e-10 * math.Cos(1.17032155085+213.299095438*t) result += 1.8e-10 * math.Cos(2.85221514199+5088.6288397668*t) result += 1.7e-10 * math.Cos(0.21780913672+6283.14316029419*t) result += 1.3e-10 * math.Cos(1.21201504386+25132.3033999656*t) result += 1.2e-10 * math.Cos(1.12953712197+90617.7374312997*t) result += 1.2e-10 * math.Cos(5.13714452592+7079.3738568078*t) result += 1.3e-10 * math.Cos(3.79842135217+4933.2084403326*t) result += 1.2e-10 * math.Cos(4.89407978213+3738.761430108*t) result += 1.5e-10 * math.Cos(6.05682328852+398.1490034082*t) result += 1.4e-10 * math.Cos(4.81029291856+4694.0029547076*t) result += 1.1e-10 * math.Cos(0.61684523405+3128.3887650958*t) result += 1.1e-10 * math.Cos(5.328765385+6040.3472460174*t) result += 1.4e-10 * math.Cos(5.27227350286+4535.0594369244*t) result += 1.1e-10 * math.Cos(2.39292099451+5331.3574437408*t) result += 1e-10 * math.Cos(4.4529653271+6525.8044539654*t) result += 1.4e-10 * math.Cos(4.66400985037+8031.0922630584*t) result += 1e-10 * math.Cos(3.22472385926+9437.762934887*t) result += 1.1e-10 * math.Cos(3.80913404437+801.8209311238*t) result += 1e-10 * math.Cos(5.15032130575+11371.7046897582*t) result += 1.3e-10 * math.Cos(0.98720797401+5729.506447149*t) result += 9e-11 * math.Cos(5.94191743597+7632.9432596502*t) return result } func GetEarthB3(t float64) float64 { var result float64 = 0.0 result += 1.1e-10 * math.Cos(0.23877262399+7860.4193924392*t) result += 9e-11 * math.Cos(1.16069982609+5507.5532386674*t) result += 8e-11 * math.Cos(1.65357552925+5884.9268465832*t) result += 8e-11 * math.Cos(2.86720038197+7058.5984613154*t) result += 7e-11 * math.Cos(3.04818741666+5486.777843175*t) result += 7e-11 * math.Cos(2.59437103785+529.6909650946*t) result += 8e-11 * math.Cos(4.02863090524+6256.7775301916*t) result += 8e-11 * math.Cos(2.42003508927+5753.3848848968*t) result += 6e-11 * math.Cos(0.84181087594+6275.9623029906*t) result += 6e-11 * math.Cos(5.40160929468+1577.3435424478*t) result += 7e-11 * math.Cos(2.73399865247+6309.3741697912*t) return result } func GetEarthB4(t float64) float64 { var result float64 = 0.0 result += 4e-11 * math.Cos(0.79662198849+6438.4962494256*t) result += 5e-11 * math.Cos(0.84308705203+1047.7473117547*t) result += 5e-11 * math.Cos(0.05711572303+84334.6615813083*t) result += 3e-11 * math.Cos(3.46779895686+6279.5527316424*t) result += 3e-11 * math.Cos(2.89822201212+6127.6554505572*t) return result } func GetEarthR0(t float64) float64 { var result float64 = 0.0 result += 1.00013988799 result += 0.01670699626 * math.Cos(3.09846350771+6283.0758499914*t) result += 0.00013956023 * math.Cos(3.0552460962+12566.1516999828*t) result += 3.08372e-05 * math.Cos(5.19846674381+77713.7714681205*t) result += 1.628461e-05 * math.Cos(1.17387749012+5753.3848848968*t) result += 1.575568e-05 * math.Cos(2.84685245825+7860.4193924392*t) result += 9.24799e-06 * math.Cos(5.45292234084+11506.7697697936*t) result += 5.42444e-06 * math.Cos(4.56409149777+3930.2096962196*t) result += 4.7211e-06 * math.Cos(3.66100022149+5884.9268465832*t) result += 3.2878e-06 * math.Cos(5.89983646482+5223.6939198022*t) result += 3.45983e-06 * math.Cos(0.96368617687+5507.5532386674*t) result += 3.06784e-06 * math.Cos(0.29867139512+5573.1428014331*t) result += 1.74844e-06 * math.Cos(3.01193636534+18849.2275499742*t) result += 2.43189e-06 * math.Cos(4.27349536153+11790.6290886588*t) result += 2.11829e-06 * math.Cos(5.84714540314+1577.3435424478*t) result += 1.85752e-06 * math.Cos(5.02194447178+10977.078804699*t) result += 1.09835e-06 * math.Cos(5.05510636285+5486.777843175*t) result += 9.8316e-07 * math.Cos(0.88681311277+6069.7767545534*t) result += 8.6499e-07 * math.Cos(5.68959778254+15720.8387848784*t) result += 8.5825e-07 * math.Cos(1.27083733351+161000.685737674*t) result += 6.2916e-07 * math.Cos(0.92177108832+529.6909650946*t) result += 5.7056e-07 * math.Cos(2.01374292014+83996.8473181119*t) result += 6.4903e-07 * math.Cos(0.27250613787+17260.1546546904*t) result += 4.9384e-07 * math.Cos(3.24501240359+2544.3144198834*t) result += 5.5736e-07 * math.Cos(5.24159798933+71430.6956181291*t) result += 4.2515e-07 * math.Cos(6.01110242003+6275.9623029906*t) result += 4.6963e-07 * math.Cos(2.57805070386+775.522611324*t) result += 3.8968e-07 * math.Cos(5.36071738169+4694.0029547076*t) result += 4.4661e-07 * math.Cos(5.53715807302+9437.762934887*t) result += 3.566e-07 * math.Cos(1.67468058995+12036.4607348882*t) result += 3.1921e-07 * math.Cos(0.18368229781+5088.6288397668*t) result += 3.1846e-07 * math.Cos(1.77775642085+398.1490034082*t) result += 3.3193e-07 * math.Cos(0.24370300098+7084.8967811152*t) result += 3.8245e-07 * math.Cos(2.39255343974+8827.3902698748*t) result += 2.8464e-07 * math.Cos(1.21344868176+6286.5989683404*t) result += 3.749e-07 * math.Cos(0.82952922332+19651.048481098*t) result += 3.6957e-07 * math.Cos(4.90107591914+12139.5535091068*t) result += 3.4537e-07 * math.Cos(1.84270693282+2942.4634232916*t) result += 2.6275e-07 * math.Cos(4.58896850401+10447.3878396044*t) result += 2.4596e-07 * math.Cos(3.78660875483+8429.2412664666*t) result += 2.3587e-07 * math.Cos(0.26866117066+796.2980068164*t) result += 2.7793e-07 * math.Cos(1.89934330904+6279.5527316424*t) result += 2.3927e-07 * math.Cos(4.99598548138+5856.4776591154*t) result += 2.0349e-07 * math.Cos(4.65267995431+2146.1654164752*t) result += 2.3287e-07 * math.Cos(2.80783650928+14143.4952424306*t) result += 2.2103e-07 * math.Cos(1.95004702988+3154.6870848956*t) result += 1.9506e-07 * math.Cos(5.38227371393+2352.8661537718*t) result += 1.7958e-07 * math.Cos(0.19871379385+6812.766815086*t) result += 1.7174e-07 * math.Cos(4.43315560735+10213.285546211*t) result += 1.619e-07 * math.Cos(5.23160507859+17789.845619785*t) result += 1.7314e-07 * math.Cos(6.15200787916+16730.4636895958*t) result += 1.3814e-07 * math.Cos(5.18962074032+8031.0922630584*t) result += 1.8833e-07 * math.Cos(0.67306674027+149854.400134808*t) result += 1.8331e-07 * math.Cos(2.25348733734+23581.2581773176*t) result += 1.3641e-07 * math.Cos(3.68516118804+4705.7323075436*t) result += 1.3139e-07 * math.Cos(0.65289581324+13367.9726311066*t) result += 1.0414e-07 * math.Cos(4.33285688538+11769.8536931664*t) result += 9.978e-08 * math.Cos(4.20126336355+6309.3741697912*t) result += 1.0169e-07 * math.Cos(1.59390681369+4690.4798363586*t) result += 7.564e-08 * math.Cos(2.6256059739+6256.7775301916*t) result += 9.661e-08 * math.Cos(3.6758679122+27511.4678735372*t) result += 6.743e-08 * math.Cos(0.56270332741+3340.6124266998*t) result += 8.743e-08 * math.Cos(6.06359123461+1748.016413067*t) result += 7.786e-08 * math.Cos(3.67371235637+12168.0026965746*t) result += 6.633e-08 * math.Cos(5.66149277792+11371.7046897582*t) result += 7.712e-08 * math.Cos(0.31242577789+7632.9432596502*t) result += 6.592e-08 * math.Cos(3.13576266188+801.8209311238*t) result += 7.46e-08 * math.Cos(5.64757188143+11926.2544136688*t) result += 6.933e-08 * math.Cos(2.923845864+6681.2248533996*t) result += 6.802e-08 * math.Cos(1.4232980642+23013.5395395872*t) result += 6.115e-08 * math.Cos(5.13393615454+1194.4470102246*t) result += 6.477e-08 * math.Cos(2.64986648492+19804.8272915828*t) result += 5.233e-08 * math.Cos(4.62434053374+6438.4962494256*t) result += 6.147e-08 * math.Cos(3.02863936662+233141.314404362*t) result += 4.608e-08 * math.Cos(1.72194702724+7234.794256242*t) result += 4.221e-08 * math.Cos(1.55697533729+7238.6755916*t) result += 5.314e-08 * math.Cos(2.40716580847+11499.6562227928*t) result += 5.128e-08 * math.Cos(5.3239896569+11513.8833167944*t) result += 4.77e-08 * math.Cos(0.25554312006+11856.2186514245*t) result += 5.519e-08 * math.Cos(2.09089154502+17298.1823273262*t) result += 5.625e-08 * math.Cos(4.34052903053+90955.5516944961*t) result += 4.578e-08 * math.Cos(4.4656964157+5746.271337896*t) result += 3.788e-08 * math.Cos(4.9072938351+4164.311989613*t) result += 5.337e-08 * math.Cos(5.09957905104+31441.6775697568*t) result += 3.967e-08 * math.Cos(1.20054555174+1349.8674096588*t) result += 4.008e-08 * math.Cos(3.03007204392+1059.3819301892*t) result += 3.476e-08 * math.Cos(0.7608027703+10973.55568635*t) result += 4.232e-08 * math.Cos(1.05485713117+5760.4984318976*t) result += 4.582e-08 * math.Cos(3.76570026763+6386.16862421*t) result += 3.335e-08 * math.Cos(3.13829943354+6836.6452528338*t) result += 3.418e-08 * math.Cos(3.00072390334+4292.3308329504*t) result += 3.598e-08 * math.Cos(5.70718084323+5643.1785636774*t) result += 3.237e-08 * math.Cos(4.16448773994+9917.6968745098*t) result += 4.154e-08 * math.Cos(2.59941292162+7058.5984613154*t) result += 3.362e-08 * math.Cos(4.54577697964+4732.0306273434*t) result += 2.978e-08 * math.Cos(1.3056126882+6283.14316029419*t) result += 2.765e-08 * math.Cos(0.51311975679+26.2983197998*t) result += 2.802e-08 * math.Cos(5.66263240521+8635.9420037632*t) result += 2.927e-08 * math.Cos(5.73787481548+16200.7727245012*t) result += 3.164e-08 * math.Cos(1.69140262657+11015.1064773348*t) result += 2.598e-08 * math.Cos(2.96244118586+25132.3033999656*t) result += 3.519e-08 * math.Cos(3.62639325753+244287.600007228*t) result += 2.676e-08 * math.Cos(4.2072570085+18073.7049386502*t) result += 2.978e-08 * math.Cos(1.74971565805+6283.0085396886*t) result += 2.287e-08 * math.Cos(1.06975704977+14314.1681130498*t) result += 2.863e-08 * math.Cos(5.92838131397+14712.317116458*t) result += 3.071e-08 * math.Cos(0.23793217002+35371.8872659764*t) result += 2.656e-08 * math.Cos(0.8995930178+12352.8526045448*t) result += 2.415e-08 * math.Cos(2.79975176257+709.9330485583*t) result += 2.814e-08 * math.Cos(3.51488206882+21228.3920235458*t) result += 1.977e-08 * math.Cos(2.6135829755+951.7184062506*t) result += 2.548e-08 * math.Cos(2.47684686575+6208.2942514241*t) result += 1.999e-08 * math.Cos(0.5609038816+7079.3738568078*t) result += 2.305e-08 * math.Cos(1.05376461628+22483.8485744926*t) result += 1.855e-08 * math.Cos(2.86090681163+5216.5803728014*t) result += 2.157e-08 * math.Cos(1.31396741861+154717.609887683*t) result += 1.97e-08 * math.Cos(4.36929875289+167283.761587666*t) result += 1.635e-08 * math.Cos(5.85571606764+10984.1923516998*t) result += 1.754e-08 * math.Cos(2.14452408833+6290.1893969922*t) result += 2.154e-08 * math.Cos(6.03828341543+10873.9860304804*t) result += 1.714e-08 * math.Cos(3.70157691113+1592.5960136328*t) result += 1.541e-08 * math.Cos(6.21598380732+23543.2305046818*t) result += 1.611e-08 * math.Cos(1.99824499377+10969.9652576982*t) result += 1.712e-08 * math.Cos(1.34295663542+3128.3887650958*t) result += 1.642e-08 * math.Cos(5.55026665339+6496.3749454294*t) result += 1.502e-08 * math.Cos(5.43948825854+155.4203994342*t) result += 1.827e-08 * math.Cos(5.91227480261+3738.761430108*t) result += 1.726e-08 * math.Cos(2.16764983583+10575.4066829418*t) result += 1.532e-08 * math.Cos(5.3568310707+13521.7514415914*t) result += 1.829e-08 * math.Cos(1.66006148731+39302.096962196*t) result += 1.605e-08 * math.Cos(1.90928637633+6133.5126528568*t) result += 1.282e-08 * math.Cos(2.46014880418+13916.0191096416*t) result += 1.211e-08 * math.Cos(4.4136063155+3894.1818295422*t) result += 1.394e-08 * math.Cos(1.77801929354+9225.539273283*t) result += 1.571e-08 * math.Cos(4.95512957592+25158.6017197654*t) result += 1.205e-08 * math.Cos(1.19212540615+3.523118349*t) result += 1.132e-08 * math.Cos(2.69830084955+6040.3472460174*t) result += 1.504e-08 * math.Cos(5.77002730341+18209.3302636602*t) result += 1.393e-08 * math.Cos(1.62621805428+5120.6011455836*t) result += 1.077e-08 * math.Cos(2.93931554233+17256.6315363414*t) result += 1.232e-08 * math.Cos(0.71655165307+143571.324284816*t) result += 1.087e-08 * math.Cos(0.99769687939+955.5997416086*t) result += 1.068e-08 * math.Cos(5.28472576231+65147.6197681377*t) result += 9.8e-09 * math.Cos(5.10949204607+6172.869528772*t) result += 1.169e-08 * math.Cos(3.11664290862+14945.3161735544*t) result += 1.202e-08 * math.Cos(4.02992510402+553.5694028424*t) result += 9.79e-09 * math.Cos(2.00000879212+15110.4661198662*t) result += 9.62e-09 * math.Cos(4.023807714+6282.0955289232*t) result += 9.99e-09 * math.Cos(3.6264300279+6262.300454499*t) result += 1.03e-08 * math.Cos(5.84989900289+213.299095438*t) result += 1.014e-08 * math.Cos(2.84221578218+8662.240323563*t) result += 1.185e-08 * math.Cos(1.51330541132+17654.7805397496*t) result += 9.67e-09 * math.Cos(2.67081017562+5650.2921106782*t) result += 1.222e-08 * math.Cos(2.65423784904+88860.0570709867*t) result += 9.81e-09 * math.Cos(2.36370360283+6206.8097787158*t) result += 1.033e-08 * math.Cos(0.13874927606+11712.9553182308*t) result += 1.103e-08 * math.Cos(3.08477302937+43232.3066584156*t) result += 7.81e-09 * math.Cos(2.53372735932+16496.3613962024*t) result += 1.019e-08 * math.Cos(3.04569392376+6037.244203762*t) result += 7.95e-09 * math.Cos(5.80662989111+5230.807466803*t) result += 8.13e-09 * math.Cos(3.57710279439+10177.2576795336*t) result += 9.62e-09 * math.Cos(5.31470594766+6284.0561710596*t) result += 7.21e-09 * math.Cos(5.96264301567+12559.038152982*t) result += 9.66e-09 * math.Cos(2.74714939953+6244.9428143536*t) result += 9.21e-09 * math.Cos(0.10155275926+29088.811415985*t) result += 6.92e-09 * math.Cos(3.89764447548+1589.0728952838*t) result += 7.19e-09 * math.Cos(5.91791450402+4136.9104335162*t) result += 7.72e-09 * math.Cos(4.05505682353+6127.6554505572*t) result += 7.12e-09 * math.Cos(5.49291532439+22003.9146348698*t) result += 6.72e-09 * math.Cos(1.60700490811+11087.2851259184*t) result += 6.9e-09 * math.Cos(4.50539825563+426.598190876*t) result += 8.54e-09 * math.Cos(3.26104981596+20426.571092422*t) result += 6.56e-09 * math.Cos(4.3241018294+16858.4825329332*t) result += 8.4e-09 * math.Cos(2.59572585222+28766.924424484*t) result += 6.92e-09 * math.Cos(0.61650089011+11403.676995575*t) result += 7e-09 * math.Cos(3.40901167143+7.1135470008*t) result += 7.26e-09 * math.Cos(0.04243053594+5481.2549188676*t) result += 5.57e-09 * math.Cos(4.78317696534+20199.094959633*t) result += 6.49e-09 * math.Cos(1.04027912958+6062.6632075526*t) result += 6.33e-09 * math.Cos(5.70229959167+45892.730433157*t) result += 5.92e-09 * math.Cos(6.11836729658+9623.6882766912*t) result += 5.23e-09 * math.Cos(3.62840021266+5333.9002410216*t) result += 6.04e-09 * math.Cos(5.57734696185+10344.2950653858*t) result += 4.96e-09 * math.Cos(2.21023499449+1990.745017041*t) result += 6.91e-09 * math.Cos(1.96071732602+12416.5885028482*t) result += 6.4e-09 * math.Cos(1.59074172032+18319.5365848796*t) result += 6.25e-09 * math.Cos(3.82362791378+13517.8701062334*t) result += 6.63e-09 * math.Cos(5.08444996779+283.8593188652*t) result += 4.75e-09 * math.Cos(1.17025894287+12569.6748183318*t) result += 6.64e-09 * math.Cos(4.50029469969+47162.5163546352*t) result += 5.69e-09 * math.Cos(0.16310365162+17267.2682016912*t) result += 5.68e-09 * math.Cos(3.86100969474+6076.8903015542*t) result += 5.39e-09 * math.Cos(4.83282276086+18422.6293590982*t) result += 4.66e-09 * math.Cos(0.75872342878+7342.4577801806*t) result += 5.41e-09 * math.Cos(3.07212190507+226858.23855437*t) result += 4.58e-09 * math.Cos(0.26774483096+4590.910180489*t) result += 6.1e-09 * math.Cos(1.53597051291+33019.0211122046*t) result += 6.17e-09 * math.Cos(2.62356328726+11190.377900137*t) result += 5.48e-09 * math.Cos(4.55798855791+18875.525869774*t) result += 6.33e-09 * math.Cos(4.60110281228+66567.4858652543*t) result += 5.96e-09 * math.Cos(5.78202396722+632.7837393132*t) result += 5.33e-09 * math.Cos(5.01786882904+12132.439962106*t) result += 6.03e-09 * math.Cos(5.38458554802+316428.228673915*t) result += 4.69e-09 * math.Cos(0.59168241917+21954.157609398*t) result += 5.48e-09 * math.Cos(3.50613163558+17253.0411076896*t) result += 5.02e-09 * math.Cos(0.98804327589+11609.8625440122*t) result += 5.68e-09 * math.Cos(1.98497313089+7668.6374249425*t) result += 4.82e-09 * math.Cos(1.62141803864+12146.6670561076*t) result += 3.91e-09 * math.Cos(3.68718382989+18052.9295431578*t) result += 4.57e-09 * math.Cos(3.7720573734+156137.475984799*t) result += 4.01e-09 * math.Cos(5.28260651958+15671.0817594066*t) result += 4.69e-09 * math.Cos(1.80963184268+12562.6285816338*t) result += 5.08e-09 * math.Cos(3.36399024699+20597.2439630412*t) result += 4.5e-09 * math.Cos(5.6605429925+10454.5013866052*t) result += 3.75e-09 * math.Cos(4.98534633105+9779.1086761254*t) result += 5.23e-09 * math.Cos(0.97215560834+155427.542936241*t) result += 4.03e-09 * math.Cos(5.13939866506+1551.045222648*t) result += 3.72e-09 * math.Cos(3.69883738807+9388.0059094152*t) result += 3.67e-09 * math.Cos(4.43875659716+4535.0594369244*t) result += 4.06e-09 * math.Cos(4.208631566+12592.4500197826*t) result += 3.6e-09 * math.Cos(2.53924644657+242.728603974*t) result += 4.71e-09 * math.Cos(4.61907324819+5436.9930152402*t) result += 4.41e-09 * math.Cos(5.83872966262+3496.032826134*t) result += 3.85e-09 * math.Cos(4.94496680973+24356.7807886416*t) result += 3.49e-09 * math.Cos(6.15018231784+19800.9459562248*t) result += 3.55e-09 * math.Cos(0.21895678106+5429.8794682394*t) result += 3.44e-09 * math.Cos(5.62993724928+2379.1644735716*t) result += 3.8e-09 * math.Cos(2.72105213143+11933.3679606696*t) result += 4.32e-09 * math.Cos(0.24221790536+17996.0311682222*t) result += 3.78e-09 * math.Cos(5.22517556974+7477.522860216*t) result += 3.37e-09 * math.Cos(5.10888041439+5849.3641121146*t) result += 3.15e-09 * math.Cos(0.57827745123+10557.5941608238*t) result += 3.18e-09 * math.Cos(4.49953141399+3634.6210245184*t) result += 3.23e-09 * math.Cos(1.54274281393+10440.2742926036*t) result += 3.09e-09 * math.Cos(5.76839284397+20.7753954924*t) result += 3.01e-09 * math.Cos(2.34727604008+4686.8894077068*t) result += 4.14e-09 * math.Cos(5.9323760231+51092.7260508548*t) result += 3.61e-09 * math.Cos(2.1639860955+28237.2334593894*t) result += 2.88e-09 * math.Cos(0.18376252189+13095.8426650774*t) result += 2.77e-09 * math.Cos(5.12952205045+13119.7211028252*t) result += 3.27e-09 * math.Cos(6.19222146204+6268.8487559898*t) result += 2.73e-09 * math.Cos(0.30522428863+23141.5583829246*t) result += 2.67e-09 * math.Cos(5.76152585786+5966.6839803348*t) result += 3.08e-09 * math.Cos(5.99280509979+22805.7355659936*t) result += 3.45e-09 * math.Cos(2.92489919444+36949.2308084242*t) result += 2.53e-09 * math.Cos(5.20995219509+24072.9214697764*t) result += 3.42e-09 * math.Cos(5.72702586209+16460.333529525*t) result += 2.61e-09 * math.Cos(2.00304796059+6148.010769956*t) result += 2.38e-09 * math.Cos(5.08264392839+6915.8595893046*t) result += 2.49e-09 * math.Cos(2.94762789744+135.0650800354*t) result += 3.06e-09 * math.Cos(3.89764686987+10988.808157535*t) result += 3.05e-09 * math.Cos(0.05827812117+4701.1165017084*t) result += 3.19e-09 * math.Cos(2.95712862064+163096.180361183*t) result += 2.09e-09 * math.Cos(4.43768461442+6546.1597733642*t) result += 2.7e-09 * math.Cos(2.06643178717+4804.209275927*t) result += 2.17e-09 * math.Cos(0.73691592312+6303.8512454838*t) result += 2.06e-09 * math.Cos(0.32075959415+25934.1243310894*t) result += 2.18e-09 * math.Cos(0.18428135264+28286.9904848612*t) result += 2.05e-09 * math.Cos(5.21312087405+20995.3929664494*t) result += 1.99e-09 * math.Cos(0.44384292491+16737.5772365966*t) result += 2.3e-09 * math.Cos(6.06567392849+6287.0080032545*t) result += 2.19e-09 * math.Cos(1.291942163+5326.7866940208*t) result += 2.01e-09 * math.Cos(1.74700937253+22743.4093795164*t) result += 2.07e-09 * math.Cos(4.45440927276+6279.4854213396*t) result += 2.69e-09 * math.Cos(6.0564044503+64471.9912417449*t) result += 1.9e-09 * math.Cos(0.99256176518+29296.6153895786*t) result += 2.38e-09 * math.Cos(5.42471431221+39609.6545831656*t) result += 2.62e-09 * math.Cos(5.26961924198+522.5774180938*t) result += 2.1e-09 * math.Cos(4.68618183158+6254.6266625236*t) result += 1.97e-09 * math.Cos(2.8062455408+4933.2084403326*t) result += 2.52e-09 * math.Cos(4.36220154608+40879.4405046438*t) result += 2.61e-09 * math.Cos(1.07241516738+55022.9357470744*t) result += 1.89e-09 * math.Cos(3.82966734476+419.4846438752*t) result += 1.85e-09 * math.Cos(4.14324541379+5642.1982426092*t) result += 2.47e-09 * math.Cos(3.44855612987+6702.5604938666*t) result += 2.05e-09 * math.Cos(4.04424043223+536.8045120954*t) result += 1.91e-09 * math.Cos(3.14082686083+16723.350142595*t) result += 2.22e-09 * math.Cos(5.16263907319+23539.7073863328*t) result += 1.8e-09 * math.Cos(4.56214752149+6489.2613984286*t) result += 2.19e-09 * math.Cos(0.80382553358+16627.3709153772*t) result += 2.27e-09 * math.Cos(0.60156339452+5905.7022420756*t) result += 1.68e-09 * math.Cos(0.88753528161+16062.1845261168*t) result += 1.58e-09 * math.Cos(0.92127725775+23937.856389741*t) result += 1.57e-09 * math.Cos(4.69607868164+6805.6532680852*t) result += 2.07e-09 * math.Cos(4.88410451334+6286.6662786432*t) result += 1.6e-09 * math.Cos(4.95943826846+10021.8372800994*t) result += 1.66e-09 * math.Cos(0.97126433565+3097.88382272579*t) result += 2.09e-09 * math.Cos(5.75663411805+3646.3503773544*t) result += 1.75e-09 * math.Cos(6.12762824412+239424.390254353*t) result += 1.73e-09 * math.Cos(3.13887234973+6179.9830757728*t) result += 1.57e-09 * math.Cos(3.62822058179+18451.078546566*t) result += 1.57e-09 * math.Cos(4.67695912235+6709.6740408674*t) result += 1.46e-09 * math.Cos(3.09506069735+4907.3020501456*t) result += 1.65e-09 * math.Cos(2.2713912876+10660.6869350424*t) result += 2.01e-09 * math.Cos(1.67701267433+2107.0345075424*t) result += 1.44e-09 * math.Cos(3.96947747592+6019.9919266186*t) result += 1.71e-09 * math.Cos(5.91302216729+6058.7310542895*t) result += 1.44e-09 * math.Cos(2.1315565512+26084.0218062162*t) result += 1.51e-09 * math.Cos(0.67417383554+2388.8940204492*t) result += 1.89e-09 * math.Cos(5.07122281033+263.0839233728*t) result += 1.46e-09 * math.Cos(5.10373877968+10770.8932562618*t) result += 1.87e-09 * math.Cos(1.23915444627+19402.7969528166*t) result += 1.74e-09 * math.Cos(0.08407293391+9380.9596727172*t) result += 1.37e-09 * math.Cos(1.26247412309+12566.2190102856*t) result += 1.37e-09 * math.Cos(3.52826010842+639.897286314*t) result += 1.48e-09 * math.Cos(1.76124372592+5888.4499649322*t) result += 1.64e-09 * math.Cos(2.39195095081+6357.8574485587*t) result += 1.46e-09 * math.Cos(2.43675816553+5881.4037282342*t) result += 1.61e-09 * math.Cos(1.15721259372+26735.9452622132*t) result += 1.31e-09 * math.Cos(2.51859277344+6599.467719648*t) result += 1.53e-09 * math.Cos(5.85203687779+6281.5913772831*t) result += 1.51e-09 * math.Cos(3.72338532649+12669.2444742014*t) result += 1.32e-09 * math.Cos(2.38417741883+6525.8044539654*t) result += 1.29e-09 * math.Cos(0.75556744143+5017.508371365*t) result += 1.27e-09 * math.Cos(0.00254936441+10027.9031957292*t) result += 1.48e-09 * math.Cos(2.85102145528+6418.1409300268*t) result += 1.43e-09 * math.Cos(5.74460279367+26087.9031415742*t) result += 1.72e-09 * math.Cos(0.4128996224+174242.46596405*t) result += 1.36e-09 * math.Cos(4.15497742275+6311.5250374592*t) result += 1.7e-09 * math.Cos(5.98194913129+327574.514276781*t) result += 1.24e-09 * math.Cos(1.65497607604+32217.2001810808*t) result += 1.36e-09 * math.Cos(2.48430783417+13341.6743113068*t) result += 1.65e-09 * math.Cos(2.496679246+58953.145443294*t) result += 1.23e-09 * math.Cos(3.45660563754+6277.552925684*t) result += 1.17e-09 * math.Cos(0.86065134175+6245.0481773556*t) result += 1.49e-09 * math.Cos(5.61358280963+5729.506447149*t) result += 1.53e-09 * math.Cos(0.2686002995+245.8316462294*t) result += 1.28e-09 * math.Cos(0.71204006588+103.0927742186*t) result += 1.59e-09 * math.Cos(2.43166592149+221995.028801495*t) result += 1.3e-09 * math.Cos(2.80707316718+6016.4688082696*t) result += 1.37e-09 * math.Cos(1.70657709294+12566.08438968*t) result += 1.11e-09 * math.Cos(1.56305648432+17782.7320727842*t) result += 1.13e-09 * math.Cos(3.58302904101+25685.872802808*t) result += 1.09e-09 * math.Cos(3.26403795962+6819.8803620868*t) result += 1.22e-09 * math.Cos(0.34120688217+1162.4747044078*t) result += 1.19e-09 * math.Cos(5.84644718278+12721.572099417*t) result += 1.44e-09 * math.Cos(2.28899679126+12489.8856287072*t) result += 1.37e-09 * math.Cos(5.82029768354+44809.6502008634*t) result += 1.07e-09 * math.Cos(2.4281854414+5547.1993364596*t) result += 1.34e-09 * math.Cos(1.26539982939+5331.3574437408*t) result += 1.03e-09 * math.Cos(5.96518130595+6321.1035226272*t) result += 1.09e-09 * math.Cos(0.33808549034+11300.5842213564*t) result += 1.29e-09 * math.Cos(5.89187277327+12029.3471878874*t) result += 1.22e-09 * math.Cos(5.77325634636+11919.140866668*t) result += 1.07e-09 * math.Cos(6.2499898935+77690.7595057385*t) result += 1.07e-09 * math.Cos(1.00535580713+77736.7834305025*t) result += 1.43e-09 * math.Cos(0.24122178432+4214.0690150848*t) result += 1.43e-09 * math.Cos(0.88529649733+7576.560073574*t) result += 1.07e-09 * math.Cos(2.92124030496+31415.379249957*t) result += 9.9e-10 * math.Cos(5.70862227072+5540.0857894588*t) result += 1.1e-09 * math.Cos(0.37528037383+5863.5912061162*t) result += 1.04e-09 * math.Cos(4.44107178366+2118.7638603784*t) result += 9.8e-10 * math.Cos(5.95877916706+4061.2192153944*t) result += 1.13e-09 * math.Cos(1.24206857385+84672.4758445047*t) result += 1.24e-09 * math.Cos(2.55619029867+12539.853380183*t) result += 1.1e-09 * math.Cos(3.66952094329+238004.524157236*t) result += 1.12e-09 * math.Cos(4.32512422943+97238.6275444875*t) result += 9.7e-10 * math.Cos(3.70151541181+11720.0688652316*t) result += 1.2e-09 * math.Cos(1.26895630252+12043.574281889*t) result += 9.4e-10 * math.Cos(2.56461130309+19004.6479494084*t) result += 1.17e-09 * math.Cos(3.65425622684+34520.3093093808*t) result += 9.8e-10 * math.Cos(0.13589994287+11080.1715789176*t) result += 9.7e-10 * math.Cos(5.38330115253+7834.1210726394*t) result += 9.7e-10 * math.Cos(2.46722096722+71980.6335747312*t) result += 9.5e-10 * math.Cos(5.36958330451+6288.5987742988*t) result += 1.11e-09 * math.Cos(5.01961920313+11823.1616394502*t) result += 9e-10 * math.Cos(2.72299804525+26880.3198130326*t) result += 9.9e-10 * math.Cos(0.90164266377+18635.9284545362*t) result += 1.26e-09 * math.Cos(4.78722177847+305281.943071049*t) result += 9.3e-10 * math.Cos(0.21240380046+18139.2945014159*t) result += 1.24e-09 * math.Cos(5.00979495566+172146.97134054*t) result += 9.9e-10 * math.Cos(5.67090026475+16522.6597160022*t) result += 9.2e-10 * math.Cos(2.28180963676+12491.3701014155*t) result += 9e-10 * math.Cos(4.50544881196+40077.61957352*t) result += 1e-09 * math.Cos(2.00639461612+12323.4230960088*t) result += 9.5e-10 * math.Cos(5.68801979087+14919.0178537546*t) result += 8.7e-10 * math.Cos(1.86043406047+27707.5424942948*t) result += 1.05e-09 * math.Cos(3.02903468417+22345.2603761082*t) result += 8.7e-10 * math.Cos(5.43970168638+6272.0301497275*t) result += 8.9e-10 * math.Cos(1.63389387182+33326.5787331742*t) result += 8.2e-10 * math.Cos(5.58298993353+10241.2022911672*t) result += 9.4e-10 * math.Cos(5.47749711149+9924.8104215106*t) result += 8.2e-10 * math.Cos(4.71988314145+15141.390794312*t) result += 9.7e-10 * math.Cos(5.61458778738+2787.0430238574*t) result += 9.6e-10 * math.Cos(3.89073946348+6379.0550772092*t) result += 8.1e-10 * math.Cos(3.13038482444+36147.4098773004*t) result += 1.1e-09 * math.Cos(4.89978492291+72140.6286666874*t) result += 9.7e-10 * math.Cos(5.20764563059+6303.4311693902*t) result += 8.2e-10 * math.Cos(5.26342716139+9814.6041002912*t) result += 1.09e-09 * math.Cos(2.3555558977+83286.9142695536*t) result += 9.7e-10 * math.Cos(2.58492958057+30666.1549584328*t) result += 9.3e-10 * math.Cos(1.32651591333+23020.653086588*t) result += 7.8e-10 * math.Cos(3.99588630754+11293.4706743556*t) result += 9e-10 * math.Cos(0.57771932738+26482.1708096244*t) result += 1.06e-09 * math.Cos(3.92012705073+62883.3551395136*t) result += 9.8e-10 * math.Cos(2.94397773524+316.3918696566*t) result += 7.6e-10 * math.Cos(3.96310417608+29026.4852295078*t) result += 7.8e-10 * math.Cos(1.97068529306+90279.9231681033*t) result += 7.6e-10 * math.Cos(0.23027966596+21424.4666443034*t) result += 8e-10 * math.Cos(2.23099742212+266.6070417218*t) result += 7.9e-10 * math.Cos(1.46227790922+8982.810669309*t) result += 1.02e-09 * math.Cos(4.92129953565+5621.8429232104*t) result += 1e-09 * math.Cos(0.39243148321+24279.1070182136*t) result += 7.1e-10 * math.Cos(1.52014858474+33794.5437235286*t) result += 7.6e-10 * math.Cos(0.22880641443+57375.8019008462*t) result += 9.1e-10 * math.Cos(0.96515913904+48739.859897083*t) result += 7.5e-10 * math.Cos(2.77638585157+12964.300703391*t) result += 7.7e-10 * math.Cos(5.18846946344+11520.9968637952*t) result += 6.8e-10 * math.Cos(0.50006599129+4274.5183108324*t) result += 7.5e-10 * math.Cos(2.07323762803+15664.0355227086*t) result += 7.4e-10 * math.Cos(1.01884134928+6393.2821712108*t) result += 7.7e-10 * math.Cos(0.4666517878+16207.886271502*t) result += 8.1e-10 * math.Cos(4.10452219483+161710.618786232*t) result += 6.7e-10 * math.Cos(3.83840630887+6262.7205305926*t) result += 7.1e-10 * math.Cos(3.91415523291+7875.6718636242*t) result += 8.1e-10 * math.Cos(0.91938383237+74.7815985673*t) result += 8.3e-10 * math.Cos(4.69916218791+23006.4259925864*t) result += 6.3e-10 * math.Cos(2.32556465878+6279.1945146334*t) result += 6.5e-10 * math.Cos(5.41938745446+28628.3362260996*t) result += 6.5e-10 * math.Cos(3.02336771694+5959.570433334*t) result += 6.4e-10 * math.Cos(3.3103319837+2636.725472637*t) result += 6.4e-10 * math.Cos(0.18375587519+1066.49547719*t) result += 8e-10 * math.Cos(5.81239171612+12341.8069042809*t) result += 6.6e-10 * math.Cos(2.15105504851+38.0276726358*t) result += 6.2e-10 * math.Cos(2.43313614978+10138.1095169486*t) result += 6e-10 * math.Cos(3.1615390647+5490.300961524*t) result += 6.9e-10 * math.Cos(0.30764736334+7018.9523635232*t) result += 6.8e-10 * math.Cos(2.24442548639+24383.0791084414*t) result += 7.8e-10 * math.Cos(1.39649386463+9411.4646150872*t) result += 6.3e-10 * math.Cos(0.72976362625+6286.9571853494*t) result += 7.3e-10 * math.Cos(4.95125917731+6453.7487206106*t) result += 7.8e-10 * math.Cos(0.32736023459+6528.9074962208*t) result += 5.9e-10 * math.Cos(4.95362151577+35707.7100829074*t) result += 7e-10 * math.Cos(2.37962727525+15508.6151232744*t) result += 7.3e-10 * math.Cos(1.35229143111+5327.4761083828*t) result += 7.2e-10 * math.Cos(5.91833527334+10881.0995774812*t) result += 5.9e-10 * math.Cos(5.36231868425+10239.5838660108*t) result += 5.9e-10 * math.Cos(1.63156134967+61306.0115970658*t) result += 5.4e-10 * math.Cos(4.29491690425+21947.1113727*t) result += 5.7e-10 * math.Cos(5.89190132575+34513.2630726828*t) result += 7.4e-10 * math.Cos(1.38235845304+9967.4538999816*t) result += 5.3e-10 * math.Cos(3.86543309344+32370.9789915656*t) result += 5.5e-10 * math.Cos(4.51794544854+34911.412076091*t) result += 6.3e-10 * math.Cos(5.41479412056+11502.8376165305*t) result += 6.3e-10 * math.Cos(2.34416220742+11510.7019230567*t) result += 6.8e-10 * math.Cos(0.77493931112+29864.334027309*t) result += 6e-10 * math.Cos(5.57024703495+5756.9080032458*t) result += 7.2e-10 * math.Cos(2.80863088166+10866.8724834796*t) result += 6.1e-10 * math.Cos(2.69736991384+82576.9812209953*t) result += 6.3e-10 * math.Cos(5.32068807257+3116.6594122598*t) result += 5.2e-10 * math.Cos(1.02278758099+6272.4391846416*t) result += 6.9e-10 * math.Cos(5.00698550308+25287.7237993998*t) result += 6.6e-10 * math.Cos(6.12047940728+12074.488407524*t) result += 5.1e-10 * math.Cos(2.59519527563+11396.5634485742*t) result += 5.6e-10 * math.Cos(2.57995973521+17892.9383940036*t) result += 5.9e-10 * math.Cos(0.4416723762+250570.675857219*t) result += 5.9e-10 * math.Cos(3.84070143543+5483.254724826*t) result += 4.9e-10 * math.Cos(0.54704693048+22594.054895712*t) result += 6.5e-10 * math.Cos(2.38423614501+52670.0695933026*t) result += 6.9e-10 * math.Cos(5.34363738671+66813.5648357332*t) result += 5.7e-10 * math.Cos(5.42770501007+310145.152823924*t) result += 5.3e-10 * math.Cos(1.17760296075+149.5631971346*t) result += 6.1e-10 * math.Cos(4.02090887211+34596.3646546524*t) result += 4.9e-10 * math.Cos(4.18361320516+18606.4989460002*t) result += 5.5e-10 * math.Cos(0.83886167974+20452.8694122218*t) result += 5e-10 * math.Cos(1.46327331958+37455.7264959744*t) result += 4.8e-10 * math.Cos(4.53854727167+29822.7832363242*t) result += 5.8e-10 * math.Cos(3.34847975377+33990.6183442862*t) result += 6.5e-10 * math.Cos(1.45522693982+76251.3277706202*t) result += 5.6e-10 * math.Cos(2.35650663692+37724.7534197482*t) result += 5.2e-10 * math.Cos(2.61551081496+5999.2165311262*t) result += 5.3e-10 * math.Cos(0.17334326094+77717.2945864695*t) result += 5.3e-10 * math.Cos(0.79879700631+77710.2483497715*t) result += 4.7e-10 * math.Cos(0.43240779709+735.8765135318*t) result += 5.3e-10 * math.Cos(4.58763261686+11616.976091013*t) result += 4.8e-10 * math.Cos(6.20230111054+4171.4255366138*t) result += 5.2e-10 * math.Cos(1.09723616404+640.8776073822*t) result += 5.7e-10 * math.Cos(3.42008310383+50317.2034395308*t) result += 5.3e-10 * math.Cos(1.01528448581+149144.46708625*t) result += 4.7e-10 * math.Cos(3.00924906195+52175.8062831484*t) result += 5.2e-10 * math.Cos(2.03254070404+6293.7125153412*t) result += 4.8e-10 * math.Cos(0.12356889734+13362.4497067992*t) result += 4.5e-10 * math.Cos(3.37963782356+10763.779709261*t) result += 4.7e-10 * math.Cos(5.50981287869+12779.4507954208*t) result += 6.2e-10 * math.Cos(5.45209070099+949.1756089698*t) result += 6.1e-10 * math.Cos(2.93237974631+5791.4125575326*t) result += 4.4e-10 * math.Cos(2.87440620802+8584.6616659008*t) result += 4.6e-10 * math.Cos(4.0314179656+10667.8004820432*t) result += 4.7e-10 * math.Cos(3.89902931422+3903.9113764198*t) result += 4.6e-10 * math.Cos(2.75700467329+6993.0088985497*t) result += 4.5e-10 * math.Cos(1.933862933+206.1855484372*t) result += 4.7e-10 * math.Cos(2.57670800912+11492.542675792*t) result += 4.4e-10 * math.Cos(3.62570223167+63658.8777508376*t) result += 5.1e-10 * math.Cos(0.84536826273+12345.739057544*t) result += 4.3e-10 * math.Cos(0.01524970172+37853.8754993826*t) result += 4.1e-10 * math.Cos(3.27146326065+8858.3149443206*t) result += 4.5e-10 * math.Cos(3.03765521215+65236.2212932854*t) result += 4.7e-10 * math.Cos(1.44447548944+21393.5419698576*t) result += 5.8e-10 * math.Cos(5.45843180927+1975.492545856*t) result += 5e-10 * math.Cos(2.13285524146+12573.2652469836*t) result += 4.1e-10 * math.Cos(1.32190847146+2547.8375382324*t) result += 4.7e-10 * math.Cos(3.67579608544+28313.288804661*t) result += 4.1e-10 * math.Cos(2.24013475126+8273.8208670324*t) result += 4.7e-10 * math.Cos(6.21438985953+10991.3058987006*t) result += 4.2e-10 * math.Cos(3.0163181735+853.196381752*t) result += 5.6e-10 * math.Cos(1.09773690181+77376.2010224076*t) result += 4e-10 * math.Cos(2.35698541041+2699.7348193176*t) result += 4.3e-10 * math.Cos(5.28030898459+17796.9591667858*t) result += 5.4e-10 * math.Cos(2.59175932091+22910.4467653686*t) result += 5.4e-10 * math.Cos(0.88027764102+71960.3865832237*t) result += 5.5e-10 * math.Cos(0.07988899477+83467.1563530173*t) result += 3.9e-10 * math.Cos(1.12867321442+9910.583327509*t) result += 4e-10 * math.Cos(1.35670430524+27177.8515292002*t) result += 3.9e-10 * math.Cos(4.39624220245+5618.3198048614*t) result += 4.2e-10 * math.Cos(4.78798367468+7856.89627409019*t) result += 4.7e-10 * math.Cos(2.75482175292+18202.2167166594*t) result += 3.9e-10 * math.Cos(1.97008298629+24491.4257925834*t) result += 4.2e-10 * math.Cos(4.04346599946+7863.9425107882*t) result += 3.8e-10 * math.Cos(0.49178679251+38650.173506199*t) result += 3.6e-10 * math.Cos(4.86047906533+4157.1984426122*t) result += 4.3e-10 * math.Cos(5.64354880978+1062.9050485382*t) result += 3.6e-10 * math.Cos(3.98066313627+12565.1713789146*t) result += 4.2e-10 * math.Cos(2.30753932657+6549.6828917132*t) result += 4e-10 * math.Cos(5.3969491832+9498.2122306346*t) result += 4e-10 * math.Cos(3.30603243754+23536.116957681*t) result += 5e-10 * math.Cos(6.15760345261+78051.3419138334*t) return result } func GetEarthR1(t float64) float64 { var result float64 = 0.0 result += 0.00103018608 * math.Cos(1.10748969588+6283.0758499914*t) result += 1.721238e-05 * math.Cos(1.06442301418+12566.1516999828*t) result -= -7.02215e-06 result += 3.2346e-07 * math.Cos(1.02169059149+18849.2275499742*t) result += 3.0799e-07 * math.Cos(2.84353804832+5507.5532386674*t) result += 2.4971e-07 * math.Cos(1.31906709482+5223.6939198022*t) result += 1.8485e-07 * math.Cos(1.42429748614+1577.3435424478*t) result += 1.0078e-07 * math.Cos(5.91378194648+10977.078804699*t) result += 8.634e-08 * math.Cos(0.27146150602+5486.777843175*t) result += 8.654e-08 * math.Cos(1.42046854427+6275.9623029906*t) result += 5.069e-08 * math.Cos(1.68613426734+5088.6288397668*t) result += 4.985e-08 * math.Cos(6.01401770704+6286.5989683404*t) result += 4.669e-08 * math.Cos(5.98724494073+529.6909650946*t) result += 4.395e-08 * math.Cos(0.51800238019+4694.0029547076*t) result += 3.872e-08 * math.Cos(4.74969833437+2544.3144198834*t) result += 3.75e-08 * math.Cos(5.07097685568+796.2980068164*t) result += 4.1e-08 * math.Cos(1.08424786092+9437.762934887*t) result += 3.518e-08 * math.Cos(0.02290216272+83996.8473181119*t) result += 3.436e-08 * math.Cos(0.94937019624+71430.6956181291*t) result += 3.221e-08 * math.Cos(6.15628775313+2146.1654164752*t) result += 3.414e-08 * math.Cos(5.41218322538+775.522611324*t) result += 2.863e-08 * math.Cos(5.48432847146+10447.3878396044*t) result += 2.52e-08 * math.Cos(0.24276941146+398.1490034082*t) result += 2.201e-08 * math.Cos(4.95216196651+6812.766815086*t) result += 2.186e-08 * math.Cos(0.41991743105+8031.0922630584*t) result += 2.838e-08 * math.Cos(3.42034351366+2352.8661537718*t) result += 2.554e-08 * math.Cos(6.13241878525+6438.4962494256*t) result += 1.932e-08 * math.Cos(5.31374608366+8429.2412664666*t) result += 2.429e-08 * math.Cos(3.09164528262+4690.4798363586*t) result += 1.73e-08 * math.Cos(1.5368620855+4705.7323075436*t) result += 2.25e-08 * math.Cos(3.68863633842+7084.8967811152*t) result += 2.093e-08 * math.Cos(1.28191783032+1748.016413067*t) result += 1.441e-08 * math.Cos(0.81656250862+14143.4952424306*t) result += 1.483e-08 * math.Cos(3.22225357771+7234.794256242*t) result += 1.754e-08 * math.Cos(3.22883705112+6279.5527316424*t) result += 1.583e-08 * math.Cos(4.09702349428+11499.6562227928*t) result += 1.575e-08 * math.Cos(5.53890170575+3154.6870848956*t) result += 1.847e-08 * math.Cos(1.82040335363+7632.9432596502*t) result += 1.504e-08 * math.Cos(3.63293385726+11513.8833167944*t) result += 1.337e-08 * math.Cos(4.64440864339+6836.6452528338*t) result += 1.275e-08 * math.Cos(2.69341415363+1349.8674096588*t) result += 1.352e-08 * math.Cos(6.15101580257+5746.271337896*t) result += 1.125e-08 * math.Cos(3.35673439497+17789.845619785*t) result += 1.47e-08 * math.Cos(3.65282991755+1194.4470102246*t) result += 1.177e-08 * math.Cos(2.57676109092+13367.9726311066*t) result += 1.101e-08 * math.Cos(4.49748696552+4292.3308329504*t) result += 1.234e-08 * math.Cos(5.65036509521+5760.4984318976*t) result += 9.84e-09 * math.Cos(0.65517395136+5856.4776591154*t) result += 9.28e-09 * math.Cos(2.32420318751+10213.285546211*t) result += 1.077e-08 * math.Cos(5.82812169132+12036.4607348882*t) result += 9.16e-09 * math.Cos(0.76613009583+16730.4636895958*t) result += 8.77e-09 * math.Cos(1.50137505051+11926.2544136688*t) result += 1.023e-08 * math.Cos(5.62076589825+6256.7775301916*t) result += 8.51e-09 * math.Cos(0.65709335533+155.4203994342*t) result += 8.02e-09 * math.Cos(4.10519132088+951.7184062506*t) result += 8.57e-09 * math.Cos(1.41661697538+5753.3848848968*t) result += 9.94e-09 * math.Cos(1.14418521187+1059.3819301892*t) result += 8.13e-09 * math.Cos(1.63948433322+6681.2248533996*t) result += 6.62e-09 * math.Cos(4.5520045226+5216.5803728014*t) result += 6.44e-09 * math.Cos(4.19478168733+6040.3472460174*t) result += 6.26e-09 * math.Cos(1.50767713598+5643.1785636774*t) result += 5.9e-09 * math.Cos(6.18277145205+4164.311989613*t) result += 6.35e-09 * math.Cos(0.52413263542+6290.1893969922*t) result += 6.5e-09 * math.Cos(0.9793569035+25132.3033999656*t) result += 5.68e-09 * math.Cos(2.30125315873+10973.55568635*t) result += 5.47e-09 * math.Cos(5.27256412213+3340.6124266998*t) result += 5.47e-09 * math.Cos(2.20144422886+1592.5960136328*t) result += 5.26e-09 * math.Cos(0.92464258226+11371.7046897582*t) result += 4.9e-09 * math.Cos(5.90951388655+3894.1818295422*t) result += 4.78e-09 * math.Cos(1.66857963179+12168.0026965746*t) result += 5.16e-09 * math.Cos(3.59803483887+10969.9652576982*t) result += 5.18e-09 * math.Cos(3.97914412373+17298.1823273262*t) result += 5.34e-09 * math.Cos(5.03740926442+9917.6968745098*t) result += 4.87e-09 * math.Cos(2.50545369269+6127.6554505572*t) result += 4.16e-09 * math.Cos(4.04828175503+10984.1923516998*t) result += 5.38e-09 * math.Cos(5.54081539805+553.5694028424*t) result += 4.02e-09 * math.Cos(2.16544019233+7860.4193924392*t) result += 5.53e-09 * math.Cos(2.32177369366+11506.7697697936*t) result += 3.67e-09 * math.Cos(3.3915253225+6496.3749454294*t) result += 3.6e-09 * math.Cos(5.34379853282+7079.3738568078*t) result += 3.37e-09 * math.Cos(3.61563704045+11790.6290886588*t) result += 4.56e-09 * math.Cos(0.30754294809+801.8209311238*t) result += 4.17e-09 * math.Cos(3.70009308674+10575.4066829418*t) result += 3.81e-09 * math.Cos(5.82033971802+7058.5984613154*t) result += 3.21e-09 * math.Cos(0.31988767355+16200.7727245012*t) result += 3.64e-09 * math.Cos(1.08414306177+6309.3741697912*t) result += 2.94e-09 * math.Cos(4.54798604957+11856.2186514245*t) result += 2.9e-09 * math.Cos(1.26473978562+8635.9420037632*t) result += 3.99e-09 * math.Cos(4.16998866302+26.2983197998*t) result += 2.62e-09 * math.Cos(5.08316906342+10177.2576795336*t) result += 2.43e-09 * math.Cos(2.2574609119+11712.9553182308*t) result += 2.37e-09 * math.Cos(1.05070575346+242.728603974*t) result += 2.75e-09 * math.Cos(3.45319481756+5884.9268465832*t) result += 2.55e-09 * math.Cos(5.38496831087+21228.3920235458*t) result += 3.07e-09 * math.Cos(4.24313526604+3738.761430108*t) result += 2.16e-09 * math.Cos(3.46037894728+213.299095438*t) result += 1.96e-09 * math.Cos(0.69029243914+1990.745017041*t) result += 1.98e-09 * math.Cos(5.16301829964+12352.8526045448*t) result += 2.14e-09 * math.Cos(3.91876200279+13916.0191096416*t) result += 2.12e-09 * math.Cos(4.00861198517+5230.807466803*t) result += 1.84e-09 * math.Cos(5.59805976614+6283.14316029419*t) result += 1.84e-09 * math.Cos(2.85275392124+7238.6755916*t) result += 1.79e-09 * math.Cos(2.54259058334+14314.1681130498*t) result += 2.25e-09 * math.Cos(1.64458698399+4732.0306273434*t) result += 2.36e-09 * math.Cos(5.58826125715+6069.7767545534*t) result += 1.87e-09 * math.Cos(2.72805985443+6062.6632075526*t) result += 1.84e-09 * math.Cos(6.04216273598+6283.0085396886*t) result += 2.3e-09 * math.Cos(3.62591335086+6284.0561710596*t) result += 1.63e-09 * math.Cos(2.19117396803+18073.7049386502*t) result += 1.72e-09 * math.Cos(0.9761295074+3930.2096962196*t) result += 2.15e-09 * math.Cos(1.04672844028+3496.032826134*t) result += 1.69e-09 * math.Cos(4.75084479006+17267.2682016912*t) result += 1.52e-09 * math.Cos(0.19390712179+9779.1086761254*t) result += 1.82e-09 * math.Cos(5.16288118255+17253.0411076896*t) result += 1.49e-09 * math.Cos(0.8094418426+709.9330485583*t) result += 1.63e-09 * math.Cos(2.1920957039+6076.8903015542*t) result += 1.86e-09 * math.Cos(5.01159497089+11015.1064773348*t) result += 1.34e-09 * math.Cos(0.97765485759+65147.6197681377*t) result += 1.41e-09 * math.Cos(4.38421981312+4136.9104335162*t) result += 1.58e-09 * math.Cos(4.60974280627+9623.6882766912*t) result += 1.33e-09 * math.Cos(3.30508592837+154717.609887683*t) result += 1.63e-09 * math.Cos(6.11782626245+3.523118349*t) result += 1.74e-09 * math.Cos(1.58078542187+7.1135470008*t) result += 1.41e-09 * math.Cos(0.49976927274+25158.6017197654*t) result += 1.24e-09 * math.Cos(6.03440460031+9225.539273283*t) result += 1.5e-09 * math.Cos(5.30166336812+13517.8701062334*t) result += 1.27e-09 * math.Cos(1.92389511438+22483.8485744926*t) result += 1.21e-09 * math.Cos(2.37813129011+167283.761587666*t) result += 1.2e-09 * math.Cos(3.98423684853+4686.8894077068*t) result += 1.17e-09 * math.Cos(5.81072642211+12569.6748183318*t) result += 1.22e-09 * math.Cos(5.60973054224+5642.1982426092*t) result += 1.57e-09 * math.Cos(3.40236426002+16496.3613962024*t) result += 1.29e-09 * math.Cos(2.10705116371+1589.0728952838*t) result += 1.16e-09 * math.Cos(0.55839966736+5849.3641121146*t) result += 1.23e-09 * math.Cos(1.52961392771+12559.038152982*t) result += 1.11e-09 * math.Cos(0.44848279675+6172.869528772*t) result += 1.23e-09 * math.Cos(5.81645568991+6282.0955289232*t) result += 1.5e-09 * math.Cos(4.26278409223+3128.3887650958*t) result += 1.06e-09 * math.Cos(2.27437761356+5429.8794682394*t) result += 1.04e-09 * math.Cos(4.42743707728+23543.2305046818*t) result += 1.21e-09 * math.Cos(0.39459045915+12132.439962106*t) result += 1.04e-09 * math.Cos(2.41842602527+426.598190876*t) result += 1.1e-09 * math.Cos(5.80381480447+16858.4825329332*t) result += 1e-09 * math.Cos(2.93805577485+4535.0594369244*t) result += 9.7e-10 * math.Cos(3.97935904984+6133.5126528568*t) result += 1.1e-09 * math.Cos(6.22339014386+12146.6670561076*t) result += 9.8e-10 * math.Cos(0.87576563709+6525.8044539654*t) result += 9.8e-10 * math.Cos(3.15248421301+10440.2742926036*t) result += 9.5e-10 * math.Cos(2.461684111+3097.88382272579*t) result += 8.8e-10 * math.Cos(0.23371480284+13119.7211028252*t) result += 9.8e-10 * math.Cos(5.77016493489+7342.4577801806*t) result += 9.2e-10 * math.Cos(6.03915555063+20426.571092422*t) result += 9.6e-10 * math.Cos(5.56909292561+2388.8940204492*t) result += 8.1e-10 * math.Cos(1.32131147691+5650.2921106782*t) result += 8.6e-10 * math.Cos(3.94529200528+10454.5013866052*t) result += 7.6e-10 * math.Cos(2.70729716925+143571.324284816*t) result += 9.1e-10 * math.Cos(5.64100034152+8827.3902698748*t) result += 7.6e-10 * math.Cos(1.80783856698+28286.9904848612*t) result += 8.1e-10 * math.Cos(1.90858992196+29088.811415985*t) result += 7.5e-10 * math.Cos(3.40955892978+5481.2549188676*t) result += 6.9e-10 * math.Cos(4.49936170873+17256.6315363414*t) result += 8.8e-10 * math.Cos(1.10098454357+11769.8536931664*t) result += 6.6e-10 * math.Cos(2.78285801977+536.8045120954*t) result += 6.8e-10 * math.Cos(3.88179770758+17260.1546546904*t) result += 8.4e-10 * math.Cos(1.59303306354+9380.9596727172*t) result += 8.8e-10 * math.Cos(3.88076636762+7477.522860216*t) result += 6.1e-10 * math.Cos(6.17558202197+11087.2851259184*t) result += 6e-10 * math.Cos(4.34824715818+6206.8097787158*t) result += 8.2e-10 * math.Cos(4.59843208943+9388.0059094152*t) result += 7.9e-10 * math.Cos(1.63131230601+4933.2084403326*t) result += 7.8e-10 * math.Cos(4.20905757484+5729.506447149*t) result += 5.7e-10 * math.Cos(5.48157926651+18319.5365848796*t) result += 6e-10 * math.Cos(1.01261781084+12721.572099417*t) result += 5.6e-10 * math.Cos(1.63031935692+15720.8387848784*t) result += 5.5e-10 * math.Cos(0.24926735018+15110.4661198662*t) result += 6.1e-10 * math.Cos(5.93059279661+12539.853380183*t) result += 5.5e-10 * math.Cos(4.84298966314+13095.8426650774*t) result += 6.7e-10 * math.Cos(6.11690589247+8662.240323563*t) result += 5.4e-10 * math.Cos(5.73750638571+3634.6210245184*t) result += 7.4e-10 * math.Cos(1.05466745829+16460.333529525*t) result += 5.3e-10 * math.Cos(2.29084335688+16062.1845261168*t) result += 6.4e-10 * math.Cos(2.13513767927+7875.6718636242*t) result += 6.7e-10 * math.Cos(0.07096807518+14945.3161735544*t) result += 5.1e-10 * math.Cos(2.31511194429+6262.7205305926*t) result += 5.7e-10 * math.Cos(5.77055471237+12043.574281889*t) result += 5.6e-10 * math.Cos(4.41980790431+4701.1165017084*t) result += 5.9e-10 * math.Cos(5.87963500073+5331.3574437408*t) result += 5.8e-10 * math.Cos(2.30546168628+955.5997416086*t) result += 4.9e-10 * math.Cos(1.93839278478+5333.9002410216*t) result += 4.8e-10 * math.Cos(2.69973662261+6709.6740408674*t) result += 6.4e-10 * math.Cos(1.64379897981+6262.300454499*t) result += 4.6e-10 * math.Cos(3.98449608961+98068.5367163054*t) result += 5e-10 * math.Cos(3.68875893005+12323.4230960088*t) result += 4.5e-10 * math.Cos(3.30068569697+22003.9146348698*t) result += 4.7e-10 * math.Cos(1.26317154881+11919.140866668*t) result += 4.5e-10 * math.Cos(0.89150445122+51868.2486621788*t) result += 4.3e-10 * math.Cos(1.61526242998+6277.552925684*t) result += 4.3e-10 * math.Cos(5.74295325645+11403.676995575*t) result += 4.4e-10 * math.Cos(3.43070646822+10021.8372800994*t) result += 5.6e-10 * math.Cos(0.02481833774+15671.0817594066*t) result += 5.5e-10 * math.Cos(3.14274403422+33019.0211122046*t) result += 4.5e-10 * math.Cos(3.00877289177+8982.810669309*t) result += 4.6e-10 * math.Cos(0.73303568429+6303.4311693902*t) result += 4.9e-10 * math.Cos(1.60455690285+6303.8512454838*t) result += 4.5e-10 * math.Cos(0.40210030323+6805.6532680852*t) result += 5.3e-10 * math.Cos(0.94869680175+10988.808157535*t) result += 4.1e-10 * math.Cos(1.61122384329+6819.8803620868*t) result += 5.5e-10 * math.Cos(0.89439119424+11933.3679606696*t) result += 4.5e-10 * math.Cos(3.88495384656+60530.4889857418*t) result += 4e-10 * math.Cos(4.75740908001+38526.574350872*t) result += 4e-10 * math.Cos(1.49921251887+18451.078546566*t) result += 4e-10 * math.Cos(3.77498297228+26087.9031415742*t) result += 5.1e-10 * math.Cos(1.70258603562+1551.045222648*t) result += 3.9e-10 * math.Cos(2.97100699926+2118.7638603784*t) result += 5.3e-10 * math.Cos(5.19854123078+77713.7714681205*t) result += 4.7e-10 * math.Cos(4.26356628717+21424.4666443034*t) result += 3.7e-10 * math.Cos(0.62902722802+24356.7807886416*t) result += 3.6e-10 * math.Cos(0.11087914947+10344.2950653858*t) result += 3.6e-10 * math.Cos(0.77037556319+12029.3471878874*t) result += 3.5e-10 * math.Cos(3.30933994515+24072.9214697764*t) result += 3.5e-10 * math.Cos(5.93650887012+31570.7996493912*t) result += 3.6e-10 * math.Cos(2.15108874765+30774.5016425748*t) result += 3.6e-10 * math.Cos(1.75078825382+16207.886271502*t) result += 3.3e-10 * math.Cos(5.06264177921+226858.23855437*t) result += 3.4e-10 * math.Cos(6.168913788+24491.4257925834*t) result += 3.5e-10 * math.Cos(3.19120695549+32217.2001810808*t) result += 3.4e-10 * math.Cos(2.31528650443+55798.4583583984*t) result += 3.2e-10 * math.Cos(4.21446357042+15664.0355227086*t) result += 3.9e-10 * math.Cos(1.24979117796+6418.1409300268*t) result += 3.7e-10 * math.Cos(4.1194365577+2787.0430238574*t) result += 3.2e-10 * math.Cos(1.6288771089+639.897286314*t) result += 3.8e-10 * math.Cos(5.89832942685+640.8776073822*t) result += 3.2e-10 * math.Cos(1.72442327688+27433.889215875*t) result += 3.1e-10 * math.Cos(2.78828943753+12139.5535091068*t) result += 3.5e-10 * math.Cos(4.44608896525+18202.2167166594*t) result += 3.4e-10 * math.Cos(3.96287980676+18216.443810661*t) result += 3.3e-10 * math.Cos(4.73611335874+16723.350142595*t) result += 3.4e-10 * math.Cos(1.43910280005+49515.382508407*t) result += 3.1e-10 * math.Cos(0.23302920161+23581.2581773176*t) result += 2.9e-10 * math.Cos(2.0263384022+11609.8625440122*t) result += 3e-10 * math.Cos(2.5492323024+9924.8104215106*t) result += 3.2e-10 * math.Cos(4.91793198558+11300.5842213564*t) result += 2.8e-10 * math.Cos(0.26187189577+13521.7514415914*t) result += 2.8e-10 * math.Cos(3.84568936822+2699.7348193176*t) result += 2.9e-10 * math.Cos(1.83149729794+29822.7832363242*t) result += 3.3e-10 * math.Cos(4.60320094415+19004.6479494084*t) result += 2.7e-10 * math.Cos(4.46183450287+6702.5604938666*t) result += 3e-10 * math.Cos(4.4649407224+36147.4098773004*t) result += 2.7e-10 * math.Cos(0.03211931363+6279.7894925736*t) result += 2.6e-10 * math.Cos(5.46497324333+6245.0481773556*t) result += 3.5e-10 * math.Cos(4.52695674113+36949.2308084242*t) result += 2.7e-10 * math.Cos(3.52528177609+10770.8932562618*t) result += 2.6e-10 * math.Cos(1.48499438453+11080.1715789176*t) result += 3.5e-10 * math.Cos(2.82154380962+19402.7969528166*t) result += 2.5e-10 * math.Cos(2.46339998836+6279.4854213396*t) result += 2.6e-10 * math.Cos(4.97688894643+16737.5772365966*t) result += 2.6e-10 * math.Cos(2.36136541526+17996.0311682222*t) result += 2.9e-10 * math.Cos(4.15148654061+45892.730433157*t) result += 2.6e-10 * math.Cos(4.50714272714+17796.9591667858*t) result += 2.7e-10 * math.Cos(4.72625223674+1066.49547719*t) result += 2.5e-10 * math.Cos(2.89309528854+6286.6662786432*t) result += 2.7e-10 * math.Cos(0.37462444357+12964.300703391*t) result += 2.9e-10 * math.Cos(4.94860010533+5863.5912061162*t) result += 3.1e-10 * math.Cos(3.93096113577+29864.334027309*t) result += 2.4e-10 * math.Cos(6.14987193584+18606.4989460002*t) result += 2.4e-10 * math.Cos(3.74225964547+29026.4852295078*t) result += 2.5e-10 * math.Cos(5.70460621565+27707.5424942948*t) result += 2.5e-10 * math.Cos(5.33928840652+15141.390794312*t) result += 2.7e-10 * math.Cos(3.0232089714+6286.3622074092*t) result += 2.3e-10 * math.Cos(0.28364955406+5327.4761083828*t) result += 2.6e-10 * math.Cos(1.34240461687+18875.525869774*t) result += 2.4e-10 * math.Cos(1.33998410121+19800.9459562248*t) result += 2.5e-10 * math.Cos(6.00172494004+6489.2613984286*t) result += 2.2e-10 * math.Cos(1.81777974484+6288.5987742988*t) result += 2.2e-10 * math.Cos(3.5860360664+6915.8595893046*t) result += 2.9e-10 * math.Cos(2.09564449439+15265.8865193004*t) result += 2.2e-10 * math.Cos(1.02173599251+11925.2740926006*t) result += 2.2e-10 * math.Cos(4.74660932338+28230.1872226914*t) result += 2.1e-10 * math.Cos(2.30688751432+5999.2165311262*t) result += 2.1e-10 * math.Cos(3.2265494443+25934.1243310894*t) result += 2.1e-10 * math.Cos(3.04956726238+6566.9351688566*t) result += 2.7e-10 * math.Cos(5.35653084499+33794.5437235286*t) result += 2.8e-10 * math.Cos(3.91168324815+18208.349942592*t) result += 2e-10 * math.Cos(1.52296293311+135.0650800354*t) result += 2.2e-10 * math.Cos(4.66462839521+13362.4497067992*t) result += 1.9e-10 * math.Cos(1.78121167862+156137.475984799*t) result += 1.9e-10 * math.Cos(2.99969102221+19651.048481098*t) result += 1.9e-10 * math.Cos(2.86664273362+18422.6293590982*t) result += 2.5e-10 * math.Cos(0.94995632141+31415.379249957*t) result += 1.9e-10 * math.Cos(4.71432851499+77690.7595057385*t) result += 1.9e-10 * math.Cos(2.54227398241+77736.7834305025*t) result += 2e-10 * math.Cos(5.91915117116+48739.859897083*t) return result } func GetEarthR2(t float64) float64 { var result float64 = 0.0 result += 4.359385e-05 * math.Cos(5.78455133738+6283.0758499914*t) result += 1.23633e-06 * math.Cos(5.57934722157+12566.1516999828*t) result -= -1.2341e-07 result += 8.792e-08 * math.Cos(3.62777733395+77713.7714681205*t) result += 5.689e-08 * math.Cos(1.86958905084+5573.1428014331*t) result += 3.301e-08 * math.Cos(5.47027913302+18849.2275499742*t) result += 1.471e-08 * math.Cos(4.48028885617+5507.5532386674*t) result += 1.013e-08 * math.Cos(2.81456417694+5223.6939198022*t) result += 8.54e-09 * math.Cos(3.10878241236+1577.3435424478*t) result += 1.102e-08 * math.Cos(2.84173992403+161000.685737674*t) result += 6.48e-09 * math.Cos(5.47349498544+775.522611324*t) result += 6.09e-09 * math.Cos(1.37969434104+6438.4962494256*t) result += 4.99e-09 * math.Cos(4.4164924225+6286.5989683404*t) result += 4.17e-09 * math.Cos(0.90242451175+10977.078804699*t) result += 4.02e-09 * math.Cos(3.2037658529+5088.6288397668*t) result += 3.51e-09 * math.Cos(1.8107922777+5486.777843175*t) result += 4.67e-09 * math.Cos(3.65753702738+7084.8967811152*t) result += 4.58e-09 * math.Cos(5.38585314743+149854.400134808*t) result += 3.04e-09 * math.Cos(3.51701098693+796.2980068164*t) result += 2.66e-09 * math.Cos(6.17413982699+6836.6452528338*t) result += 2.79e-09 * math.Cos(1.84120501086+4694.0029547076*t) result += 2.6e-09 * math.Cos(1.41629543251+2146.1654164752*t) result += 2.66e-09 * math.Cos(3.13832905677+71430.6956181291*t) result += 3.21e-09 * math.Cos(5.35313367048+3154.6870848956*t) result += 2.38e-09 * math.Cos(2.17720020018+155.4203994342*t) result += 2.93e-09 * math.Cos(4.61501268144+4690.4798363586*t) result += 2.29e-09 * math.Cos(4.7596958807+7234.794256242*t) result += 2.11e-09 * math.Cos(0.21868065485+4705.7323075436*t) result += 2.01e-09 * math.Cos(4.21905743357+1349.8674096588*t) result += 1.95e-09 * math.Cos(4.57808285364+529.6909650946*t) result += 2.53e-09 * math.Cos(2.81496293039+1748.016413067*t) result += 1.82e-09 * math.Cos(5.70454011389+6040.3472460174*t) result += 1.79e-09 * math.Cos(6.02897097053+4292.3308329504*t) result += 1.86e-09 * math.Cos(1.58690991244+6309.3741697912*t) result += 1.7e-09 * math.Cos(2.90220009715+9437.762934887*t) result += 1.66e-09 * math.Cos(1.99984925026+8031.0922630584*t) result += 1.58e-09 * math.Cos(0.04783713552+2544.3144198834*t) result += 1.97e-09 * math.Cos(2.01083639502+1194.4470102246*t) result += 1.65e-09 * math.Cos(5.78372596778+83996.8473181119*t) result += 2.14e-09 * math.Cos(3.38285934319+7632.9432596502*t) result += 1.4e-09 * math.Cos(0.36401486094+10447.3878396044*t) result += 1.51e-09 * math.Cos(0.95153163031+6127.6554505572*t) result += 1.36e-09 * math.Cos(1.48426306582+2352.8661537718*t) result += 1.27e-09 * math.Cos(5.48475435134+951.7184062506*t) result += 1.26e-09 * math.Cos(5.26866506592+6279.5527316424*t) result += 1.25e-09 * math.Cos(3.75754889288+6812.766815086*t) result += 1.01e-09 * math.Cos(4.95015746147+398.1490034082*t) result += 1.02e-09 * math.Cos(0.68468295277+1592.5960136328*t) result += 1e-09 * math.Cos(1.14568935785+3894.1818295422*t) result += 1.29e-09 * math.Cos(0.76540016965+553.5694028424*t) result += 1.09e-09 * math.Cos(5.41063597567+6256.7775301916*t) result += 7.5e-10 * math.Cos(5.84804322893+242.728603974*t) result += 9.5e-10 * math.Cos(1.94452244083+11856.2186514245*t) result += 7.7e-10 * math.Cos(0.69373708195+8429.2412664666*t) result += 1e-09 * math.Cos(5.19725292131+244287.600007228*t) result += 8e-10 * math.Cos(6.18440483705+1059.3819301892*t) result += 6.9e-10 * math.Cos(5.25699888595+14143.4952424306*t) result += 8.5e-10 * math.Cos(5.39484725499+25132.3033999656*t) result += 6.6e-10 * math.Cos(0.51779993906+801.8209311238*t) result += 5.5e-10 * math.Cos(5.16878202461+7058.5984613154*t) result += 5.1e-10 * math.Cos(3.88759155247+12036.4607348882*t) result += 5e-10 * math.Cos(5.57636570536+6290.1893969922*t) result += 6.1e-10 * math.Cos(2.24359003264+8635.9420037632*t) result += 5e-10 * math.Cos(5.54441900966+1990.745017041*t) result += 5.6e-10 * math.Cos(4.0030107804+13367.9726311066*t) result += 5.2e-10 * math.Cos(4.13138898038+7860.4193924392*t) result += 5.2e-10 * math.Cos(3.90943054011+26.2983197998*t) result += 4.1e-10 * math.Cos(3.5712848278+7079.3738568078*t) result += 5.6e-10 * math.Cos(2.76959005761+90955.5516944961*t) result += 4.2e-10 * math.Cos(1.91461189199+7477.522860216*t) result += 4.2e-10 * math.Cos(0.42728171713+10213.285546211*t) result += 4.2e-10 * math.Cos(1.09413724455+709.9330485583*t) result += 3.9e-10 * math.Cos(3.93298068961+10973.55568635*t) result += 3.8e-10 * math.Cos(6.17935925345+9917.6968745098*t) result += 4.9e-10 * math.Cos(0.83021145241+11506.7697697936*t) result += 5.3e-10 * math.Cos(1.45828359397+233141.314404362*t) result += 4.7e-10 * math.Cos(6.21568666789+6681.2248533996*t) result += 3.7e-10 * math.Cos(0.3635930998+10177.2576795336*t) result += 3.5e-10 * math.Cos(3.33024911524+5643.1785636774*t) result += 3.4e-10 * math.Cos(5.63446915337+6525.8044539654*t) result += 3.5e-10 * math.Cos(5.36033855038+25158.6017197654*t) result += 3.4e-10 * math.Cos(5.36319798321+4933.2084403326*t) result += 3.3e-10 * math.Cos(4.24722336872+12569.6748183318*t) result += 4.3e-10 * math.Cos(5.26370903404+10575.4066829418*t) result += 4.2e-10 * math.Cos(5.08837645072+11015.1064773348*t) result += 4e-10 * math.Cos(1.98334703186+6284.0561710596*t) result += 4.2e-10 * math.Cos(4.22496037505+88860.0570709867*t) result += 2.9e-10 * math.Cos(3.1908862817+11926.2544136688*t) result += 2.9e-10 * math.Cos(0.15217616684+12168.0026965746*t) result += 3e-10 * math.Cos(1.61904744136+9779.1086761254*t) result += 2.7e-10 * math.Cos(0.76388991416+1589.0728952838*t) result += 3.6e-10 * math.Cos(2.74712003443+3738.761430108*t) result += 3.3e-10 * math.Cos(3.08807829566+3930.2096962196*t) result += 3.1e-10 * math.Cos(5.34906619513+143571.324284816*t) result += 2.5e-10 * math.Cos(0.10240267494+22483.8485744926*t) result += 3e-10 * math.Cos(3.47110495524+14945.3161735544*t) result += 2.4e-10 * math.Cos(1.10425016019+4535.0594369244*t) result += 2.4e-10 * math.Cos(1.5803725978+6496.3749454294*t) result += 2.3e-10 * math.Cos(3.87710321433+6275.9623029906*t) result += 2.5e-10 * math.Cos(3.9452977897+3128.3887650958*t) result += 2.3e-10 * math.Cos(3.44685609601+4136.9104335162*t) result += 2.3e-10 * math.Cos(3.83156029849+5753.3848848968*t) result += 2.2e-10 * math.Cos(1.86956128067+16730.4636895958*t) result += 2.5e-10 * math.Cos(2.42188933855+5729.506447149*t) result += 2e-10 * math.Cos(1.78208352927+17789.845619785*t) result += 2.1e-10 * math.Cos(4.303630874+16858.4825329332*t) result += 2.1e-10 * math.Cos(0.49258939822+29088.811415985*t) result += 2.5e-10 * math.Cos(1.33030250444+6282.0955289232*t) result += 2.7e-10 * math.Cos(2.54785812264+3496.032826134*t) result += 2.2e-10 * math.Cos(1.1123252195+12721.572099417*t) result += 2.1e-10 * math.Cos(5.97759081637+7.1135470008*t) result += 1.9e-10 * math.Cos(0.80292033311+16062.1845261168*t) result += 2.3e-10 * math.Cos(4.12454848769+2388.8940204492*t) result += 2.2e-10 * math.Cos(4.92663152168+18875.525869774*t) result += 2.3e-10 * math.Cos(5.68902059771+16460.333529525*t) result += 2.3e-10 * math.Cos(4.97346265647+17260.1546546904*t) result += 2.3e-10 * math.Cos(3.03021283729+66567.4858652543*t) result += 1.6e-10 * math.Cos(3.89740925257+5331.3574437408*t) result += 1.7e-10 * math.Cos(3.08268671348+154717.609887683*t) result += 1.6e-10 * math.Cos(3.95085099736+3097.88382272579*t) result += 1.6e-10 * math.Cos(3.99041783945+6283.14316029419*t) result += 2e-10 * math.Cos(6.10644140189+167283.761587666*t) result += 1.5e-10 * math.Cos(4.09775914607+11712.9553182308*t) result += 1.6e-10 * math.Cos(5.717699407+17298.1823273262*t) result += 1.6e-10 * math.Cos(3.28894009404+5884.9268465832*t) result += 1.5e-10 * math.Cos(5.64785377164+12559.038152982*t) result += 1.6e-10 * math.Cos(4.4345208093+6283.0085396886*t) result += 1.4e-10 * math.Cos(2.31721603062+5481.2549188676*t) result += 1.4e-10 * math.Cos(4.43479032305+13517.8701062334*t) result += 1.4e-10 * math.Cos(4.73209312936+7342.4577801806*t) result += 1.2e-10 * math.Cos(0.64705975463+18073.7049386502*t) result += 1.1e-10 * math.Cos(1.514433322+16200.7727245012*t) result += 1.1e-10 * math.Cos(0.88708889185+21228.3920235458*t) result += 1.4e-10 * math.Cos(4.50116508534+640.8776073822*t) result += 1.1e-10 * math.Cos(4.64339996198+11790.6290886588*t) result += 1.1e-10 * math.Cos(1.31064298246+4164.311989613*t) result += 9e-11 * math.Cos(3.02238989305+23543.2305046818*t) result += 9e-11 * math.Cos(2.04999402381+22003.9146348698*t) result += 9e-11 * math.Cos(4.91488110218+213.299095438*t) return result } func GetEarthR3(t float64) float64 { var result float64 = 0.0 result += 1.44595e-06 * math.Cos(4.27319435148+6283.0758499914*t) result += 6.729e-08 * math.Cos(3.91697608662+12566.1516999828*t) result += 7.74e-09 result += 2.47e-09 * math.Cos(3.73019298781+18849.2275499742*t) result += 3.6e-10 * math.Cos(2.8008140905+6286.5989683404*t) result += 3.3e-10 * math.Cos(5.62216602775+6127.6554505572*t) result += 1.9e-10 * math.Cos(3.71292621802+6438.4962494256*t) result += 1.6e-10 * math.Cos(4.26011484232+6525.8044539654*t) result += 1.6e-10 * math.Cos(3.50416887054+6256.7775301916*t) result += 1.4e-10 * math.Cos(3.62127621114+25132.3033999656*t) result += 1.1e-10 * math.Cos(4.39200958819+4705.7323075436*t) result += 1.1e-10 * math.Cos(5.22327127059+6040.3472460174*t) result += 1e-10 * math.Cos(4.28045254647+83996.8473181119*t) result += 9e-11 * math.Cos(1.56864096494+5507.5532386674*t) result += 1.1e-10 * math.Cos(1.37795688024+6309.3741697912*t) result += 1e-10 * math.Cos(5.19937959068+71430.6956181291*t) result += 9e-11 * math.Cos(0.4727519993+6279.5527316424*t) result += 9e-11 * math.Cos(0.74642756529+5729.506447149*t) result += 7e-11 * math.Cos(2.9737489156+775.522611324*t) result += 7e-11 * math.Cos(3.28615691021+7058.5984613154*t) result += 7e-11 * math.Cos(2.19184402142+6812.766815086*t) result += 5e-11 * math.Cos(3.15419034438+529.6909650946*t) result += 6e-11 * math.Cos(4.54725567047+1059.3819301892*t) result += 5e-11 * math.Cos(1.51104406936+7079.3738568078*t) result += 7e-11 * math.Cos(2.98052059053+6681.2248533996*t) result += 5e-11 * math.Cos(2.30961231391+12036.4607348882*t) result += 5e-11 * math.Cos(3.71102966917+6290.1893969922*t) return result } func GetEarthR4(t float64) float64 { var result float64 = 0.0 result += 3.858e-08 * math.Cos(2.56384387339+6283.0758499914*t) result += 3.06e-09 * math.Cos(2.2676950123+12566.1516999828*t) result += 5.3e-10 * math.Cos(3.44031471924+5573.1428014331*t) result += 1.5e-10 * math.Cos(2.04794573436+18849.2275499742*t) result += 1.3e-10 * math.Cos(2.05688873673+77713.7714681205*t) result += 7e-11 * math.Cos(4.4121885448+161000.685737674*t) result += 5e-11 * math.Cos(5.26154653107+6438.4962494256*t) result += 5e-11 * math.Cos(4.07695126049+6127.6554505572*t) result += 6e-11 * math.Cos(3.81514213664+149854.400134808*t) result += 3e-11 * math.Cos(1.28175749811+6286.5989683404*t) return result } func GetEarthR5(t float64) float64 { var result float64 = 0.0 result += 8.6e-10 * math.Cos(1.21579741687+6283.0758499914*t) result += 1.2e-10 * math.Cos(0.65617264033+12566.1516999828*t) result += 1e-11 * math.Cos(0.38068797142+18849.2275499742*t) return result } go-lib-5.6.0.9/calendar/lunar/vsop87earthd_test.go000664 000000 000000 00000004642 13753517240 021655 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package lunar import ( "pkg.deepin.io/lib/calendar/util" "testing" ) //行星日心黄经(L)、日心黄纬(B)和到太阳的距离(R) // L0~5 B0~4 // func GetEarthL0 (t float64) float64 { // func GetEarthL1 (t float64) float64 { // func GetEarthL2 (t float64) float64 { // func GetEarthL3 (t float64) float64 { // func GetEarthL4 (t float64) float64 { // func GetEarthL5 (t float64) float64 { // func GetEarthB0 (t float64) float64 { // func GetEarthB1 (t float64) float64 { // func GetEarthB2 (t float64) float64 { // func GetEarthB3 (t float64) float64 { // func GetEarthB4 (t float64) float64 { func Test_GetEarthXX(te *testing.T) { const t = 1.2345 L0 := GetEarthL0(t) L1 := GetEarthL1(t) L2 := GetEarthL2(t) L3 := GetEarthL3(t) L4 := GetEarthL4(t) L5 := GetEarthL5(t) te.Log(L0) te.Log(L1) te.Log(L2) te.Log(L3) te.Log(L4) te.Log(L5) B0 := GetEarthB0(t) B1 := GetEarthB1(t) B2 := GetEarthB2(t) B3 := GetEarthB3(t) B4 := GetEarthB4(t) te.Log(B0) te.Log(B1) te.Log(B2) te.Log(B3) te.Log(B4) R0 := GetEarthR0(t) R1 := GetEarthR1(t) R2 := GetEarthR2(t) R3 := GetEarthR3(t) R4 := GetEarthR4(t) R5 := GetEarthR5(t) te.Log(R0) te.Log(R1) te.Log(R2) te.Log(R3) te.Log(R4) te.Log("R5 = ", R5) } func Test_GetSunEclipticLongitudeForEarth(t *testing.T) { jd := util.ToJulianDateHMS(2016, 2, 16, 6, 6, 6.0) L := GetSunEclipticLongitudeForEarth(jd) t.Log(L) } func Test_GetSunEclipticLatitudeForEarth(t *testing.T) { jd := util.ToJulianDateHMS(2016, 2, 16, 6, 6, 6.0) B := GetSunEclipticLatitudeForEarth(jd) t.Log(B) } func Test_GetSunRadiusForEarth(t *testing.T) { jd := util.ToJulianDateHMS(2016, 2, 16, 6, 6, 6.0) R := GetSunRadiusForEarth(jd) t.Log(R) } go-lib-5.6.0.9/calendar/util/000775 000000 000000 00000000000 13753517240 015557 5ustar00rootroot000000 000000 go-lib-5.6.0.9/calendar/util/julianday.go000664 000000 000000 00000005102 13753517240 020064 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package util import ( "math" "time" ) // GetDateFromJulianDay 从儒略日中获取公历的日期 func GetDateFromJulianDay(jd float64) (yy, mm, dd int) { /* * This algorithm is taken from * "Numerical Recipes in c, 2nd Ed." (1992), pp. 14-15 * and converted to integer math. * The electronic version of the book is freely available * at http://www.nr.com/ , under "Obsolete Versions - Older * book and code versions. */ const JD_GREG_CAL = 2299161 const JB_MAX_WITHOUT_OVERFLOW = 107374182 julian := int64(math.Floor(jd + 0.5)) var ta, jalpha, tb, tc, td, te int64 if julian >= JD_GREG_CAL { jalpha = (4*(julian-1867216) - 1) / 146097 ta = int64(julian) + 1 + jalpha - jalpha/4 } else if julian < 0 { ta = julian + 36525*(1-julian/36525) } else { ta = julian } tb = ta + 1524 if tb <= JB_MAX_WITHOUT_OVERFLOW { tc = (tb*20 - 2442) / 7305 } else { tc = int64((uint64(tb)*20 - 2442) / 7305) } td = 365*tc + tc/4 te = ((tb - td) * 10000) / 306001 dd = int(tb - td - (306001*te)/10000) mm = int(te - 1) if mm > 12 { mm -= 12 } yy = int(tc - 4715) if mm > 2 { yy-- } if julian < 0 { yy -= int(100 * (1 - julian/36525)) } return } // GetTimeFromJulianDay 从儒略日中获取时间 时分秒 func GetTimeFromJulianDay(jd float64) (hour, minute, second int) { frac := jd - math.Floor(jd) s := int(math.Floor(frac * 24.0 * 60.0 * 60.0)) hour = ((s / (60 * 60)) + 12) % 24 minute = (s / (60)) % 60 second = s % 60 return } // GetDateTimeFromJulianDay 将儒略日转换为 time.Time // 其中包含了 TT 到 UTC 的转换 func GetDateTimeFromJulianDay(jd float64) time.Time { yy, mm, _ := GetDateFromJulianDay(jd) // TT -> UTC jd -= GetDeltaT(yy, mm) / 86400 yy, mm, dd := GetDateFromJulianDay(jd) h, m, s := GetTimeFromJulianDay(jd) return time.Date(yy, time.Month(mm), dd, h, m, s, 0, time.UTC) } go-lib-5.6.0.9/calendar/util/julianday_test.go000664 000000 000000 00000003206 13753517240 021126 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package util import ( "testing" ) func Test_GetDateFromJulianDay(t *testing.T) { y, m, d := GetDateFromJulianDay(2457438.0) t.Log(y, m, d) if y == 2016 && m == 2 && d == 19 { t.Log("ok") } else { t.Error("fail") } y, m, d = GetDateFromJulianDay(2248528.0) t.Log(y, m, d) if y == 1444 && m == 2 && d == 19 { t.Log("ok") } else { t.Error("fail") } } func Test_GetTimeFromJulianDay(t *testing.T) { h, m, s := GetTimeFromJulianDay(2457438.09546) t.Log(h, m, s) if h == 14 && m == 17 && s == 27 { t.Log("ok") } else { t.Error("fail") } h, m, s = GetTimeFromJulianDay(2457438.09851) t.Log(h, m, s) if h == 14 && m == 21 && s == 51 { t.Log("ok") } else { t.Error("fail") } } func Test_GetDateTimeFromJulianDay(t *testing.T) { dt := GetDateTimeFromJulianDay(2457438.10454) t.Log(dt) if dt.String() == "2016-02-19 14:29:22 +0000 UTC" { t.Log("ok") } else { t.Error("fail") } } go-lib-5.6.0.9/calendar/util/util.go000664 000000 000000 00000012631 13753517240 017066 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package util // IsLeapYear 公历闰年判断 func IsLeapYear(year int) bool { return (year&3) == 0 && year%100 != 0 || year%400 == 0 } var monthDays = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // GetSolarMonthDays 获取公历月份的天数 func GetSolarMonthDays(year, month int) int { if month == 2 && IsLeapYear(year) { return 29 } else { return monthDays[month-1] } } // GetYearDaysCount 获取某年的天数 func GetYearDaysCount(year int) int { if IsLeapYear(year) { return 366 } return 365 } // ToJulianDate 计算Gregorian日期的儒略日数,以TT当天中午12点为准(结果是整数)。 // 算法摘自 http://en.wikipedia.org/wiki/Julian_day func ToJulianDate(year, month, day int) int { var a int = (14 - month) / 12 var y int = year + 4800 - a var m int = month + 12*a - 3 return day + (153*m+2)/5 + 365*y + y/4 - y/100 + y/400 - 32045 } // ToJulianDateHMS 计算Gregorian时间的儒略日数 // 算法摘自 http://en.wikipedia.org/wiki/Julian_day func ToJulianDateHMS(year, month, day, hour, minute int, second float64) float64 { jdn := ToJulianDate(year, month, day) return float64(jdn) + (float64(hour)-12)/24.0 + float64(minute)/1440.0 + second/86400.0 } // Gregorian历TT2000年1月1日中午12点的儒略日 const J2000 = 2451545.0 // GetJulianThousandYears 计算儒略千年数 func GetJulianThousandYears(jd float64) float64 { //1000年的日数 const DaysOf1000Years = 365250.0 return (jd - J2000) / DaysOf1000Years } // GetJulianCentury 计算儒略世纪数 func GetJulianCentury(jd float64) float64 { // 100年的日数 const DaysOfCentury = 36525.0 return (jd - J2000) / DaysOfCentury } // GetWeekday 计算Gregorian日历的星期几 // 算法摘自 http://en.wikipedia.org/wiki/Zeller%27s_congruence // 返回星期几的数字表示,1-6表示星期一到星期六,0表示星期日 func GetWeekday(y, m, d int) int { if m <= 2 { y -= 1 m += 12 } c := int(y / 100) y = y % 100 w := (d + 13*(m+1)/5 + y + (y / 4) + (c / 4) - 2*c - 1) % 7 if w < 0 { w += 7 } return w } // GetDeltaT 计算地球时和UTC的时差,算法摘自 // http://eclipse.gsfc.nasa.gov/SEhelp/deltatpoly2004.html NASA网站 // ∆T = TT - UT 此算法在-1999年到3000年有效 func GetDeltaT(year, month int) float64 { y := float64(year) + (float64(month)-0.5)/12 switch { case year < -500: u := (float64(year) - 1820) / 100 return -20 + 32*u*u case year < 500: u := y / 100 u2 := u * u u3 := u2 * u u4 := u3 * u u5 := u4 * u u6 := u5 * u return 10583.6 - 1014.41*u + 33.78311*u2 - 5.952053*u3 - 0.1798452*u4 + 0.022174192*u5 + 0.0090316521*u6 case year < 1600: u := (y - 1000) / 100 u2 := u * u u3 := u2 * u u4 := u3 * u u5 := u4 * u u6 := u5 * u return 1574.2 - 556.01*u + 71.23472*u2 + 0.319781*u3 - 0.8503463*u4 - 0.005050998*u5 + 0.0083572073*u6 case year < 1700: t := y - 1600 t2 := t * t t3 := t2 * t return 120 - 0.9808*t - 0.01532*t2 + t3/7129 case year < 1800: t := y - 1700 t2 := t * t t3 := t2 * t t4 := t3 * t return 8.83 + 0.1603*t - 0.0059285*t2 + 0.00013336*t3 - t4/1174000 case year < 1860: t := y - 1800 t2 := t * t t3 := t2 * t t4 := t3 * t t5 := t4 * t t6 := t5 * t t7 := t6 * t return 13.72 - 0.332447*t + 0.0068612*t2 + 0.0041116*t3 - 0.00037436*t4 + 0.0000121272*t5 - 0.0000001699*t6 + 0.000000000875*t7 case year < 1900: t := y - 1860 t2 := t * t t3 := t2 * t t4 := t3 * t t5 := t4 * t return 7.62 + 0.5737*t - 0.251754*t2 + 0.01680668*t3 - 0.0004473624*t4 + t5/233174 case year < 1920: t := y - 1900 t2 := t * t t3 := t2 * t t4 := t3 * t return -2.79 + 1.494119*t - 0.0598939*t2 + 0.0061966*t3 - 0.000197*t4 case year < 1941: t := y - 1920 t2 := t * t t3 := t2 * t return 21.20 + 0.84493*t - 0.076100*t2 + 0.0020936*t3 case year < 1961: t := y - 1950 t2 := t * t t3 := t2 * t return 29.07 + 0.407*t - t2/233 + t3/2547 case year < 1986: t := y - 1975 t2 := t * t t3 := t2 * t return 45.45 + 1.067*t - t2/260 - t3/718 case year < 2005: t := y - 2000 t2 := t * t t3 := t2 * t t4 := t3 * t t5 := t4 * t return 63.86 + 0.3345*t - 0.060374*t2 + 0.0017275*t3 + 0.000651814*t4 + 0.00002373599*t5 case year < 2050: t := y - 2000 t2 := t * t return 62.92 + 0.32217*t + 0.005589*t2 case year < 2150: u := (y - 1820) / 100 u2 := u * u return -20 + 32*u2 - 0.5628*(2150-y) default: u := (y - 1820) / 100 u2 := u * u return -20 + 32*u2 } } // JDUTC2BeijingTime 儒略日 UTC 时间转换到北京时间 func JDUTC2BeijingTime(utcJD float64) float64 { return utcJD + 8.0/24.0 } // JDBeijingTime2UTC 儒略日 北京时间到 UTC 时间 func JDBeijingTime2UTC(bjtJD float64) float64 { return bjtJD - 8.0/24.0 } go-lib-5.6.0.9/calendar/util/util_test.go000664 000000 000000 00000004203 13753517240 020121 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package util import ( "testing" // "time" ) func Test_IsLeapYear(t *testing.T) { if IsLeapYear(1996) && IsLeapYear(2000) && !IsLeapYear(2001) { t.Log("ok") } else { t.Error("fail") } } func Test_GetSolarMonthDays(t *testing.T) { if 31 == GetSolarMonthDays(2001, 1) { t.Log("ok") } else { t.Error("fail") } if 29 == GetSolarMonthDays(2016, 2) { t.Log("ok") } else { t.Error("fail") } if 28 == GetSolarMonthDays(2015, 2) { t.Log("ok") } else { t.Error("fail") } } func Test_ToJulianDate(t *testing.T) { if 2443230 == ToJulianDate(1977, 3, 27) && 2453522 == ToJulianDate(2005, 5, 31) { t.Log("ok") } else { t.Error("fail") } } func Test_ToJulianDateHMS(t *testing.T) { t.Log(ToJulianDateHMS(1977, 3, 27, 6, 6, 6)) if 2.4432297542361114e+06 == ToJulianDateHMS(1977, 3, 27, 6, 6, 6) { t.Log("ok") } else { t.Error("fail") } } func Test_GetJulianThousandYears(t *testing.T) { t.Log(GetJulianThousandYears(2.2324937542361114e+06)) if -0.5997296256369298 == GetJulianThousandYears(2.2324937542361114e+06) { t.Log("ok") } else { t.Error("fail") } } func Test_GetJulianCentury(t *testing.T) { t.Log(GetJulianCentury(2.2324937542361114e+06)) if -5.997296256369297 == GetJulianCentury(2.2324937542361114e+06) { t.Log("ok") } else { t.Error("fail") } } func Test_GetWeekday(t *testing.T) { if 4 == GetWeekday(2015, 1, 1) { t.Log("ok") } else { t.Error("fail") } } go-lib-5.6.0.9/cgroup/000775 000000 000000 00000000000 13753517240 014330 5ustar00rootroot000000 000000 go-lib-5.6.0.9/cgroup/cgroup.go000664 000000 000000 00000062602 13753517240 016164 0ustar00rootroot000000 000000 package cgroup import ( "bufio" "bytes" "errors" "fmt" "io" "io/ioutil" "os" "path/filepath" "strconv" "strings" "syscall" "pkg.deepin.io/lib/log" ) var logger = log.NewLogger("lib/cgroup") const ( Blkio = "blkio" Cpu = "cpu" Cpuacct = "cpuacct" Cpuset = "cpuset" Devices = "devices" Freezer = "freezer" Memory = "memory" NetCLS = "net_cls" NetPrio = "net_prio" PerfEvent = "perf_event" Pids = "pids" ) var initialized bool var mountTable []*MountTableItem type MountTableItem struct { name string mountPoints []string } func (item *MountTableItem) Name() string { return item.name } func (item *MountTableItem) MountPoints() []string { return item.mountPoints } func (item *MountTableItem) addDuplicateMount(path string) { item.mountPoints = append(item.mountPoints, path) } func Init() error { if initialized { return nil } // read /proc/cgroup procCgroupF, err := os.Open("/proc/cgroups") if err != nil { return err } defer procCgroupF.Close() procCgroupRd := bufio.NewReader(procCgroupF) //#subsys_name hierarchy num_cgroups enabled var subsysName string var hierarchy int var numCgroups int var enabled int // discard first line _, err = procCgroupRd.ReadBytes('\n') if err != nil { return err } var controllers []string for { _, err := fmt.Fscanf(procCgroupRd, "%s %d %d %d\n", &subsysName, &hierarchy, &numCgroups, &enabled) if err != nil { if err == io.EOF { break } return err } controllers = append(controllers, subsysName) } logger.Debug("controllers:", controllers) procMountsF, err := os.Open("/proc/mounts") if err != nil { return err } defer procMountsF.Close() procMountsRd := bufio.NewReader(procMountsF) for { mntEnt, err := getMountEntry(procMountsRd) if err != nil { if err == io.EOF { break } return err } if mntEnt.type0 != "cgroup" { continue } for _, controller := range controllers { if mntEnt.hasOpt(controller) == "" { continue } logger.Debugf("found %s in %s", controller, mntEnt.opts) var duplicate bool var mntTableEntry *MountTableItem for _, mntTableEnt := range mountTable { if mntTableEnt.name == controller { duplicate = true mntTableEntry = mntTableEnt break } } if duplicate { logger.Debugf("controller %s is already mounted on %s", controller, mntTableEntry.mountPoints[0]) mntTableEntry.addDuplicateMount(mntEnt.dir) continue } mountTable = append(mountTable, &MountTableItem{ name: controller, mountPoints: []string{mntEnt.dir}, }) logger.Debug("found cgroup option ", mntEnt.opts) } // doesn't match the controller // check if it is a named hierarchy. mntopt := mntEnt.hasOpt("name") if mntopt != "" { var duplicate bool var mntTableEntry *MountTableItem for _, mntTableEnt := range mountTable { if mntTableEnt.name == mntopt { duplicate = true mntTableEntry = mntTableEnt break } } if duplicate { logger.Debugf("controller %s is already mounted on %s", mntopt, mntTableEntry.mountPoints[0]) mntTableEntry.addDuplicateMount(mntEnt.dir) continue } mountTable = append(mountTable, &MountTableItem{ name: mntopt, mountPoints: []string{mntEnt.dir}, }) logger.Debug("found cgroup option ", mntEnt.opts) } } //spew.Dump(mountTable) initialized = true return nil } func panicIfNotInitialized() { if !initialized { panic("lib cgroup is not initialized") } } func GetSubSysMountPoint(controller string) string { panicIfNotInitialized() for _, mountTableItem := range mountTable { if mountTableItem.name == controller { return mountTableItem.mountPoints[0] } } return "" } func GetSubSysMountPoints(controller string) []string { panicIfNotInitialized() for _, mountTableItem := range mountTable { if mountTableItem.name == controller { return mountTableItem.mountPoints } } return nil } type MountEntry struct { fsname string dir string type0 string opts string freq int passno int } func (me *MountEntry) hasOpt(opt string) string { optEqual := opt + "=" opts := strings.Split(me.opts, ",") for _, opt0 := range opts { if opt0 == opt || strings.HasPrefix(opt0, optEqual) { return opt0 } } return "" } func getMountEntry(rd io.Reader) (*MountEntry, error) { // fsname dir type0 opts freq passno var mntent MountEntry _, err := fmt.Fscanf(rd, "%s %s %s %s %d %d\n", &mntent.fsname, &mntent.dir, &mntent.type0, &mntent.opts, &mntent.freq, &mntent.passno) if err != nil { return nil, err } return &mntent, nil } type Cgroup struct { name string controllers []*Controller tasksUid int tasksGid int tasksFilePerm os.FileMode controlUid int controlGid int controlFilePerm os.FileMode controlDirPerm os.FileMode } func NewCgroup(name string) *Cgroup { cg := &Cgroup{ name: name, } cg.init() return cg } const noUidGid = -1 const noPerms = ^os.FileMode(0) func (cg *Cgroup) init() { cg.controlUid = noUidGid cg.controlGid = noUidGid cg.tasksUid = noUidGid cg.tasksGid = noUidGid cg.tasksFilePerm = noPerms cg.controlFilePerm = noPerms cg.controlDirPerm = noPerms } func (cg *Cgroup) Name() string { return cg.name } func (cg *Cgroup) AddController(name string) *Controller { ctl := &Controller{ name: name, cgroup: cg, } cg.controllers = append(cg.controllers, ctl) return ctl } func (cg *Cgroup) GetController(name string) *Controller { for _, ctl := range cg.controllers { if ctl.name == name { return ctl } } return nil } func (cg *Cgroup) NewChildGroup(name string) *Cgroup { child := NewCgroup(filepath.Join(cg.name, name)) child.SetUidGid(cg.GetUidGid()) child.SetPermissions(cg.controlDirPerm, cg.controlFilePerm, cg.tasksFilePerm) for _, ctl := range cg.controllers { child.AddController(ctl.name) } return child } func (cg *Cgroup) NewChildrenGroups(controller string) ([]*Cgroup, error) { childrenNames, err := cg.GetChildren(controller) if err != nil { return nil, err } result := make([]*Cgroup, len(childrenNames)) for idx, name := range childrenNames { result[idx] = cg.NewChildGroup(name) } return result, nil } func (cg *Cgroup) GetChildren(controller string) ([]string, error) { panicIfNotInitialized() if controller == "" { controller = cg.getFirstControllerName() } dir := buildPath(cg.name, controller) fileInfoList, err := ioutil.ReadDir(dir) if err != nil { return nil, err } var result []string for _, fileInfo := range fileInfoList { if fileInfo.IsDir() { result = append(result, fileInfo.Name()) } } return result, nil } func testSubSysMounted(name string) bool { for _, mountTableItem := range mountTable { if mountTableItem.name == name { return true } } return false } var ErrSubSysNotMounted = errors.New("cgroup one of the needed subsystems is not mounted") // Create physically create a control group in kernel. func (cg *Cgroup) Create(ignoreOwnership bool) (err error) { panicIfNotInitialized() for _, ctl := range cg.controllers { if !testSubSysMounted(ctl.name) { return ErrSubSysNotMounted } } for _, ctl := range cg.controllers { path := buildPath(cg.name, ctl.name) base := path if path == "" { continue } err = createControlGroup(path) if err != nil { return err } if !ignoreOwnership { logger.Debug("changing ownership of ", path) err = chownRecursive(path, cg.controlUid, cg.controlGid) if err == nil { err = chmodRecursiveController(path, cg.controlDirPerm, cg.controlDirPerm != noPerms, cg.controlFilePerm, cg.controlFilePerm != noPerms, true, []string{"tasks"}) } } if err != nil { return err } if !ignoreOwnership { path := filepath.Join(base, "tasks") err = chown(path, cg.tasksUid, cg.tasksGid) if err == nil && cg.tasksFilePerm != noPerms { var info os.FileInfo info, err = os.Stat(path) if err == nil { err = chmodPath(path, info, cg.tasksFilePerm, true) } } if err != nil { return err } } } return nil } var ErrCgroupNotMounted = errors.New("cgroup is not mounted") func createControlGroup(path string) error { if !testMountedFs() { return ErrCgroupNotMounted } return os.MkdirAll(path, 0755) } func chownRecursive(path string, owner, group int) error { return filepath.Walk(path, func(path string, info os.FileInfo, err error) error { if err != nil { return nil } err = chown(path, owner, group) if err != nil { logger.Warningf("can not change owner of file %s : %v", path, err) } return nil }) } func chmodRecursiveController(path string, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool, ignoreList []string) error { logger.Debug("chmod: path is ", path) return filepath.Walk(path, func(path string, info os.FileInfo, err error) error { if err != nil { return err } for _, ig := range ignoreList { if ig == path { // ignore return nil } } err = chmodFile(path, info, dirMode, dirModeChange, fileMode, fileModeChange, ownerIsUmask) if err != nil { logger.Warningf("can not change file mode %s: %v", path, err) } return nil }) } func chown(filename string, owner, group int) error { if owner == noUidGid { owner = os.Getuid() } if group == noUidGid { group = os.Getgid() } return os.Chown(filename, owner, group) } func chmodFile(filename string, info os.FileInfo, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool) error { if info.IsDir() { if dirModeChange { return chmodPath(filename, info, dirMode, ownerIsUmask) } } else { if fileModeChange { return chmodPath(filename, info, fileMode, ownerIsUmask) } } return nil } func chmodPath(path string, info os.FileInfo, mode os.FileMode, ownerIsUmask bool) error { mask := ^os.FileMode(0) if ownerIsUmask { var umask, gmask, omask os.FileMode umask = syscall.S_IRWXU & info.Mode() gmask = umask >> 3 omask = umask >> 3 mask = umask | gmask | omask | syscall.S_ISUID | syscall.S_ISGID | syscall.S_ISVTX } return os.Chmod(path, mode&mask) } func testMountedFs() bool { procMountsF, err := os.Open("/proc/mounts") if err != nil { return false } defer procMountsF.Close() procMountsRd := bufio.NewReader(procMountsF) for { mntEnt, err := getMountEntry(procMountsRd) if err != nil { return false } if mntEnt.type0 == "cgroup" { return true } } } func buildPath(name, controller string) string { for _, mountTableItem := range mountTable { if mountTableItem.name == controller { return filepath.Join(mountTableItem.mountPoints[0], name) } } return "" } type DeleteFlags uint const ( DeleteFlagIgnoreMigration = 1 << iota DeleteFlagRecursive DeleteFlagEmptyOnly ) var ErrInvalid = errors.New("invalid operation") func (cg *Cgroup) Delete(flags DeleteFlags) (err error) { panicIfNotInitialized() deleteCgroup := true if (flags&DeleteFlagEmptyOnly != 0) && (flags&DeleteFlagRecursive != 0) { return ErrInvalid } for _, ctl := range cg.controllers { if !testSubSysMounted(ctl.name) { return ErrSubSysNotMounted } } var firstErr error var parentName string for _, ctl := range cg.controllers { if flags&DeleteFlagEmptyOnly == 0 { parentName, err = cg.findParent(ctl.name) if err != nil { continue } if parentName == "" { // root cgroup is being deleted if flags&DeleteFlagRecursive != 0 { // move all tasks to the root group and // do not delete it afterwards. parentName = "." deleteCgroup = false } else { continue } } } var parentTasksF *os.File logger.Debug("parentName is", parentName) if parentName != "" { // tasks need to be moved, pre-open target tasks file parentPath := buildPath(parentName, ctl.name) parentTasksPath := filepath.Join(parentPath, "tasks") parentTasksF, err = os.OpenFile(parentTasksPath, os.O_WRONLY, 0644) if err != nil { logger.Debugf("warnning: can not open file %q: %v", parentTasksPath, err) continue } } if flags&DeleteFlagRecursive != 0 { err = deleteCgroupControllerRecursive(cg.name, ctl.name, parentTasksF, flags, deleteCgroup) } else { err = deleteCgroupController(cg.name, ctl.name, parentTasksF, flags) } if parentTasksF != nil { parentTasksF.Close() } // ErrNonEmpty is more or less not an error, // but an indication that something was not removed. // Therefore it should be replaced by any other error. if err != nil { if firstErr == nil { firstErr = err } else if firstErr == ErrNonEmpty && firstErr != err { firstErr = err } logger.Warningf("failed to remove group %q: %v", ctl.name+":"+cg.name, err) } } return firstErr } var ErrNonEmpty = errors.New("group is not empty") func deleteCgroupController(cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags) (err error) { logger.Debugf("Removing group %s:%s", controller, cgroupName) if flags&DeleteFlagEmptyOnly == 0 { // open tasks file of the group to delete path := filepath.Join(buildPath(cgroupName, controller), "tasks") logger.Debugf("tasks path is %q", path) var deleteTaskF *os.File deleteTaskF, err = os.Open(path) if err == nil { err = moveTaskFiles(deleteTaskF, targetTasksF) if err != nil { logger.Warning("moveTaskFiles err:", err) } deleteTaskF.Close() } else { // can't open the tasks file. if the file does not // exist, ignore it - the group has been already removed. if os.IsNotExist(err) { err = nil } else { logger.Warningf("can not open %q: %v", path, err) } } if err != nil && flags&DeleteFlagIgnoreMigration == 0 { return err } } // remove the group path := buildPath(cgroupName, controller) err = os.Remove(path) if err == nil || os.IsNotExist(err) { return nil } if flags&DeleteFlagEmptyOnly != 0 { if pErr, ok := err.(*os.PathError); ok && pErr.Err == syscall.EBUSY { return ErrNonEmpty } } logger.Warningf("can not remove directory %q:%v", path, err) return err } func moveTaskFiles(inputTasksF, outputTasksF *os.File) error { logger.Debug("move tasks") var tid int for { _, err := fmt.Fscanln(inputTasksF, &tid) if err != nil { if err == io.EOF { break } return err } logger.Debug("moveTaskFiles tid:", tid) _, err = fmt.Fprintln(outputTasksF, tid) if err != nil { return err } } return nil } func deleteCgroupControllerRecursive(cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags, deleteRoot bool) error { logger.Debugf("Recursively removing %s:%s", controller, cgroupName) path := buildPath(cgroupName, controller) fd, err := os.Open(path) if err != nil { if os.IsNotExist(err) { return nil } return err } for { names, err1 := fd.Readdirnames(100) for _, name := range names { cgroupName1 := cgroupName + string(os.PathSeparator) + name p := buildPath(cgroupName1, controller) pStat, err := os.Stat(p) if err != nil { continue } if pStat.IsDir() { _ = deleteCgroupControllerRecursive(cgroupName1, controller, targetTasksF, flags, true) } } if err1 == io.EOF { break } if len(names) == 0 { break } } _ = fd.Close() if deleteRoot { err = deleteCgroupController(cgroupName, controller, targetTasksF, flags) if err != nil { return err } } return nil } func (cg *Cgroup) getParentName() string { dir := cg.name pdir := filepath.Dir(dir) // check for root cgroup if cg.name == "" || cg.name == pdir { logger.Debugf("specified cgroup %q is root cgroup", cg.name) return "" } return pdir } func (cg *Cgroup) findParent(controller string) (string, error) { childPath := buildPath(cg.name, controller) parentPath := filepath.Join(childPath, "..") logger.Debugf("findParent child path: %q", childPath) logger.Debugf("findParent parent path: %q", parentPath) statChild, err := os.Stat(childPath) if err != nil { return "", err } statParent, err := os.Stat(parentPath) if err != nil { return "", err } childDev := statChild.Sys().(*syscall.Stat_t).Dev parentDev := statParent.Sys().(*syscall.Stat_t).Dev if childDev != parentDev { logger.Debug("parent is on different device") return "", nil } return cg.getParentName(), nil } func (cg *Cgroup) AllExist() bool { panicIfNotInitialized() for _, ctl := range cg.controllers { if !ctl.exists() { return false } } return true } func (cg *Cgroup) SetUidGid(tasksUid, tasksGid, controlUid, controlGid int) { cg.tasksUid = tasksUid cg.tasksGid = tasksGid cg.controlUid = controlUid cg.controlGid = controlGid } func (cg *Cgroup) GetUidGid() (int, int, int, int) { return cg.tasksUid, cg.tasksGid, cg.controlUid, cg.controlGid } func (cg *Cgroup) SetPermissions(controlDirPerm, controlFilePerm, tasksFilePerm os.FileMode) { cg.controlDirPerm = controlDirPerm cg.controlFilePerm = controlFilePerm cg.tasksFilePerm = tasksFilePerm } func (cg *Cgroup) AttachCurrentTask() error { return cg.AttachTask(syscall.Gettid()) } func (cg *Cgroup) AttachTask(tid int) error { panicIfNotInitialized() for _, ctl := range cg.controllers { if !testSubSysMounted(ctl.name) { return ErrSubSysNotMounted } } for _, ctl := range cg.controllers { path := buildPath(cg.name, ctl.name) taskPath := filepath.Join(path, "tasks") err := attachTaskProc(taskPath, tid) if err != nil { return err } } return nil } func (cg *Cgroup) AttachCurrentProcess() error { return cg.AttachProcess(os.Getpid()) } func (cg *Cgroup) AttachProcess(pid int) error { panicIfNotInitialized() for _, ctl := range cg.controllers { if !testSubSysMounted(ctl.name) { return ErrSubSysNotMounted } } for _, ctl := range cg.controllers { cgroupProcsFile := filepath.Join(buildPath(cg.name, ctl.name), "cgroup.procs") err := attachTaskProc(cgroupProcsFile, pid) if err != nil { return err } } return nil } func attachTaskProc(path string, tid int) error { taskF, err := os.OpenFile(path, os.O_WRONLY, 0644) if err != nil { return err } defer taskF.Close() _, err = fmt.Fprintln(taskF, tid) if err != nil { return err } return taskF.Sync() } func getIntegers(name, controller, basename string) ([]int, error) { panicIfNotInitialized() filename := filepath.Join(buildPath(name, controller), basename) fh, err := os.Open(filename) if err != nil { return nil, err } defer fh.Close() var ints []int scanner := bufio.NewScanner(fh) for scanner.Scan() { pid, err := strconv.Atoi(scanner.Text()) if err != nil { return nil, err } ints = append(ints, pid) } err = scanner.Err() if err != nil { return nil, err } return ints, nil } func GetTasks(name, controller string) ([]int, error) { return getIntegers(name, controller, "tasks") } func GetProcs(name, controller string) ([]int, error) { return getIntegers(name, controller, "cgroup.procs") } func (cg *Cgroup) GetProcs(controller string) ([]int, error) { if controller == "" { controller = cg.getFirstControllerName() if controller == "" { return nil, errors.New("no controller") } } return GetProcs(cg.name, controller) } func (cg *Cgroup) GetTasks(controller string) ([]int, error) { if controller == "" { controller = cg.getFirstControllerName() if controller == "" { return nil, errors.New("no controller") } } return GetTasks(cg.name, controller) } func (cg *Cgroup) getFirstControllerName() string { for _, ctl := range cg.controllers { return ctl.name } return "" } func GetProcessControllerPath(pid int, controller string) (string, error) { procCgroupFile := fmt.Sprintf("/proc/%d/cgroup", pid) pidCgroupF, err := os.Open(procCgroupFile) if err != nil { return "", err } defer pidCgroupF.Close() scanner := bufio.NewScanner(pidCgroupF) for scanner.Scan() { line := scanner.Bytes() parts := bytes.SplitN(line, []byte{':'}, 3) if len(parts) != 3 { continue } ctlName := string(parts[1]) cgroupPath := string(parts[2]) if ctlName == controller { return cgroupPath, nil } } err = scanner.Err() if err != nil { return "", err } return "", errors.New("controller not found") } type Controller struct { name string cgroup *Cgroup } func (c *Controller) Name() string { return c.name } func (c *Controller) Cgroup() *Cgroup { return c.cgroup } func (c *Controller) Exists() bool { panicIfNotInitialized() return c.exists() } func (c *Controller) exists() bool { path := buildPath(c.cgroup.name, c.name) fileInfo, err := os.Stat(path) if err != nil || !fileInfo.IsDir() { return false } cgroupProcsFile := filepath.Join(path, "cgroup.procs") cgroupProcsFi, err := os.Stat(cgroupProcsFile) if err != nil || cgroupProcsFi.IsDir() { return false } return true } func (c *Controller) getValueFile(name string) string { return filepath.Join(buildPath(c.cgroup.name, c.name), c.name+"."+name) } func (c *Controller) GetValueString(name string) (string, error) { panicIfNotInitialized() filename := c.getValueFile(name) content, err := ioutil.ReadFile(filename) if err != nil { return "", err } return string(content), nil } func (c *Controller) SetValueString(name, value string) error { panicIfNotInitialized() filename := c.getValueFile(name) fh, err := os.OpenFile(filename, os.O_WRONLY, 0644) if err != nil { return err } defer fh.Close() _, err = fh.WriteString(value) if err != nil { return err } return fh.Sync() } func (c *Controller) GetValueInt64(name string) (int64, error) { valStr, err := c.GetValueString(name) if err != nil { return 0, err } return strconv.ParseInt(strings.TrimSpace(valStr), 10, 64) } func (c *Controller) SetValueInt64(name string, value int64) error { valStr := strconv.FormatInt(value, 10) return c.SetValueString(name, valStr) } func (c *Controller) GetValueUint64(name string) (uint64, error) { valStr, err := c.GetValueString(name) if err != nil { return 0, err } return strconv.ParseUint(strings.TrimSpace(valStr), 10, 64) } func (c *Controller) SetValueUint64(name string, value uint64) error { valStr := strconv.FormatUint(value, 10) return c.SetValueString(name, valStr) } func (c *Controller) GetValueBool(name string) (bool, error) { valStr, err := c.GetValueString(name) if err != nil { return false, err } valInt, err := strconv.ParseInt(strings.TrimSpace(valStr), 10, 64) if err != nil { return false, err } return valInt != 0, nil } func (c *Controller) SetValueBool(name string, value bool) error { valStr := "0" if value { valStr = "1" } return c.SetValueString(name, valStr) } func (c *Controller) GetStats(fields []string, args ...*uint64) (int, error) { panicIfNotInitialized() if len(fields) != len(args) { return 0, errors.New("len(fields) != len(args)") } statFile := c.getValueFile("stat") statF, err := os.Open(statFile) if err != nil { return 0, err } defer statF.Close() scanner := bufio.NewScanner(statF) var count int for scanner.Scan() { parts := bytes.Fields(scanner.Bytes()) if len(parts) != 2 { continue } key := string(parts[0]) for i := 0; i < len(fields); i++ { if fields[i] == key { valUint, err := strconv.ParseUint(string(parts[1]), 10, 64) if err != nil { return count, err } *(args[i]) = valUint count++ break } } if count == len(fields) { break } } return count, scanner.Err() } func (c *Controller) GetStatsAll() (map[string]uint64, error) { panicIfNotInitialized() statFile := c.getValueFile("stat") statF, err := os.Open(statFile) if err != nil { return nil, err } defer statF.Close() ret := make(map[string]uint64) scanner := bufio.NewScanner(statF) for scanner.Scan() { parts := bytes.Fields(scanner.Bytes()) if len(parts) != 2 { continue } valUint, err := strconv.ParseUint(string(parts[1]), 10, 64) if err != nil { return nil, err } ret[string(parts[0])] = valUint } err = scanner.Err() if err != nil { return nil, err } return ret, nil } type ControllerInfo struct { name string hierarchy int numCgroups int enabled bool } func (cd *ControllerInfo) Name() string { return cd.name } // Hierarchy is the identification of the controller. Controllers with the same // hierarchy ID are mounted together as one hierarchy. Controllers with ID 0 // are not currently mounted anywhere. func (cd *ControllerInfo) Hierarchy() int { return cd.hierarchy } func (cd *ControllerInfo) NumCgroups() int { return cd.numCgroups } func (cd *ControllerInfo) Enabled() bool { return cd.enabled } // GetAllControllers list all controllers, including those which are not mounted. func GetAllControllers() ([]*ControllerInfo, error) { procCgroupF, err := os.Open("/proc/cgroups") if err != nil { return nil, err } defer procCgroupF.Close() procCgroupRd := bufio.NewReader(procCgroupF) //#subsys_name hierarchy num_cgroups enabled var name string var hierarchy int var numCgroups int var enabled int // discard first line _, err = procCgroupRd.ReadBytes('\n') if err != nil { return nil, err } var controllers []*ControllerInfo for { _, err := fmt.Fscanf(procCgroupRd, "%s %d %d %d\n", &name, &hierarchy, &numCgroups, &enabled) if err != nil { if err == io.EOF { break } return nil, err } var enabledBool bool if enabled != 0 { enabledBool = true } controllers = append(controllers, &ControllerInfo{ name: name, hierarchy: hierarchy, numCgroups: numCgroups, enabled: enabledBool, }) } return controllers, nil } // GetControllers list mounted controllers. func GetControllers() []*MountTableItem { panicIfNotInitialized() return mountTable } go-lib-5.6.0.9/dbusutil/000775 000000 000000 00000000000 13753517240 014664 5ustar00rootroot000000 000000 go-lib-5.6.0.9/dbusutil/_tool/000775 000000 000000 00000000000 13753517240 016000 5ustar00rootroot000000 000000 go-lib-5.6.0.9/dbusutil/_tool/dbusutil-gen/000775 000000 000000 00000000000 13753517240 020402 5ustar00rootroot000000 000000 go-lib-5.6.0.9/dbusutil/_tool/dbusutil-gen/main.go000664 000000 000000 00000015603 13753517240 021662 0ustar00rootroot000000 000000 package main import ( "bytes" "flag" "fmt" "go/ast" "go/format" "go/parser" "go/printer" "go/token" "io/ioutil" "log" "os" "strings" "unicode" "pkg.deepin.io/lib/strv" ) func astNodeToStr(fset *token.FileSet, node interface{}) (string, error) { var buf bytes.Buffer err := printer.Fprint(&buf, fset, node) if err != nil { return "", err } return buf.String(), nil } type Property struct { Name string Type string Equal string } type Generator struct { buf bytes.Buffer pkg Package } func (g *Generator) printf(format string, args ...interface{}) (int, error) { return fmt.Fprintf(&g.buf, format, args...) } const propsMuField = "PropsMu" func (g *Generator) generate() { cmdline := strings.Join(os.Args, " ") g.printf("// Code generated by %q; DO NOT EDIT.\n\n", cmdline) g.printf("package %s\n", g.pkg.name) if len(g.pkg.extraImports) > 0 { g.printf("import (\n") for _, imp := range g.pkg.extraImports { g.printf(imp + "\n") } // end import g.printf(")\n\n") } for typ, props := range g.pkg.typePropMap { for _, prop := range props { // set property method returnVarType := "(changed bool)" if prop.Equal == "nil" { returnVarType = "" } g.printf("func (v *%s) setProp%s(value %s) %s {\n", typ, prop.Name, prop.Type, returnVarType) switch prop.Equal { case "nil": g.printf("v.%s = value\n", prop.Name) g.printf("v.emitPropChanged%s(value)\n", prop.Name) case "": g.printf("if v.%s != value {\n", prop.Name) g.printf(" v.%s = value\n", prop.Name) g.printf(" v.emitPropChanged%s(value)\n", prop.Name) g.printf(" return true\n") g.printf("}\n") g.printf("return false\n") default: expr := fmt.Sprintf("%s(v.%s, value)", prop.Equal, prop.Name) if strings.HasPrefix(prop.Equal, "method:") { method := prop.Equal[len("method:"):] expr = fmt.Sprintf("v.%s.%s(value)", prop.Name, method) } g.printf("if !%s {\n", expr) g.printf(" v.%s = value\n", prop.Name) g.printf(" v.emitPropChanged%s(value)\n", prop.Name) g.printf(" return true\n") g.printf("}\n") g.printf("return false\n") } g.printf("}\n\n") // method emitPropChangedXXX g.printf("func(v *%s) emitPropChanged%s(value %s) error {\n", typ, prop.Name, prop.Type) g.printf(" return v.service.EmitPropertyChanged(v, \"%s\", value)\n", prop.Name) g.printf("}\n\n") } } } type Package struct { name string typePropMap map[string][]Property // ^type name extraImports []string } func (g *Generator) parseFiles(names []string, types strv.Strv) { log.Printf("parseFiles names: %v, types: %v\n", names, types) fs := token.NewFileSet() var typePropMap = make(map[string][]Property) for _, name := range names { if !strings.HasSuffix(name, ".go") { //not go file continue } f, err := parser.ParseFile(fs, name, nil, parser.ParseComments) if err != nil { log.Fatalf("failed to parse file %q: %s", name, err) } ast.Inspect(f, func(node ast.Node) bool { decl, ok := node.(*ast.GenDecl) if !ok || decl.Tok != token.TYPE { return true } for _, spec := range decl.Specs { typeSpec, ok := spec.(*ast.TypeSpec) if !ok { continue } structType, ok := typeSpec.Type.(*ast.StructType) if !ok { continue } if !types.Contains(typeSpec.Name.Name) { continue } props := getProps(fs, structType) typePropMap[typeSpec.Name.Name] = props } return true }) } g.pkg.typePropMap = typePropMap } func (g *Generator) format() []byte { src, err := format.Source(g.buf.Bytes()) if err != nil { log.Println("warning: internal error: invalid Go generated:", err) return g.buf.Bytes() } return src } var ( typeNames string extraImports string outputFile string ) func init() { flag.StringVar(&typeNames, "type", "", "comma-separated list of type names; must be set") flag.StringVar(&extraImports, "import", "", "") flag.StringVar(&outputFile, "output", "", "output file") } func main() { log.SetFlags(log.Lshortfile) log.SetPrefix("dbusutil-gen: ") flag.Parse() types := strv.Strv(strings.Split(typeNames, ",")) goPackage := os.Getenv("GOPACKAGE") files := flag.Args() var parsedExtraImports []string for _, imp := range strings.Split(extraImports, ",") { if imp == "" { continue } if strings.Contains(imp, "=") { parts := strings.SplitN(imp, "=", 2) pkg := parts[0] alias := parts[1] // github.com/godbus/dbus=dbus,bytes parsedExtraImports = append(parsedExtraImports, fmt.Sprintf("%s \"%s\"", alias, pkg)) } else { parsedExtraImports = append(parsedExtraImports, `"`+imp+`"`) } } g := &Generator{ pkg: Package{ name: goPackage, extraImports: parsedExtraImports, }, } g.parseFiles(files, types) g.generate() code := g.format() if outputFile == "" { outputFile = g.pkg.name + "_dbusutil.go" } log.Println("output file:", outputFile) err := ioutil.WriteFile(outputFile, code, 0644) if err != nil { log.Fatal(err) } } func isExportField(fieldName string) bool { return unicode.IsUpper(rune(fieldName[0])) } func getProps(fs *token.FileSet, structType *ast.StructType) []Property { //ast.Print(fs, structType) var prevField *ast.Field var props []Property for _, field := range structType.Fields.List { if len(field.Names) != 1 { prevField = field continue } fieldName := field.Names[0].Name if !isExportField(fieldName) { prevField = field continue } if fieldName == propsMuField { prevField = field continue } var equal string if field.Doc != nil { comments := field.Doc.List if len(comments) > 0 { option := getOptionFromComment(comments[0].Text) if option != "" { log.Printf("field %s option %s", fieldName, option) } if option == "ignore" { prevField = field continue } else if option == "ignore-below" { break } equal = getEqualFunc(option) } } fieldType, err := astNodeToStr(fs, field.Type) if err != nil { log.Fatal(err) } if fieldType == "sync.RWMutex" && prevField != nil && len(prevField.Names) == 1 { prevFieldName := prevField.Names[0].Name if prevFieldName+"Mu" == fieldName { // ignore this field and prev field props = props[:len(props)-1] prevField = field continue } } props = append(props, Property{ Name: fieldName, Type: fieldType, Equal: equal, }) prevField = field } return props } func getEqualFunc(option string) string { idx := strings.Index(option, "equal=") if idx != -1 { equal := option[idx+len("equal="):] return strings.TrimSpace(equal) } return "" } func getOptionFromComment(comment string) string { comment = strings.TrimPrefix(comment, "//") comment = strings.TrimSpace(comment) const prefix = "dbusutil-gen:" if !strings.HasPrefix(comment, prefix) { return "" } option := comment[len(prefix):] return strings.TrimSpace(option) } go-lib-5.6.0.9/dbusutil/dbusutil.go000664 000000 000000 00000037301 13753517240 017052 0ustar00rootroot000000 000000 package dbusutil import ( "errors" "fmt" "io/ioutil" "log" "os" "reflect" "strings" "sync" "github.com/godbus/dbus" "github.com/godbus/dbus/introspect" ) var logger *log.Logger func init() { // setup logger logOut := ioutil.Discard if os.Getenv("DEBUG_DBUSUTIL") == "1" { logOut = os.Stderr } logger = log.New(logOut, "[dbusutil]", log.Lshortfile) } const orgFreedesktopDBus = "org.freedesktop.DBus" type accessType uint const ( accessRead accessType = 1 accessWrite = 2 accessReadWrite = accessRead | accessWrite ) func (a accessType) String() string { switch a { case accessRead: return "read" case accessWrite: return "write" case accessReadWrite: return "readwrite" default: return fmt.Sprintf("invalid(%d)", a) } } type emitType uint const ( emitFalse emitType = iota emitTrue emitInvalidates ) func (e emitType) String() string { switch e { case emitFalse: return "false" case emitTrue: return "true" case emitInvalidates: return "invalidates" default: return fmt.Sprintf("invalid(%d)", e) } } // struct field prop type fieldProp struct { rValue reflect.Value valueMu *sync.RWMutex cbMu sync.Mutex writeCb PropertyWriteCallback readCb PropertyReadCallback changedCbs []PropertyChangedCallback } type fieldPropStatic struct { name string rType reflect.Type valueType fieldPropValueType signature dbus.Signature hasStruct bool emit emitType access accessType } type fieldPropValueType uint const ( fieldPropValueNotProp fieldPropValueType = iota fieldPropValueImplProp fieldPropValuePtrImplProp ) func (p *fieldProp) getValue(propRead *PropertyRead) (value interface{}, err *dbus.Error) { readCb := p.getReadCallback() if readCb != nil { err = readCb(propRead) if err != nil { return } } if p.valueMu != nil { p.valueMu.RLock() } value = p.rValue.Interface() if propValue, ok := value.(Property); ok { value, err = propValue.GetValue() } if p.valueMu != nil { p.valueMu.RUnlock() } return } func (p *fieldProp) GetValueVariant(propRead *PropertyRead, signature dbus.Signature) (dbus.Variant, *dbus.Error) { value, err := p.getValue(propRead) if err != nil { return dbus.Variant{}, err } return dbus.MakeVariantWithSignature(value, signature), nil } func (p *fieldProp) SetValue(propWrite *PropertyWrite) (changed bool, err *dbus.Error) { writeCb := p.getWriteCallback() if writeCb != nil { err = writeCb(propWrite) if err != nil { return } } if p.valueMu != nil { p.valueMu.Lock() } newVal := propWrite.Value value := p.rValue.Interface() propValue, ok := value.(Property) if ok { changed, err = propValue.SetValue(newVal) } else { newValRV := reflect.ValueOf(newVal) newValRT := reflect.TypeOf(newVal) valueRT := reflect.TypeOf(value) if valueRT != newValRT { // type not equal, try convert if newValRT.ConvertibleTo(valueRT) { newValRV = newValRV.Convert(valueRT) } else { err = dbus.MakeFailedError(errors.New("type not convertible")) } } if err == nil && !reflect.DeepEqual(value, newValRV.Interface()) { p.rValue.Set(newValRV) changed = true } } if p.valueMu != nil { p.valueMu.Unlock() } return } func (p *fieldProp) getWriteCallback() PropertyWriteCallback { p.cbMu.Lock() cb := p.writeCb p.cbMu.Unlock() return cb } func (p *fieldProp) getReadCallback() PropertyReadCallback { p.cbMu.Lock() cb := p.readCb p.cbMu.Unlock() return cb } func (p *fieldProp) setWriteCallback(cb PropertyWriteCallback) { p.cbMu.Lock() p.writeCb = cb p.cbMu.Unlock() } func (p *fieldProp) setReadCallback(cb PropertyReadCallback) { p.cbMu.Lock() p.readCb = cb p.cbMu.Unlock() } func (p *fieldProp) connectChanged(cb PropertyChangedCallback) { p.cbMu.Lock() // copy on write newCbs := make([]PropertyChangedCallback, len(p.changedCbs)+1) copy(newCbs, p.changedCbs) newCbs[len(newCbs)-1] = cb p.changedCbs = newCbs p.cbMu.Unlock() } // do changed callbacks func (p *fieldProp) notifyChanged(change *PropertyChanged) { p.cbMu.Lock() callbacks := p.changedCbs p.cbMu.Unlock() for _, cb := range callbacks { cb(change) } } // emit DBus signal Properties.PropertiesChanged func emitPropertiesChanged(conn *dbus.Conn, path dbus.ObjectPath, interfaceName string, propName string, value interface{}, emit emitType) (err error) { const signal = orgFreedesktopDBus + ".Properties.PropertiesChanged" var changedProps map[string]dbus.Variant switch emit { case emitFalse: // do nothing case emitInvalidates: err = conn.Emit(path, signal, interfaceName, changedProps, []string{propName}) case emitTrue: changedProps = map[string]dbus.Variant{ propName: dbus.MakeVariant(value), } err = conn.Emit(path, signal, interfaceName, changedProps, []string{}) default: panic("invalid value for emitType") } return } func getPropsIntrospection(props map[string]*fieldPropStatic) []introspect.Property { var result = make([]introspect.Property, len(props)) idx := 0 for _, p := range props { var access string switch p.access { case accessWrite: access = "write" case accessRead: access = "read" case accessReadWrite: access = "readwrite" default: panic("invalid access") } result[idx] = introspect.Property{ Name: p.name, Type: p.signature.String(), Access: access, } idx++ } return result } func getSignals(structType reflect.Type) []introspect.Signal { signalsField, ok := structType.FieldByName("signals") if !ok { return nil } if signalsField.Type.Kind() != reflect.Ptr { return nil } signalsFieldElemType := signalsField.Type.Elem() if signalsFieldElemType.Kind() != reflect.Struct { return nil } var signals []introspect.Signal numField := signalsFieldElemType.NumField() for i := 0; i < numField; i++ { signalItem := signalsFieldElemType.Field(i) signalItemType := signalItem.Type if signalItemType.Kind() == reflect.Struct { var args []introspect.Arg numArg := signalItemType.NumField() for j := 0; j < numArg; j++ { signalArg := signalItemType.Field(j) args = append(args, introspect.Arg{ Name: signalArg.Name, Type: dbus.SignatureOfType(signalArg.Type).String(), }) } signals = append(signals, introspect.Signal{ Name: signalItem.Name, Args: args, }) } } return signals } const propsMuField = "PropsMu" func getCorePropsMu(structValue reflect.Value) *sync.RWMutex { propsMasterRV := structValue.FieldByName(propsMuField) if !propsMasterRV.IsValid() { return nil } return propsMasterRV.Addr().Interface().(*sync.RWMutex) } func getStructValue(m interface{}) (reflect.Value, bool) { type0 := reflect.TypeOf(m) value0 := reflect.ValueOf(m) if type0.Kind() != reflect.Ptr { return reflect.Value{}, false } elemType := type0.Elem() elemValue := value0.Elem() if elemType.Kind() != reflect.Struct { return reflect.Value{}, false } if !elemValue.IsValid() { return reflect.Value{}, false } return elemValue, true } func getFieldPropStaticMap(structType reflect.Type, structValue reflect.Value) map[string]*fieldPropStatic { props := make(map[string]*fieldPropStatic) var prevField reflect.StructField numField := structType.NumField() for i := 0; i < numField; i++ { field := structType.Field(i) fieldValue := structValue.Field(i) if field.Name == propsMuField { prevField = field continue } if !fieldValue.CanSet() { prevField = field continue } tag := field.Tag.Get("prop") if tag == "-" { prevField = field continue } if prevField.Name+"Mu" == field.Name { prevField = field continue } prop0 := newFieldPropStatic(field, fieldValue, tag) props[field.Name] = prop0 prevField = field } return props } func getFieldPropMap(impl *implementer, implStatic *implementerStatic, structValue reflect.Value, s *Service, path dbus.ObjectPath) map[string]*fieldProp { structType := structValue.Type() props := make(map[string]*fieldProp) corePropsMu := getCorePropsMu(structValue) numField := structType.NumField() var prevField reflect.StructField for i := 0; i < numField; i++ { field := structType.Field(i) fieldValue := structValue.Field(i) // ex: // prevField: Prop1 // current Field: Prop1Mu if prevField.Name+"Mu" == field.Name && props[prevField.Name] != nil { mu, ok := fieldValue.Addr().Interface().(*sync.RWMutex) if ok { // override prev fieldProp.ValueMu props[prevField.Name].valueMu = mu } prevField = field continue } propStatic, ok := implStatic.props[field.Name] if !ok { prevField = field continue } p := &fieldProp{ rValue: fieldValue, } var propValue Property switch propStatic.valueType { case fieldPropValueNotProp: p.valueMu = corePropsMu case fieldPropValueImplProp: propValue = fieldValue.Interface().(Property) case fieldPropValuePtrImplProp: fieldValuePtr := fieldValue.Addr() propValue = fieldValuePtr.Interface().(Property) p.rValue = fieldValuePtr } if propValue != nil { propValue.SetNotifyChangedFunc(func(val interface{}) { impl.notifyChanged(s, path, p, propStatic, val) }) } props[field.Name] = p prevField = field } return props } func parsePropTag(tag string) (accessType, emitType) { access := accessRead emit := emitTrue tagParts := strings.Split(tag, ",") for _, tagPart := range tagParts { if strings.HasPrefix(tagPart, "access:") { accessStr := tagPart[len("access:"):] switch accessStr { case "r", "read": access = accessRead case "w", "write": access = accessWrite case "rw", "readwrite": access = accessReadWrite default: panic(fmt.Errorf("invalid access %q", accessStr)) } continue } else if strings.HasPrefix(tagPart, "emit:") { emitStr := tagPart[len("emit:"):] switch emitStr { case "true": emit = emitTrue case "false": emit = emitFalse case "invalidates": emit = emitInvalidates default: panic(fmt.Errorf("invalid emit %q", emitStr)) } continue } } return access, emit } func toProperty(value reflect.Value) (Property, fieldPropValueType) { propValue, ok := value.Interface().(Property) if ok { return propValue, fieldPropValueImplProp } // try value.Addr if value.Kind() == reflect.Struct { propValue, ok = value.Addr().Interface().(Property) if ok { return propValue, fieldPropValuePtrImplProp } } return nil, fieldPropValueNotProp } func newFieldPropStatic(field reflect.StructField, fieldValue reflect.Value, tag string) *fieldPropStatic { access, emit := parsePropTag(tag) p := &fieldPropStatic{ name: field.Name, access: access, emit: emit, } var rType reflect.Type propValue, valueType := toProperty(fieldValue) p.valueType = valueType if valueType == fieldPropValueNotProp { rType = field.Type } else { rType = propValue.GetType() } p.rType = rType p.signature = dbus.SignatureOfType(rType) if strings.Contains(p.signature.String(), "(") { p.hasStruct = true } return p } type methodDetail struct { In []string Out []string } func (md methodDetail) getInArgName(index int, type0 reflect.Type, methodName string) string { if index >= len(md.In) { panic(fmt.Errorf("failed to get %s.%s in[%d] argument name", type0, methodName, index)) } return md.In[index] } func (md methodDetail) getOutArgName(index int, type0 reflect.Type, methodName string) string { if index >= len(md.Out) { panic(fmt.Errorf("failed to get %s.%s out[%d] argument name", type0, methodName, index)) } return md.Out[index] } func getMethodDetailMap(structType reflect.Type) map[string]methodDetail { result := make(map[string]methodDetail) methodsField, ok := structType.FieldByName("methods") if !ok { return nil } if methodsField.Type.Kind() != reflect.Ptr { return nil } methodsFieldElemType := methodsField.Type.Elem() if methodsFieldElemType.Kind() != reflect.Struct { return nil } numField := methodsFieldElemType.NumField() for i := 0; i < numField; i++ { methodItem := methodsFieldElemType.Field(i) tagIn := methodItem.Tag.Get("in") tagOut := methodItem.Tag.Get("out") result[methodItem.Name] = methodDetail{ In: splitArg(tagIn), Out: splitArg(tagOut), } } return result } func splitArg(str string) (result []string) { parts := strings.Split(str, ",") for _, part := range parts { part = strings.TrimSpace(part) if part != "" { result = append(result, part) } } return } // Methods returns the description of the methods of v. This can be used to // create a Node which can be passed to NewIntrospectable. func getMethods(v interface{}, methodDetailMap map[string]methodDetail) []introspect.Method { t := reflect.TypeOf(v) ms := make([]introspect.Method, 0, t.NumMethod()) for i := 0; i < t.NumMethod(); i++ { if t.Method(i).PkgPath != "" { continue } mt := t.Method(i).Type if mt.NumOut() == 0 || mt.Out(mt.NumOut()-1) != reflect.TypeOf(&dbus.Error{}) { continue } var m introspect.Method m.Name = t.Method(i).Name m.Args = make([]introspect.Arg, 0, mt.NumIn()+mt.NumOut()-2) methodDetail := methodDetailMap[m.Name] inArgIndex := 0 for j := 1; j < mt.NumIn(); j++ { if mt.In(j) != reflect.TypeOf((*dbus.Sender)(nil)).Elem() && mt.In(j) != reflect.TypeOf((*dbus.Message)(nil)).Elem() { argName := methodDetail.getInArgName(inArgIndex, t, m.Name) inArgIndex++ arg := introspect.Arg{Name: argName, Type: dbus.SignatureOfType(mt.In(j)).String(), Direction: "in", } m.Args = append(m.Args, arg) } } for j := 0; j < mt.NumOut()-1; j++ { argName := methodDetail.getOutArgName(j, t, m.Name) arg := introspect.Arg{ Name: argName, Type: dbus.SignatureOfType(mt.Out(j)).String(), Direction: "out", } m.Args = append(m.Args, arg) } m.Annotations = make([]introspect.Annotation, 0) ms = append(ms, m) } return ms } type PropertyReadCallback func(read *PropertyRead) *dbus.Error type PropertyWriteCallback func(write *PropertyWrite) *dbus.Error type PropertyChangedCallback func(change *PropertyChanged) type Property interface { SetValue(val interface{}) (changed bool, err *dbus.Error) GetValue() (val interface{}, err *dbus.Error) SetNotifyChangedFunc(func(val interface{})) GetType() reflect.Type } type PropertyInfo struct { Path dbus.ObjectPath Interface string Name string } type PropertyAccess struct { PropertyInfo Sender dbus.Sender service *Service } func (pa *PropertyAccess) GetPID() (uint32, error) { return pa.service.GetConnPID(string(pa.Sender)) } func (pa *PropertyAccess) GetUID() (uint32, error) { return pa.service.GetConnUID(string(pa.Sender)) } type PropertyRead struct { PropertyAccess } func newPropertyRead(sender dbus.Sender, so *ServerObject, interfaceName, name string) *PropertyRead { pr := new(PropertyRead) pr.Sender = sender pr.service = so.service pr.Name = name pr.Interface = interfaceName pr.Path = so.path return pr } type PropertyWrite struct { PropertyAccess Value interface{} // new value } func newPropertyWrite(sender dbus.Sender, so *ServerObject, interfaceName, name string, value interface{}) *PropertyWrite { pw := new(PropertyWrite) pw.Sender = sender pw.service = so.service pw.Name = name pw.Interface = interfaceName pw.Path = so.path pw.Value = value return pw } type PropertyChanged struct { PropertyInfo Value interface{} // new value } func newPropertyChanged(path dbus.ObjectPath, interfaceName, name string, value interface{}) *PropertyChanged { pc := new(PropertyChanged) pc.Name = name pc.Interface = interfaceName pc.Path = path pc.Value = value return pc } func valueFromBus(src interface{}, valueRT reflect.Type) (reflect.Value, error) { newValueRV := reflect.New(valueRT) err := dbus.Store([]interface{}{src}, newValueRV.Interface()) if err != nil { return reflect.Value{}, err } return newValueRV.Elem(), nil } go-lib-5.6.0.9/dbusutil/err.go000664 000000 000000 00000002373 13753517240 016010 0ustar00rootroot000000 000000 package dbusutil import ( "encoding/json" "fmt" "github.com/godbus/dbus" ) func MakeError(v Implementer, name string, args ...interface{}) *dbus.Error { errName := v.GetInterfaceName() + ".Error." + name msg := fmt.Sprint(args...) return &dbus.Error{ Name: errName, Body: []interface{}{msg}, } } func MakeErrorf(v Implementer, name, format string, args ...interface{}) *dbus.Error { errName := v.GetInterfaceName() + ".Error." + name msg := fmt.Sprintf(format, args...) return &dbus.Error{ Name: errName, Body: []interface{}{msg}, } } func MakeErrorJSON(v Implementer, name string, detail interface{}) *dbus.Error { var msg string errName := v.GetInterfaceName() + ".Error." + name data, err := json.Marshal(detail) if err != nil { msg = "failed to marshal json" } else { msg = string(data) } return &dbus.Error{ Name: errName, Body: []interface{}{msg}, } } type DBusError interface { Error() string Name() string } func ToError(err error) *dbus.Error { if err == nil { return nil } err0, ok := err.(DBusError) var name, msg string if ok { name = err0.Name() msg = err0.Error() } else { name = "com.deepin.DBus.Error.Unnamed" msg = err.Error() } return &dbus.Error{ Name: name, Body: []interface{}{msg}, } } go-lib-5.6.0.9/dbusutil/err_test.go000664 000000 000000 00000004500 13753517240 017041 0ustar00rootroot000000 000000 package dbusutil import ( "reflect" "testing" "github.com/godbus/dbus" ) type impl1 struct { } func (*impl1) GetInterfaceName() string { return "com.deepin.lib.Exportable1" } func TestMakeError(t *testing.T) { err := MakeError(&impl1{}, "Err1", "abc", 123) expectedErr := &dbus.Error{ Name: "com.deepin.lib.Exportable1.Error.Err1", Body: []interface{}{"abc123"}, } if !reflect.DeepEqual(err, expectedErr) { t.Errorf("err expected %#v, but got %#v", expectedErr, err) } } func TestMakeErrorf(t *testing.T) { err := MakeErrorf(&impl1{}, "Err2", "name: %s, num: %d", "abc", 123) expectedErr := &dbus.Error{ Name: "com.deepin.lib.Exportable1.Error.Err2", Body: []interface{}{"name: abc, num: 123"}, } if !reflect.DeepEqual(err, expectedErr) { t.Errorf("err expected %#v, but got %#v", expectedErr, err) } } func TestMakeErrorJSON(t *testing.T) { detail := &struct { Name string `json:"name"` Num int `json:"num"` }{"abc", 123} err := MakeErrorJSON(&impl1{}, "Err3", detail) expectedErr := &dbus.Error{ Name: "com.deepin.lib.Exportable1.Error.Err3", Body: []interface{}{`{"name":"abc","num":123}`}, } if !reflect.DeepEqual(err, expectedErr) { t.Errorf("err expected %#v, but got %#v", expectedErr, err) } detail1 := &struct { Chan chan int }{ nil, } err = MakeErrorJSON(&impl1{}, "Err3", detail1) // do not panic if err == nil { t.Errorf("Expected error due to detail1 has chan type field") } } type unnamedError struct{} func (err unnamedError) Error() string { return "xxx err msg" } type namedError struct{} func (err namedError) Error() string { return "yyy err msg" } func (err namedError) Name() string { return "com.deepin.lib.Exportable1.Error.Err4" } func TestToError(t *testing.T) { err := ToError(unnamedError{}) expectedErr := &dbus.Error{ Name: "com.deepin.DBus.Error.Unnamed", Body: []interface{}{"xxx err msg"}, } if !reflect.DeepEqual(err, expectedErr) { t.Errorf("err expected %#v, but got %#v", expectedErr, err) } err = ToError(namedError{}) expectedErr = &dbus.Error{ Name: "com.deepin.lib.Exportable1.Error.Err4", Body: []interface{}{"yyy err msg"}, } if !reflect.DeepEqual(err, expectedErr) { t.Errorf("err expected %#v, but got %#v", expectedErr, err) } err = ToError(nil) if err != nil { t.Errorf("err expected nil, but got %#v", err) } } go-lib-5.6.0.9/dbusutil/gsprop/000775 000000 000000 00000000000 13753517240 016176 5ustar00rootroot000000 000000 go-lib-5.6.0.9/dbusutil/gsprop/gsprop.go000664 000000 000000 00000014763 13753517240 020052 0ustar00rootroot000000 000000 package gsprop import ( "errors" "reflect" "sync" "pkg.deepin.io/gir/gio-2.0" "github.com/godbus/dbus" "pkg.deepin.io/lib/dbusutil" "pkg.deepin.io/lib/gsettings" ) type base struct { mu sync.Mutex gs *gio.Settings key string notifyChanged func(val interface{}) } func (b *base) bind(gs *gio.Settings, keyName string, getFn func() (interface{}, *dbus.Error)) { b.gs = gs b.key = keyName var propPath string gs.GetProperty("path", &propPath) gsettings.ConnectChanged(propPath, keyName, func(_ string) { b.mu.Lock() notifyChanged := b.notifyChanged b.mu.Unlock() if notifyChanged != nil { val, _ := getFn() notifyChanged(val) } }) } func (b *base) SetNotifyChangedFunc(fn func(val interface{})) { b.mu.Lock() b.notifyChanged = fn b.mu.Unlock() } func checkSet(setOk bool) *dbus.Error { if setOk { return nil } return dbusutil.ToError(errors.New("write failed")) } type Bool struct { base } func (b *Bool) Bind(gs *gio.Settings, key string) { b.bind(gs, key, b.GetValue) } func (b *Bool) SetValue(val interface{}) (changed bool, err *dbus.Error) { err = checkSet(b.Set(val.(bool))) return } func (b *Bool) GetValue() (val interface{}, err *dbus.Error) { val = b.Get() return } func (b *Bool) Get() bool { b.mu.Lock() v := b.gs.GetBoolean(b.key) b.mu.Unlock() return v } func (b *Bool) Set(val bool) bool { if b.Get() != val { b.mu.Lock() ok := b.gs.SetBoolean(b.key, val) b.mu.Unlock() return ok } return true } func (*Bool) GetType() reflect.Type { return reflect.TypeOf(false) } type Int struct { base } func (i *Int) Bind(gs *gio.Settings, key string) { i.bind(gs, key, i.GetValue) } func (i *Int) SetValue(val interface{}) (changed bool, err *dbus.Error) { err = checkSet(i.Set(val.(int32))) return } func (i *Int) GetValue() (val interface{}, err *dbus.Error) { val = i.Get() return } func (*Int) GetType() reflect.Type { return reflect.TypeOf(int32(0)) } func (i *Int) Set(val int32) bool { if i.Get() != val { i.mu.Lock() ok := i.gs.SetInt(i.key, val) i.mu.Unlock() return ok } return true } func (i *Int) Get() int32 { i.mu.Lock() v := i.gs.GetInt(i.key) i.mu.Unlock() return v } type Enum struct { base } func (e *Enum) SetValue(val interface{}) (changed bool, err *dbus.Error) { err = checkSet(e.Set(val.(int32))) return } func (e *Enum) GetValue() (val interface{}, err *dbus.Error) { val = e.Get() return } func (e *Enum) GetType() reflect.Type { return reflect.TypeOf(int32(0)) } func (e *Enum) Bind(gs *gio.Settings, key string) { e.bind(gs, key, e.GetValue) } func (e *Enum) Get() int32 { e.mu.Lock() v := e.gs.GetEnum(e.key) e.mu.Unlock() return v } func (e *Enum) GetString() string { e.mu.Lock() v := e.gs.GetString(e.key) e.mu.Unlock() return v } func (e *Enum) Set(val int32) bool { if e.Get() != val { e.mu.Lock() ok := e.gs.SetEnum(e.key, val) e.mu.Unlock() return ok } return true } func (e *Enum) SetString(val string) bool { if e.GetString() != val { e.mu.Lock() ok := e.gs.SetString(e.key, val) e.mu.Unlock() return ok } return true } type Uint struct { base } func (u *Uint) SetValue(val interface{}) (changed bool, err *dbus.Error) { err = checkSet(u.Set(val.(uint32))) return } func (u *Uint) GetValue() (val interface{}, err *dbus.Error) { val = u.Get() return } func (*Uint) GetType() reflect.Type { return reflect.TypeOf(uint32(0)) } func (u *Uint) Get() uint32 { u.mu.Lock() v := u.gs.GetUint(u.key) u.mu.Unlock() return v } func (u *Uint) Set(val uint32) bool { if u.Get() != val { u.mu.Lock() ok := u.gs.SetUint(u.key, val) u.mu.Unlock() return ok } return true } func (u *Uint) Bind(gs *gio.Settings, key string) { u.bind(gs, key, u.GetValue) } type Uint64 struct { base } func (u *Uint64) SetValue(val interface{}) (changed bool, err *dbus.Error) { err = checkSet(u.Set(val.(uint64))) return } func (u *Uint64) GetValue() (val interface{}, err *dbus.Error) { val = u.Get() return } func (*Uint64) GetType() reflect.Type { return reflect.TypeOf(uint64(0)) } func (u *Uint64) Get() uint64 { u.mu.Lock() v := u.gs.GetUint64(u.key) u.mu.Unlock() return v } func (u *Uint64) Set(val uint64) bool { if u.Get() != val { u.mu.Lock() ok := u.gs.SetUint64(u.key, val) u.mu.Unlock() return ok } return true } func (u *Uint64) Bind(gs *gio.Settings, key string) { u.bind(gs, key, u.GetValue) } type Double struct { base } func (d *Double) SetValue(val interface{}) (changed bool, err *dbus.Error) { err = checkSet(d.Set(val.(float64))) return } func (d *Double) GetValue() (val interface{}, err *dbus.Error) { val = d.Get() return } func (*Double) GetType() reflect.Type { return reflect.TypeOf(float64(0)) } func (d *Double) Get() float64 { d.mu.Lock() v := d.gs.GetDouble(d.key) d.mu.Unlock() return v } func (d *Double) Set(val float64) bool { if d.Get() != val { d.mu.Lock() ok := d.gs.SetDouble(d.key, val) d.mu.Unlock() return ok } return true } func (d *Double) Bind(gs *gio.Settings, key string) { d.bind(gs, key, d.GetValue) } type String struct { base } func (s *String) SetValue(val interface{}) (changed bool, err *dbus.Error) { err = checkSet(s.Set(val.(string))) return } func (s *String) GetValue() (val interface{}, err *dbus.Error) { val = s.Get() return } func (*String) GetType() reflect.Type { return reflect.TypeOf("") } func (s *String) Get() string { s.mu.Lock() v := s.gs.GetString(s.key) s.mu.Unlock() return v } func (s *String) Set(val string) bool { if s.Get() != val { s.mu.Lock() ok := s.gs.SetString(s.key, val) s.mu.Unlock() return ok } return true } func (s *String) Bind(gs *gio.Settings, key string) { s.bind(gs, key, s.GetValue) } type Strv struct { base } func (s *Strv) SetValue(val interface{}) (changed bool, err *dbus.Error) { err = checkSet(s.Set(val.([]string))) return } func (s *Strv) GetValue() (val interface{}, err *dbus.Error) { val = s.Get() return } func (*Strv) GetType() reflect.Type { return reflect.TypeOf([]string{}) } func (s *Strv) Get() []string { s.mu.Lock() v := s.gs.GetStrv(s.key) s.mu.Unlock() return v } func (s *Strv) Set(val []string) bool { if !strvEqual(s.Get(), val) { s.mu.Lock() ok := s.gs.SetStrv(s.key, val) s.mu.Unlock() return ok } return true } func (s *Strv) Bind(gs *gio.Settings, key string) { s.bind(gs, key, s.GetValue) } func strvEqual(a []string, b []string) bool { an := len(a) bn := len(b) if an != bn { return false } for i, v := range a { if b[i] != v { return false } } return true } go-lib-5.6.0.9/dbusutil/gsprop/gsprop_test.go000664 000000 000000 00000025361 13753517240 021105 0ustar00rootroot000000 000000 package gsprop import ( "encoding/xml" "os/exec" "strings" "testing" "time" "pkg.deepin.io/gir/gio-2.0" "github.com/godbus/dbus" "github.com/godbus/dbus/introspect" "pkg.deepin.io/lib/dbusutil" "pkg.deepin.io/lib/gsettings" ) const demoSchemaId = "ca.desrt.dconf-editor.Demo" type srvObject1 struct { Bool Bool `prop:"access:rw"` Enum Enum `prop:"access:rw"` Int Int `prop:"access:rw"` Uint Uint `prop:"access:rw"` Double Double `prop:"access:rw"` String String `prop:"access:rw"` Strv Strv `prop:"access:rw"` } const srvObj1Interface = "com.deepin.lib.gsprop.Object1" func (*srvObject1) GetInterfaceName() string { return srvObj1Interface } func TestAll(t *testing.T) { err := exec.Command("gsettings", "list-recursively", demoSchemaId).Run() if err != nil { t.Skip("failed to exec gsettings list-recursively") } script := ` gsettings set ca.desrt.dconf-editor.Demo boolean true gsettings set ca.desrt.dconf-editor.Demo enumeration Blue gsettings set ca.desrt.dconf-editor.Demo integer-32-signed -32 gsettings set ca.desrt.dconf-editor.Demo integer-32-unsigned 132 gsettings set ca.desrt.dconf-editor.Demo double 1.5 gsettings set ca.desrt.dconf-editor.Demo string 'hello world' gsettings set ca.desrt.dconf-editor.Demo string-array '["go","perl","python", "c#"]' ` sh := exec.Command("sh") sh.Stdin = strings.NewReader(script) err = sh.Run() if err != nil { t.Error("Unexpected error executing script:", err) } gs := gio.NewSettings(demoSchemaId) srvObj1 := &srvObject1{} srvObj1.Bool.Bind(gs, "boolean") srvObj1.Enum.Bind(gs, "enumeration") srvObj1.Int.Bind(gs, "integer-32-signed") srvObj1.Uint.Bind(gs, "integer-32-unsigned") srvObj1.Double.Bind(gs, "double") srvObj1.String.Bind(gs, "string") srvObj1.Strv.Bind(gs, "string-array") service, err := dbusutil.NewSessionService() if err != nil { t.Error("Unexpected error:", err) } const srvObj1Path = "/com/deepin/lib/gsprop/Object1" err = service.Export(srvObj1Path, srvObj1) if err != nil { t.Error("Unexpected error export srvObj1:", err) } err = service.RequestName(srvObj1Interface) if err != nil { t.Error("Unexpected error calling RequestName:", err) } clientObj1 := service.Conn().Object(srvObj1Interface, srvObj1Path) var introspection string err = clientObj1.Call( "org.freedesktop.DBus.Introspectable.Introspect", 0).Store(&introspection) if err != nil { t.Error("Unexpected error calling Introspectable method:", err) } var iNode introspect.Node err = xml.Unmarshal([]byte(introspection), &iNode) if err != nil { t.Error("Unexpected error unmarshaling xml:", err) } xmlData, err := xml.MarshalIndent(&iNode, "", "\t") if err != nil { t.Error("Unexpected marshal indent:", xmlData) } t.Logf("%s\n", xmlData) var pBool bool err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Bool").Store(&pBool) if err != nil { t.Error("Unexpected error getting the Bool property:", err) } if pBool != true { t.Error("pBool expected true") } var pEnum uint32 err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Enum").Store(&pEnum) if err != nil { t.Error("Unexpected error getting the Enum property:", err) } if pEnum != 2 { t.Errorf("pEnum expected 2 but got %d", pEnum) } var pInt int32 err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Int").Store(&pInt) if err != nil { t.Error("Unexpected error getting the Int property:", err) } if pInt != -32 { t.Errorf("pInt expected -32 but got %d", pInt) } var pUint uint32 err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Uint").Store(&pUint) if err != nil { t.Error("Unexpected error getting the Uint property:", err) } if pUint != 132 { t.Errorf("pUint expected 132 but got %d", pUint) } var pDouble float64 err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Double").Store(&pDouble) if err != nil { t.Error("Unexpected error getting the Double property:", err) } if pDouble != 1.5 { t.Errorf("pDobule expected 1.5 but got %v", pDouble) } var pString string err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "String").Store(&pString) if err != nil { t.Error("Unexpected error getting the String property:", err) } pStringExpected := "hello world" if pString != pStringExpected { t.Errorf("pString expected %q but got %q", pStringExpected, pString) } var pStrv []string err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Strv").Store(&pStrv) if err != nil { t.Error("Unexpected error getting the Strv property:", err) } pStrvExpected := []string{"go", "perl", "python", "c#"} if !strvEqual(pStrvExpected, pStrv) { t.Errorf("pStrv expected %#v but got %#v", pStrvExpected, pStrv) } // GetAll var props map[string]dbus.Variant err = clientObj1.Call("org.freedesktop.DBus.Properties.GetAll", 0, srvObj1Interface).Store(&props) if err != nil { t.Error("Unexpected error getting all properties:", err) } t.Logf("props: %#v\n", props) // set bool err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "Bool", dbus.MakeVariant(false)).Err if err != nil { t.Error("Unexpected error setting the Bool property:", err) } err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Bool").Store(&pBool) if err != nil { t.Error("Unexpected error getting the Bool property:", err) } if pBool != false { t.Error("pBool expected false") } // set enum err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "Enum", dbus.MakeVariant(int32(1))).Err if err != nil { t.Error("Unexpected error setting the Enum property:", err) } err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Enum").Store(&pEnum) if err != nil { t.Error("Unexpected error getting the Enum property:", err) } if pEnum != 1 { t.Errorf("pEnum expected 1 but got %d", pEnum) } // set enum failed err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "Enum", dbus.MakeVariant(int32(999))).Err if err == nil { t.Error("Expected error setting the Enum property") } err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Enum").Store(&pEnum) if err != nil { t.Error("Unexpected error getting the Enum property:", err) } if pEnum != 1 { t.Errorf("pEnum expected 1 but got %d", pEnum) } // set int err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "Int", dbus.MakeVariant(int32(110))).Err if err != nil { t.Error("Unexpected error setting the Int property:", err) } err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Int").Store(&pInt) if err != nil { t.Error("Unexpected error getting the Int property:", err) } if pInt != 110 { t.Errorf("pInt expected 110 but got %d", pInt) } // set uint err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "Uint", dbus.MakeVariant(uint32(120))).Err if err != nil { t.Error("Unexpected error setting the Uint property:", err) } err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Uint").Store(&pUint) if err != nil { t.Error("Unexpected error getting the Uint property:", err) } if pUint != 120 { t.Errorf("pUint expected 120 but got %d", pUint) } // set double err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "Double", dbus.MakeVariant(float64(3.5))).Err if err != nil { t.Error("Unexpected error setting the Double property:", err) } err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Double").Store(&pDouble) if err != nil { t.Error("Unexpected error getting the Double property:", err) } if pDouble != 3.5 { t.Errorf("pDouble expected 3.5 but got %v", pDouble) } // set string err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "String", dbus.MakeVariant("deepin")).Err if err != nil { t.Error("Unexpected error setting the String property:", err) } err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "String").Store(&pString) if err != nil { t.Error("Unexpected error getting the String property:", err) } if pString != "deepin" { t.Errorf("pString expected %q but got %q", "deepin", pString) } // set strv err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "Strv", dbus.MakeVariant([]string{"a", "b", "c"})).Err if err != nil { t.Error("Unexpected error setting the Strv property:", err) } err = clientObj1.Call("org.freedesktop.DBus.Properties.Get", 0, srvObj1Interface, "Strv").Store(&pStrv) if err != nil { t.Error("Unexpected error getting the Strv property:", err) } pStrvExpected = []string{"a", "b", "c"} if !strvEqual(pStrv, pStrvExpected) { t.Errorf("pStrv expected %#v but got %#v", pStrvExpected, pStrv) } gio.SettingsSync() // property changed signal go func() { _ = gsettings.StartMonitor() }() rule := dbusutil.NewMatchRuleBuilder().ExtPropertiesChanged(srvObj1Path, srvObj1Interface).Build() err = rule.AddTo(service.Conn()) if err != nil { t.Error("Unexpected error adding rule to service conn:", err) } ch := make(chan int) go processSignal(service.Conn(), func(signal *dbus.Signal) bool { if signal.Name == "org.freedesktop.DBus.Properties.PropertiesChanged" && signal.Path == srvObj1Path { ch <- 1 interfaceName := signal.Body[0].(string) if interfaceName != srvObj1Interface { t.Errorf("interfaceName expected %q but got %q", srvObj1Interface, interfaceName) } propVarMap := signal.Body[1].(map[string]dbus.Variant) variant, ok := propVarMap["Bool"] if !ok { t.Error("propVarMap expected has key Prop4") } val := variant.Value().(bool) if val != true { t.Errorf("val expected true") } return false } return true }) // set bool err = clientObj1.Call("org.freedesktop.DBus.Properties.Set", 0, srvObj1Interface, "Bool", dbus.MakeVariant(true)).Err if err != nil { t.Error("Unexpected error setting the Bool property:", err) } select { case <-ch: close(ch) case <-time.After(5 * time.Second): t.Error("Failed to announce that the Bool PropertyChanged signal emitted") } err = rule.RemoveFrom(service.Conn()) if err != nil { t.Error("Unexpected error removing rule from service conn:", err) } } // copy from dbusutil service_test.go func processSignal(conn *dbus.Conn, fn func(signal *dbus.Signal) bool) { signalChan := make(chan *dbus.Signal, 10) conn.Signal(signalChan) for sig := range signalChan { shouldContinue := fn(sig) if !shouldContinue { break } } conn.RemoveSignal(signalChan) close(signalChan) } go-lib-5.6.0.9/dbusutil/implementer_static.go000664 000000 000000 00000002212 13753517240 021100 0ustar00rootroot000000 000000 package dbusutil import ( "errors" "reflect" "github.com/godbus/dbus" "github.com/godbus/dbus/introspect" ) func newImplementerStatic(impl Implementer, structValue reflect.Value) *implementerStatic { s := &implementerStatic{} structType := structValue.Type() s.props = getFieldPropStaticMap(structType, structValue) s.introspectInterface = introspect.Interface{ Name: impl.GetInterfaceName(), Signals: getSignals(structType), Properties: getPropsIntrospection(s.props), Methods: getMethods(impl, getMethodDetailMap(structType)), } return s } type implementerStatic struct { props map[string]*fieldPropStatic introspectInterface introspect.Interface } func (is *implementerStatic) checkProperty(propName string) error { _, ok := is.props[propName] if ok { return nil } return errors.New("property not found") } func (is *implementerStatic) checkPropertyValue(propName string, value interface{}) error { p := is.props[propName] if p == nil { return errors.New("property not found") } if p.signature != dbus.SignatureOf(value) { return errors.New("property signature not equal") } return nil } go-lib-5.6.0.9/dbusutil/implementor.go000664 000000 000000 00000010555 13753517240 017554 0ustar00rootroot000000 000000 package dbusutil import ( "errors" "reflect" "sync" "unsafe" "github.com/godbus/dbus" ) type Implementer interface { GetInterfaceName() string } func getImplementerPointer(impl Implementer) unsafe.Pointer { return unsafe.Pointer(reflect.ValueOf(impl).Pointer()) } type implementer struct { core Implementer props map[string]*fieldProp propChanges propChanges } func (impl *implementer) getStatic(s *Service) *implementerStatic { return s.getImplementerStatic(impl.core) } func (impl *implementer) getInterfaceName() string { return impl.core.GetInterfaceName() } func newImplementer(core Implementer, service *Service, path dbus.ObjectPath) (*implementer, error) { impl := &implementer{ core: core, } structValue, ok := getStructValue(core) if !ok { return nil, errors.New("v is not a struct pointer") } ifcName := core.GetInterfaceName() service.mu.Lock() implStatic, ok := service.implStaticMap[ifcName] if !ok { implStatic = newImplementerStatic(core, structValue) service.implStaticMap[ifcName] = implStatic } service.mu.Unlock() impl.props = getFieldPropMap(impl, implStatic, structValue, service, path) return impl, nil } type propChanges struct { mu sync.Mutex modeMu sync.Mutex delayMode bool items []implPropChanged } type implPropChanged struct { name string value interface{} } func (impl *implementer) setWriteCallback(propertyName string, cb PropertyWriteCallback) error { p := impl.props[propertyName] if p == nil { return errors.New("property not found") } p.setWriteCallback(cb) return nil } func (impl *implementer) setReadCallback(propertyName string, cb PropertyReadCallback) error { p := impl.props[propertyName] if p == nil { return errors.New("property not found") } p.setReadCallback(cb) return nil } func (impl *implementer) connectChanged(propertyName string, cb PropertyChangedCallback) error { p := impl.props[propertyName] if p == nil { return errors.New("property not found") } p.connectChanged(cb) return nil } func (impl *implementer) notifyChanged(s *Service, path dbus.ObjectPath, p *fieldProp, propStatic *fieldPropStatic, value interface{}) { interfaceName := impl.core.GetInterfaceName() propChanged := newPropertyChanged(path, interfaceName, propStatic.name, value) p.notifyChanged(propChanged) _ = emitPropertiesChanged(s.conn, path, interfaceName, propStatic.name, value, propStatic.emit) } func (impl *implementer) delayEmitPropChanged() { // start delay mode impl.propChanges.modeMu.Lock() impl.propChanges.mu.Lock() impl.propChanges.delayMode = true impl.propChanges.mu.Unlock() } func (impl *implementer) emitPropChanged(s *Service, path dbus.ObjectPath, propName string, value interface{}) (err error) { impl.propChanges.mu.Lock() defer impl.propChanges.mu.Unlock() if impl.propChanges.delayMode { // in delay mode items := impl.propChanges.items found := false for i := 0; i < len(items); i++ { item := &items[i] if item.name == propName { item.value = value found = true break } } if !found { impl.propChanges.items = append(items, implPropChanged{ name: propName, value: value, }) } } else { // not in delay mode implStatic := impl.getStatic(s) propStatic := implStatic.props[propName] err = emitPropertiesChanged(s.conn, path, impl.getInterfaceName(), propName, value, propStatic.emit) } return } func (impl *implementer) stopDelayEmitPropChanged(s *Service, path dbus.ObjectPath) (err error) { impl.propChanges.mu.Lock() var changedProps map[string]dbus.Variant var invalidatedProps []string items := impl.propChanges.items if len(items) > 0 { changedProps = make(map[string]dbus.Variant) } implStatic := impl.getStatic(s) for _, change := range items { p := implStatic.props[change.name] switch p.emit { case emitFalse: // do nothing case emitInvalidates: invalidatedProps = append(invalidatedProps, change.name) case emitTrue: changedProps[change.name] = dbus.MakeVariant(change.value) } } const signalName = orgFreedesktopDBus + ".Properties.PropertiesChanged" if len(changedProps)+len(invalidatedProps) > 0 { err = s.conn.Emit(path, signalName, impl.core.GetInterfaceName(), changedProps, invalidatedProps) } impl.propChanges.items = nil impl.propChanges.delayMode = false impl.propChanges.mu.Unlock() // end delay mode impl.propChanges.modeMu.Unlock() return } go-lib-5.6.0.9/dbusutil/introspectable.go000664 000000 000000 00000003366 13753517240 020241 0ustar00rootroot000000 000000 package dbusutil import ( "strings" "github.com/godbus/dbus" "github.com/godbus/dbus/introspect" "github.com/godbus/dbus/prop" "pkg.deepin.io/lib/strv" ) var peerIntrospectData = introspect.Interface{ Name: orgFreedesktopDBus + ".Peer", Methods: []introspect.Method{ { Name: "Ping", }, { Name: "GetMachineId", Args: []introspect.Arg{ { Name: "machine_uuid", Type: "s", Direction: "out", }, }, }, }, } func (so *ServerObject) getChildren() (children strv.Strv) { var target string if so.path == "/" { target = "/" } else { target = string(so.path) + "/" } for objPath := range so.service.objMap { if objPath == so.path { continue } if strings.HasPrefix(string(objPath), target) { tail := string(objPath[len(target):]) idx := strings.Index(tail, "/") var child string if idx == -1 { child = tail } else { child = tail[:idx] } if child == "" { continue } else { children, _ = children.Add(child) } } } return } func (so *ServerObject) introspectableIntrospect() (string, *dbus.Error) { so.service.DelayAutoQuit() node := &introspect.Node{ Interfaces: so.getInterfaces(), } for _, child := range so.getChildren() { node.Children = append(node.Children, introspect.Node{Name: child}) } // marshal xml return string(introspect.NewIntrospectable(node)), nil } func (so *ServerObject) getInterfaces() []introspect.Interface { var interfaces []introspect.Interface for _, impl := range so.implementers { implStatic := impl.getStatic(so.service) interfaces = append(interfaces, implStatic.introspectInterface) } interfaces = append(interfaces, introspect.IntrospectData, prop.IntrospectData, peerIntrospectData) return interfaces } go-lib-5.6.0.9/dbusutil/match_rule.go000664 000000 000000 00000005521 13753517240 017341 0ustar00rootroot000000 000000 package dbusutil import ( "bytes" "fmt" "github.com/godbus/dbus" ) type MatchRule struct { Str string } func (mr MatchRule) AddTo(conn *dbus.Conn) error { return conn.BusObject().Call(orgFreedesktopDBus+".AddMatch", 0, mr.Str).Err } func (mr MatchRule) RemoveFrom(conn *dbus.Conn) error { return conn.BusObject().Call(orgFreedesktopDBus+".RemoveMatch", 0, mr.Str).Err } type matchRuleItem struct { key, value string } type MatchRuleBuilder struct { items []matchRuleItem } func (b *MatchRuleBuilder) addItem(k, v string) { b.items = append(b.items, matchRuleItem{k, v}) } func NewMatchRuleBuilder() *MatchRuleBuilder { return &MatchRuleBuilder{} } func (b *MatchRuleBuilder) Type(type0 string) *MatchRuleBuilder { b.addItem("type", type0) return b } func (b *MatchRuleBuilder) Path(path string) *MatchRuleBuilder { b.addItem("path", path) return b } func (b *MatchRuleBuilder) Sender(sender string) *MatchRuleBuilder { b.addItem("sender", sender) return b } func (b *MatchRuleBuilder) Interface(interface0 string) *MatchRuleBuilder { b.addItem("interface", interface0) return b } func (b *MatchRuleBuilder) Member(member string) *MatchRuleBuilder { b.addItem("member", member) return b } func (b *MatchRuleBuilder) PathNamespace(pathNamespace string) *MatchRuleBuilder { b.addItem("path_namespace", pathNamespace) return b } func (b *MatchRuleBuilder) Destination(destination string) *MatchRuleBuilder { b.addItem("destination", destination) return b } func (b *MatchRuleBuilder) Eavesdrop(eavesdrop bool) *MatchRuleBuilder { val := "false" if eavesdrop { val = "true" } b.addItem("eavesdrop", val) return b } func (b *MatchRuleBuilder) Arg(idx int, value string) *MatchRuleBuilder { b.addItem(fmt.Sprintf("arg%d", idx), value) return b } func (b *MatchRuleBuilder) ArgPath(idx int, path string) *MatchRuleBuilder { b.addItem(fmt.Sprintf("arg%dpath", idx), path) return b } func (b *MatchRuleBuilder) ArgNamespace(idx int, namespace string) *MatchRuleBuilder { b.addItem(fmt.Sprintf("arg%dnamespace", idx), namespace) return b } func (b *MatchRuleBuilder) ExtPropertiesChanged(path, interfaceName string) *MatchRuleBuilder { return b.Type("signal"). Path(path). Interface(orgFreedesktopDBus+".Properties"). Member("PropertiesChanged"). ArgNamespace(0, interfaceName) } func (b *MatchRuleBuilder) ExtSignal(path, interfaceName, name string) *MatchRuleBuilder { return b.Type("signal"). Path(path). Interface(interfaceName). Member(name) } func (b *MatchRuleBuilder) BuildStr() string { var buf bytes.Buffer for _, item := range b.items { buf.WriteString(item.key) buf.Write([]byte("='")) buf.WriteString(item.value) buf.Write([]byte("',")) } data := buf.Bytes() return string(data[:len(data)-1]) // remove tailing comma } func (b *MatchRuleBuilder) Build() MatchRule { return MatchRule{Str: b.BuildStr()} } go-lib-5.6.0.9/dbusutil/match_rule_test.go000664 000000 000000 00000002266 13753517240 020403 0ustar00rootroot000000 000000 package dbusutil import ( "testing" ) func TestMatchRuleBuilder(t *testing.T) { ruleStr := NewMatchRuleBuilder(). Type("t1"). Path("p1"). Sender("s1"). Interface("i1"). Member("m1"). PathNamespace("pns1"). Destination("d1"). Eavesdrop(false). Arg(1, "a1"). ArgPath(2, "a2path"). ArgNamespace(3, "a3ns").BuildStr() ruleExpected := "type='t1',path='p1',sender='s1',interface='i1',member='m1',path_namespace='pns1',destination='d1',eavesdrop='false',arg1='a1',arg2path='a2path',arg3namespace='a3ns'" if ruleStr != ruleExpected { t.Errorf("ruleStr expected %q got %q", ruleExpected, ruleStr) } ruleStr = NewMatchRuleBuilder().ExtSignal("/a/b/c", "a.b.c", "Sig1").BuildStr() ruleExpected = "type='signal',path='/a/b/c',interface='a.b.c',member='Sig1'" if ruleStr != ruleExpected { t.Errorf("ruleStr expected %q got %q", ruleExpected, ruleStr) } ruleStr = NewMatchRuleBuilder().ExtPropertiesChanged("/a/b/c", "a.b.c").BuildStr() ruleExpected = "type='signal',path='/a/b/c',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',arg0namespace='a.b.c'" if ruleStr != ruleExpected { t.Errorf("ruleStr expected %q got %q", ruleExpected, ruleStr) } } go-lib-5.6.0.9/dbusutil/object.go000664 000000 000000 00000005751 13753517240 016471 0ustar00rootroot000000 000000 package dbusutil import ( "errors" "github.com/godbus/dbus" ) type ServerObject struct { service *Service path dbus.ObjectPath implementers []*implementer } func (so *ServerObject) Path() dbus.ObjectPath { return so.path } func (so *ServerObject) Export() error { s := so.service conn := s.conn path := so.path s.mu.Lock() defer s.mu.Unlock() _, ok := s.objMap[path] if ok { return errors.New("server object is exported") } for _, impl := range so.implementers { core := impl.core corePtr := getImplementerPointer(core) _, ok := s.implObjMap[corePtr] if ok { return errors.New("implementer is exported") } err := conn.Export(core, so.path, core.GetInterfaceName()) if err != nil { return err } s.implObjMap[corePtr] = so } methodTable := make(map[string]interface{}, 3) methodTable["Introspect"] = so.introspectableIntrospect err := conn.ExportMethodTable(methodTable, so.path, orgFreedesktopDBus+".Introspectable") if err != nil { return err } delete(methodTable, "Introspect") methodTable["Get"] = so.propertiesGet methodTable["GetAll"] = so.propertiesGetAll methodTable["Set"] = so.propertiesSet err = conn.ExportMethodTable(methodTable, so.path, orgFreedesktopDBus+".Properties") if err != nil { return err } s.objMap[so.path] = so return nil } func (so *ServerObject) StopExport() error { s := so.service conn := s.conn path := so.path s.mu.Lock() defer s.mu.Unlock() _, ok := s.objMap[path] if !ok { return errors.New("server object is not exported") } err := conn.Export(nil, path, orgFreedesktopDBus+".Properties") if err != nil { return err } err = conn.Export(nil, path, orgFreedesktopDBus+".Introspectable") if err != nil { return err } for _, impl := range so.implementers { core := impl.core err := conn.Export(nil, so.path, core.GetInterfaceName()) if err != nil { return err } corePtr := getImplementerPointer(core) delete(s.implObjMap, corePtr) } delete(s.objMap, path) return nil } func (so *ServerObject) getImplementer(interfaceName string) *implementer { for _, impl := range so.implementers { if impl.core.GetInterfaceName() == interfaceName { return impl } } return nil } func (so *ServerObject) SetWriteCallback(v Implementer, propertyName string, cb PropertyWriteCallback) error { impl := so.getImplementer(v.GetInterfaceName()) if impl == nil { return errors.New("not exported") } return impl.setWriteCallback(propertyName, cb) } func (so *ServerObject) SetReadCallback(v Implementer, propertyName string, cb PropertyReadCallback) error { impl := so.getImplementer(v.GetInterfaceName()) if impl == nil { return errors.New("not exported") } return impl.setReadCallback(propertyName, cb) } func (so *ServerObject) ConnectChanged(v Implementer, propertyName string, cb PropertyChangedCallback) error { impl := so.getImplementer(v.GetInterfaceName()) if impl == nil { return errors.New("not exported") } return impl.connectChanged(propertyName, cb) } go-lib-5.6.0.9/dbusutil/properties.go000664 000000 000000 00000005321 13753517240 017410 0ustar00rootroot000000 000000 package dbusutil import ( "errors" "github.com/godbus/dbus" "github.com/godbus/dbus/prop" ) func (so *ServerObject) propertiesGet(sender dbus.Sender, interfaceName, propertyName string) (dbus.Variant, *dbus.Error) { so.service.DelayAutoQuit() impl := so.getImplementer(interfaceName) if impl == nil { return dbus.Variant{}, prop.ErrIfaceNotFound } p := impl.props[propertyName] if p == nil { return dbus.Variant{}, prop.ErrPropNotFound } implStatic := impl.getStatic(so.service) propStatic := implStatic.props[propertyName] if propStatic.access&accessRead == 0 { return dbus.Variant{}, dbus.MakeFailedError(errors.New("property can not be read")) } propRead := newPropertyRead(sender, so, interfaceName, propertyName) variant, err := p.GetValueVariant(propRead, propStatic.signature) if err != nil { return dbus.Variant{}, err } return variant, nil } func (so *ServerObject) propertiesGetAll(sender dbus.Sender, interfaceName string) (map[string]dbus.Variant, *dbus.Error) { so.service.DelayAutoQuit() impl := so.getImplementer(interfaceName) if impl == nil { return nil, prop.ErrIfaceNotFound } implStatic := impl.getStatic(so.service) result := make(map[string]dbus.Variant, len(impl.props)) for propName, p := range impl.props { propStatic := implStatic.props[propName] if propStatic.access&accessRead != 0 { propRead := newPropertyRead(sender, so, interfaceName, propName) variant, err := p.GetValueVariant(propRead, propStatic.signature) if err != nil { // ignore err continue } result[propName] = variant } } return result, nil } func (so *ServerObject) propertiesSet(sender dbus.Sender, interfaceName, propertyName string, newVar dbus.Variant) *dbus.Error { so.service.DelayAutoQuit() impl := so.getImplementer(interfaceName) if impl == nil { return prop.ErrIfaceNotFound } p := impl.props[propertyName] if p == nil { return prop.ErrPropNotFound } implStatic := impl.getStatic(so.service) propStatic := implStatic.props[propertyName] if propStatic.access&accessWrite == 0 { return dbus.MakeFailedError(errors.New("property can not be written")) } if newVar.Signature() != propStatic.signature { return prop.ErrInvalidArg } newVarValue := newVar.Value() //fix newVarValue []interface{} to struct if propStatic.hasStruct { fixedRV, err := valueFromBus(newVarValue, propStatic.rType) if err != nil { return dbus.MakeFailedError(err) } newVarValue = fixedRV.Interface() } propWrite := newPropertyWrite(sender, so, interfaceName, propertyName, newVarValue) changed, setErr := p.SetValue(propWrite) if setErr != nil { return setErr } if changed { impl.notifyChanged(so.service, so.path, p, propStatic, newVarValue) } return nil } go-lib-5.6.0.9/dbusutil/proxy/000775 000000 000000 00000000000 13753517240 016045 5ustar00rootroot000000 000000 go-lib-5.6.0.9/dbusutil/proxy/object.go000664 000000 000000 00000021107 13753517240 017643 0ustar00rootroot000000 000000 package proxy import ( "errors" "fmt" "sync" "github.com/godbus/dbus" "pkg.deepin.io/lib/dbusutil" ) type Object struct { obj dbus.BusObject conn *dbus.Conn mu sync.Mutex extraMap map[string]interface{} *objectSignalExt } func (o *Object) SetExtra(key string, v interface{}) { o.mu.Lock() if o.extraMap == nil { o.extraMap = make(map[string]interface{}) } o.extraMap[key] = v o.mu.Unlock() } func (o *Object) GetExtra(key string) (interface{}, bool) { o.mu.Lock() v, ok := o.extraMap[key] o.mu.Unlock() return v, ok } type objectSignalExt struct { sigLoop *dbusutil.SignalLoop ruleAuto bool // used when ruleAuto is true ruleHandlersMap map[string][]dbusutil.SignalHandlerId //nolint // ^rule ^handler ids // used when ruleAuto is false handleIds []dbusutil.SignalHandlerId //nolint: propChangedHandlerId dbusutil.SignalHandlerId //nolint: propChangedCallbacks map[propChangedKey][]PropChangedCallback //nolint: } type propChangedKey struct { interfaceName, propName string } type PropChangedCallback func(hasValue bool, value interface{}) func (o *Object) Init_(conn *dbus.Conn, serviceName string, path dbus.ObjectPath) { o.conn = conn o.obj = conn.Object(serviceName, path) } func (o *Object) Path_() dbus.ObjectPath { return o.obj.Path() } func (o *Object) ServiceName_() string { return o.obj.Destination() } func (o *Object) Go_(method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{}) *dbus.Call { return o.obj.Go(method, flags, ch, args...) } func (o *Object) GetProperty_(flags dbus.Flags, interfaceName, propName string, value interface{}) error { call := o.obj.Call("org.freedesktop.DBus.Properties.Get", flags, interfaceName, propName) return storeGetProperty(call, value) } func storeGetProperty(call *dbus.Call, value interface{}) error { var variant dbus.Variant err := call.Store(&variant) if err != nil { return err } return dbus.Store([]interface{}{variant.Value()}, value) } func (o *Object) SetProperty_(flags dbus.Flags, interfaceName, propName string, value interface{}) error { return o.obj.Call("org.freedesktop.DBus.Properties.Set", flags, interfaceName, propName, dbus.MakeVariant(value)).Err } func (o *Object) addRuleHandlerId(rule string, handlerId dbusutil.SignalHandlerId) { if o.ruleHandlersMap == nil { o.ruleHandlersMap = make(map[string][]dbusutil.SignalHandlerId) } o.ruleHandlersMap[rule] = append(o.ruleHandlersMap[rule], handlerId) } func (o *Object) getMatchRulePropertiesChanged() string { return fmt.Sprintf("type='signal',interface='org.freedesktop.DBus.Properties',"+ "member='PropertiesChanged',path='%s',sender='%s'", o.obj.Path(), o.obj.Destination()) } func (o *Object) propChangedHandler(sig *dbus.Signal) { var interfaceName string var changedProps map[string]dbus.Variant var invalidatedProps []string err := dbus.Store(sig.Body, &interfaceName, &changedProps, &invalidatedProps) if err != nil { return } for propName, variant := range changedProps { key := propChangedKey{interfaceName, propName} o.mu.Lock() callbacks := o.propChangedCallbacks[key] o.mu.Unlock() for _, callback := range callbacks { callback(true, variant.Value()) } } for _, propName := range invalidatedProps { key := propChangedKey{interfaceName, propName} o.mu.Lock() callbacks := o.propChangedCallbacks[key] o.mu.Unlock() for _, callback := range callbacks { callback(false, nil) } } } func (o *Object) initPropertiesChangedHandler() error { o.checkSignalExt() if o.propChangedHandlerId != 0 { return nil } var handlerId dbusutil.SignalHandlerId sigRule := &dbusutil.SignalRule{ Path: o.obj.Path(), Name: "org.freedesktop.DBus.Properties.PropertiesChanged", } if o.ruleAuto { rule := o.getMatchRulePropertiesChanged() err := o.addMatch(rule) if err != nil { return err } handlerId = o.sigLoop.AddHandler(sigRule, o.propChangedHandler) o.addRuleHandlerId(rule, handlerId) } else { handlerId = o.sigLoop.AddHandler(sigRule, o.propChangedHandler) } o.propChangedHandlerId = handlerId return nil } func (o *Object) ConnectPropertyChanged_(interfaceName, propName string, callback PropChangedCallback) error { o.mu.Lock() defer o.mu.Unlock() err := o.initPropertiesChangedHandler() if err != nil { return err } if o.propChangedCallbacks == nil { o.propChangedCallbacks = make(map[propChangedKey][]PropChangedCallback) } key := propChangedKey{interfaceName, propName} o.propChangedCallbacks[key] = append(o.propChangedCallbacks[key], callback) return nil } func (o *Object) checkSignalExt() { if o.objectSignalExt == nil { panic(fmt.Sprintf("you should call %T.InitSignalExt() first", o)) } } func (o *Object) addMatch(rule string) error { handlerIds := o.ruleHandlersMap[rule] if len(handlerIds) == 0 { return globalRuleCounter.addMatch(o.conn, rule) } return nil } func handlerIdSliceDelete(slice []dbusutil.SignalHandlerId, index int) []dbusutil.SignalHandlerId { return append(slice[:index], slice[index+1:]...) } func handlerIdSliceIndex(slice []dbusutil.SignalHandlerId, hId dbusutil.SignalHandlerId) int { for idx, value := range slice { if value == hId { return idx } } return -1 } func (o *Object) removeHandler(handlerId dbusutil.SignalHandlerId) { o.sigLoop.RemoveHandler(handlerId) if o.ruleAuto { for rule, handlerIds := range o.ruleHandlersMap { for idx, hId := range handlerIds { if hId == handlerId { if len(handlerIds) == 1 { _ = globalRuleCounter.removeMatch(o.conn, rule) } o.ruleHandlersMap[rule] = handlerIdSliceDelete(handlerIds, idx) return } } } } else { idx := handlerIdSliceIndex(o.handleIds, handlerId) if idx != -1 { o.handleIds = handlerIdSliceDelete(o.handleIds, idx) } } } func (o *Object) removePropertiesChangedHandler() { if o.propChangedHandlerId != 0 { o.removeHandler(o.propChangedHandlerId) o.propChangedHandlerId = 0 } } func (o *Object) removeAllHandlers() { if o.ruleAuto { for rule, handlerIds := range o.ruleHandlersMap { for _, hId := range handlerIds { o.sigLoop.RemoveHandler(hId) } _ = globalRuleCounter.removeMatch(o.conn, rule) } o.ruleHandlersMap = nil } else { for _, hId := range o.handleIds { o.sigLoop.RemoveHandler(hId) } } o.removePropertiesChangedHandler() } func (o *Object) ConnectSignal_(rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc) (dbusutil.SignalHandlerId, error) { o.mu.Lock() defer o.mu.Unlock() o.checkSignalExt() return o.connectSignal(rule, sigRule, cb) } func (o *Object) connectSignal(rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc) (dbusutil.SignalHandlerId, error) { if o.ruleAuto { err := o.addMatch(rule) if err != nil { return 0, err } handlerId := o.sigLoop.AddHandler(sigRule, cb) o.addRuleHandlerId(rule, handlerId) return handlerId, nil } else { handlerId := o.sigLoop.AddHandler(sigRule, cb) o.handleIds = append(o.handleIds, handlerId) return handlerId, nil } } // Object public methods: func (o *Object) InitSignalExt(sigLoop *dbusutil.SignalLoop, ruleAuto bool) { if o.conn != sigLoop.Conn() { panic("dbus conn not same") } o.mu.Lock() if o.objectSignalExt == nil { o.objectSignalExt = &objectSignalExt{ sigLoop: sigLoop, ruleAuto: ruleAuto, } } o.mu.Unlock() } const ( RemoveAllHandlers = -1 RemovePropertiesChangedHandler = -2 ) func (o *Object) RemoveAllHandlers() { o.removeAllHandlers() } func (o *Object) RemoveHandler(handlerId dbusutil.SignalHandlerId) { o.mu.Lock() defer o.mu.Unlock() o.checkSignalExt() switch handlerId { case RemoveAllHandlers: o.removeAllHandlers() case RemovePropertiesChangedHandler: o.removePropertiesChangedHandler() default: o.removeHandler(handlerId) } } func (o *Object) ConnectPropertiesChanged( cb func(interfaceName string, changedProperties map[string]dbus.Variant, invalidatedProperties []string)) (dbusutil.SignalHandlerId, error) { if cb == nil { return 0, errors.New("nil callback") } var rule string o.mu.Lock() defer o.mu.Unlock() o.checkSignalExt() if o.ruleAuto { rule = o.getMatchRulePropertiesChanged() } return o.connectSignal(rule, &dbusutil.SignalRule{ Path: o.obj.Path(), Name: "org.freedesktop.DBus.Properties.PropertiesChanged", }, func(sig *dbus.Signal) { var interfaceName string var changedProps map[string]dbus.Variant var invalidatedProps []string err := dbus.Store(sig.Body, &interfaceName, &changedProps, &invalidatedProps) if err == nil { cb(interfaceName, changedProps, invalidatedProps) } }) } type Implementer interface { GetObject_() *Object GetInterfaceName_() string } go-lib-5.6.0.9/dbusutil/proxy/prop.go000664 000000 000000 00000042002 13753517240 017352 0ustar00rootroot000000 000000 package proxy import "errors" import "github.com/godbus/dbus" var errNilCallback = errors.New("nil callback") type PropBool struct { Impl Implementer Name string } func (p PropBool) Get(flags dbus.Flags) (value bool, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropBool) Set(flags dbus.Flags, value bool) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropBool) ConnectChanged(cb func(hasValue bool, value bool)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(bool) if ok { cb(true, val) } } else { cb(false, false) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropString struct { Impl Implementer Name string } func (p PropString) Get(flags dbus.Flags) (value string, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropString) Set(flags dbus.Flags, value string) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropString) ConnectChanged(cb func(hasValue bool, value string)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(string) if ok { cb(true, val) } } else { cb(false, "") } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropObjectPath struct { Impl Implementer Name string } func (p PropObjectPath) Get(flags dbus.Flags) (value dbus.ObjectPath, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropObjectPath) Set(flags dbus.Flags, value dbus.ObjectPath) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropObjectPath) ConnectChanged(cb func(hasValue bool, value dbus.ObjectPath)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(dbus.ObjectPath) if ok { cb(true, val) } } else { cb(false, "") } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropDouble struct { Impl Implementer Name string } func (p PropDouble) Get(flags dbus.Flags) (value float64, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropDouble) Set(flags dbus.Flags, value float64) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropDouble) ConnectChanged(cb func(hasValue bool, value float64)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(float64) if ok { cb(true, val) } } else { cb(false, 0) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropByte struct { Impl Implementer Name string } func (p PropByte) Get(flags dbus.Flags) (value byte, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropByte) Set(flags dbus.Flags, value byte) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropByte) ConnectChanged(cb func(hasValue bool, value byte)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(byte) if ok { cb(true, val) } } else { cb(false, 0) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropInt16 struct { Impl Implementer Name string } func (p PropInt16) Get(flags dbus.Flags) (value int16, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropInt16) Set(flags dbus.Flags, value int16) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropInt16) ConnectChanged(cb func(hasValue bool, value int16)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(int16) if ok { cb(true, val) } } else { cb(false, 0) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropUint16 struct { Impl Implementer Name string } func (p PropUint16) Get(flags dbus.Flags) (value uint16, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropUint16) Set(flags dbus.Flags, value uint16) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropUint16) ConnectChanged(cb func(hasValue bool, value uint16)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(uint16) if ok { cb(true, val) } } else { cb(false, 0) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropInt32 struct { Impl Implementer Name string } func (p PropInt32) Get(flags dbus.Flags) (value int32, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropInt32) Set(flags dbus.Flags, value int32) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropInt32) ConnectChanged(cb func(hasValue bool, value int32)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(int32) if ok { cb(true, val) } } else { cb(false, 0) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropUint32 struct { Impl Implementer Name string } func (p PropUint32) Get(flags dbus.Flags) (value uint32, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropUint32) Set(flags dbus.Flags, value uint32) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropUint32) ConnectChanged(cb func(hasValue bool, value uint32)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(uint32) if ok { cb(true, val) } } else { cb(false, 0) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropInt64 struct { Impl Implementer Name string } func (p PropInt64) Get(flags dbus.Flags) (value int64, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropInt64) Set(flags dbus.Flags, value int64) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropInt64) ConnectChanged(cb func(hasValue bool, value int64)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(int64) if ok { cb(true, val) } } else { cb(false, 0) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropUint64 struct { Impl Implementer Name string } func (p PropUint64) Get(flags dbus.Flags) (value uint64, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropUint64) Set(flags dbus.Flags, value uint64) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropUint64) ConnectChanged(cb func(hasValue bool, value uint64)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.(uint64) if ok { cb(true, val) } } else { cb(false, 0) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropBoolArray struct { Impl Implementer Name string } func (p PropBoolArray) Get(flags dbus.Flags) (value []bool, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropBoolArray) Set(flags dbus.Flags, value []bool) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropBoolArray) ConnectChanged(cb func(hasValue bool, value []bool)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]bool) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropStringArray struct { Impl Implementer Name string } func (p PropStringArray) Get(flags dbus.Flags) (value []string, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropStringArray) Set(flags dbus.Flags, value []string) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropStringArray) ConnectChanged(cb func(hasValue bool, value []string)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]string) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropObjectPathArray struct { Impl Implementer Name string } func (p PropObjectPathArray) Get(flags dbus.Flags) (value []dbus.ObjectPath, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropObjectPathArray) Set(flags dbus.Flags, value []dbus.ObjectPath) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropObjectPathArray) ConnectChanged(cb func(hasValue bool, value []dbus.ObjectPath)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]dbus.ObjectPath) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropDoubleArray struct { Impl Implementer Name string } func (p PropDoubleArray) Get(flags dbus.Flags) (value []float64, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropDoubleArray) Set(flags dbus.Flags, value []float64) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropDoubleArray) ConnectChanged(cb func(hasValue bool, value []float64)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]float64) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropByteArray struct { Impl Implementer Name string } func (p PropByteArray) Get(flags dbus.Flags) (value []byte, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropByteArray) Set(flags dbus.Flags, value []byte) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropByteArray) ConnectChanged(cb func(hasValue bool, value []byte)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]byte) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropInt16Array struct { Impl Implementer Name string } func (p PropInt16Array) Get(flags dbus.Flags) (value []int16, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropInt16Array) Set(flags dbus.Flags, value []int16) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropInt16Array) ConnectChanged(cb func(hasValue bool, value []int16)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]int16) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropUint16Array struct { Impl Implementer Name string } func (p PropUint16Array) Get(flags dbus.Flags) (value []uint16, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropUint16Array) Set(flags dbus.Flags, value []uint16) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropUint16Array) ConnectChanged(cb func(hasValue bool, value []uint16)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]uint16) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropInt32Array struct { Impl Implementer Name string } func (p PropInt32Array) Get(flags dbus.Flags) (value []int32, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropInt32Array) Set(flags dbus.Flags, value []int32) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropInt32Array) ConnectChanged(cb func(hasValue bool, value []int32)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]int32) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropUint32Array struct { Impl Implementer Name string } func (p PropUint32Array) Get(flags dbus.Flags) (value []uint32, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropUint32Array) Set(flags dbus.Flags, value []uint32) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropUint32Array) ConnectChanged(cb func(hasValue bool, value []uint32)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]uint32) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropInt64Array struct { Impl Implementer Name string } func (p PropInt64Array) Get(flags dbus.Flags) (value []int64, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropInt64Array) Set(flags dbus.Flags, value []int64) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropInt64Array) ConnectChanged(cb func(hasValue bool, value []int64)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]int64) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } type PropUint64Array struct { Impl Implementer Name string } func (p PropUint64Array) Get(flags dbus.Flags) (value []uint64, err error) { err = p.Impl.GetObject_().GetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, &value) return } func (p PropUint64Array) Set(flags dbus.Flags, value []uint64) error { return p.Impl.GetObject_().SetProperty_(flags, p.Impl.GetInterfaceName_(), p.Name, value) } func (p PropUint64Array) ConnectChanged(cb func(hasValue bool, value []uint64)) error { if cb == nil { return errNilCallback } cb0 := func(hasValue bool, value interface{}) { if hasValue { val, ok := value.([]uint64) if ok { cb(true, val) } } else { cb(false, nil) } } return p.Impl.GetObject_().ConnectPropertyChanged_(p.Impl.GetInterfaceName_(), p.Name, cb0) } go-lib-5.6.0.9/dbusutil/proxy/rule_counter.go000664 000000 000000 00000003234 13753517240 021104 0ustar00rootroot000000 000000 package proxy import ( "errors" "sync" "github.com/godbus/dbus" ) var globalRuleCounter = &ruleCounter{ connRuleCount: make(map[string]map[string]uint), } type ruleCounter struct { connRuleCount map[string]map[string]uint // ^unique name ^rule mu sync.Mutex } func getConnName(conn *dbus.Conn) string { return conn.Names()[0] } func (rc *ruleCounter) addMatch(conn *dbus.Conn, rule string) error { name := getConnName(conn) if name == "" { return errors.New("conn name is empty") } rc.mu.Lock() defer rc.mu.Unlock() var count uint ruleCount, ok := rc.connRuleCount[name] if ok { count = ruleCount[rule] } else { ruleCount = make(map[string]uint) rc.connRuleCount[name] = ruleCount } if count == 0 { err := conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule).Err if err != nil { return err } } ruleCount[rule] = count + 1 return nil } func (rc *ruleCounter) removeMatch(conn *dbus.Conn, rule string) error { name := getConnName(conn) if name == "" { return errors.New("conn name is empty") } rc.mu.Lock() defer rc.mu.Unlock() var count uint ruleCount, ok := rc.connRuleCount[name] if !ok { return nil } count = ruleCount[rule] if count == 1 { err := conn.BusObject().Call("org.freedesktop.DBus.RemoveMatch", 0, rule).Err if err != nil { return err } } ruleCount[rule] = count - 1 return nil } func (rc *ruleCounter) deleteConn(conn *dbus.Conn) { rc.mu.Lock() delete(rc.connRuleCount, getConnName(conn)) rc.mu.Unlock() } // DeleteConn 删除连接相关的数据,可以在你关闭这个连接之后调用。 func DeleteConn(conn *dbus.Conn) { globalRuleCounter.deleteConn(conn) } go-lib-5.6.0.9/dbusutil/service.go000664 000000 000000 00000020274 13753517240 016660 0ustar00rootroot000000 000000 package dbusutil import ( "bytes" "errors" "fmt" "sort" "sync" "time" "unsafe" "github.com/godbus/dbus" "github.com/godbus/dbus/introspect" ) type Service struct { conn *dbus.Conn mu sync.RWMutex hasCall bool quit chan struct{} canQuit func() bool quitCheckInterval time.Duration objMap map[dbus.ObjectPath]*ServerObject implStaticMap map[string]*implementerStatic // ^interface name implObjMap map[unsafe.Pointer]*ServerObject } func NewService(conn *dbus.Conn) *Service { return &Service{ conn: conn, objMap: make(map[dbus.ObjectPath]*ServerObject), implStaticMap: make(map[string]*implementerStatic), implObjMap: make(map[unsafe.Pointer]*ServerObject), } } func NewSessionService() (*Service, error) { bus, err := dbus.SessionBus() if err != nil { return nil, err } return NewService(bus), nil } func NewSystemService() (*Service, error) { bus, err := dbus.SystemBus() if err != nil { return nil, err } return NewService(bus), nil } func (s *Service) Conn() *dbus.Conn { return s.conn } func (s *Service) RequestName(name string) error { reply, err := s.conn.RequestName(name, dbus.NameFlagDoNotQueue) if err != nil { return err } if reply != dbus.RequestNameReplyPrimaryOwner { return fmt.Errorf("name %s already taken", name) } return nil } func (s *Service) ReleaseName(name string) error { _, err := s.conn.ReleaseName(name) return err } func (s *Service) NewServerObject(path dbus.ObjectPath, implementers ...Implementer) (*ServerObject, error) { if !path.IsValid() { return nil, errors.New("path invalid") } if len(implementers) == 0 { return nil, errors.New("no implementer") } implMap := make(map[string]Implementer) implSlice := make([]*implementer, 0, len(implementers)) for _, implCore := range implementers { ifcName := implCore.GetInterfaceName() _, ok := implMap[ifcName] if ok { return nil, errors.New("interface duplicated") } impl, err := newImplementer(implCore, s, path) if err != nil { return nil, err } implSlice = append(implSlice, impl) implMap[ifcName] = implCore } obj := &ServerObject{ service: s, path: path, implementers: implSlice, } return obj, nil } func (s *Service) GetServerObject(impl Implementer) *ServerObject { ptr := getImplementerPointer(impl) s.mu.RLock() so := s.implObjMap[ptr] s.mu.RUnlock() return so } func (s *Service) GetServerObjectByPath(path dbus.ObjectPath) *ServerObject { s.mu.RLock() so := s.objMap[path] s.mu.RUnlock() return so } func (s *Service) Export(path dbus.ObjectPath, implements ...Implementer) error { so, err := s.NewServerObject(path, implements...) if err != nil { return err } return so.Export() } func (s *Service) StopExport(impl Implementer) error { so := s.GetServerObject(impl) if so == nil { return errors.New("server object not found") } return so.StopExport() } func (s *Service) StopExportByPath(path dbus.ObjectPath) error { so := s.GetServerObjectByPath(path) if so == nil { return errors.New("server object not found") } return so.StopExport() } func (s *Service) IsExported(impl Implementer) bool { so := s.GetServerObject(impl) return so != nil } func (s *Service) getImplementerStatic(impl Implementer) *implementerStatic { ifcName := impl.GetInterfaceName() s.mu.RLock() implStatic := s.implStaticMap[ifcName] s.mu.RUnlock() return implStatic } func (s *Service) Emit(v Implementer, signalName string, values ...interface{}) error { so := s.GetServerObject(v) if so == nil { return errors.New("v is not exported") } implStatic := s.getImplementerStatic(v) var signal introspect.Signal for _, sig := range implStatic.introspectInterface.Signals { if sig.Name == signalName { signal = sig break } } if signal.Name == "" { return errors.New("not found signal") } if len(values) != len(signal.Args) { return errors.New("signal args length not equal") } for idx, arg := range signal.Args { valueType := dbus.SignatureOf(values[idx]).String() if valueType != arg.Type { return fmt.Errorf("signal arg[%d] type not match", idx) } } return s.conn.Emit(so.path, v.GetInterfaceName()+"."+signalName, values...) } func (s *Service) EmitPropertyChanged(v Implementer, propertyName string, value interface{}) error { so := s.GetServerObject(v) if so == nil { return errors.New("v is not exported") } impl := so.getImplementer(v.GetInterfaceName()) implStatic := s.getImplementerStatic(v) err := implStatic.checkPropertyValue(propertyName, value) if err != nil { return err } return impl.emitPropChanged(s, so.path, propertyName, value) } func (s *Service) DelayEmitPropertyChanged(v Implementer) func() error { so := s.GetServerObject(v) if so == nil { return nil } impl := so.getImplementer(v.GetInterfaceName()) if impl == nil { return nil } impl.delayEmitPropChanged() return func() error { return impl.stopDelayEmitPropChanged(s, so.path) } } func (s *Service) EmitPropertiesChanged(v Implementer, propValMap map[string]interface{}, invalidatedProps ...string) error { so := s.GetServerObject(v) if so == nil { return errors.New("v is not exported") } implStatic := s.getImplementerStatic(v) const signalName = orgFreedesktopDBus + ".Properties.PropertiesChanged" var changedProps map[string]dbus.Variant if len(propValMap) > 0 { changedProps = make(map[string]dbus.Variant) } for propName, val := range propValMap { err := implStatic.checkPropertyValue(propName, val) if err != nil { return err } changedProps[propName] = dbus.MakeVariant(val) } for _, propName := range invalidatedProps { if _, ok := propValMap[propName]; ok { return errors.New("property appears in both propValMap and invalidateProps") } err := implStatic.checkProperty(propName) if err != nil { return err } } return s.conn.Emit(so.path, signalName, v.GetInterfaceName(), changedProps, invalidatedProps) } func (s *Service) Quit() { s.conn.Close() close(s.quit) } func (s *Service) Wait() { s.quit = make(chan struct{}) if s.quitCheckInterval > 0 { go func() { ticker := time.NewTicker(s.quitCheckInterval) for { select { case <-s.quit: return case <-ticker.C: s.mu.RLock() hasCall := s.hasCall s.mu.RUnlock() logger.Println("Service.Wait tick hasCall:", hasCall) if !hasCall { if s.canQuit == nil || s.canQuit() { s.Quit() return } } else { s.mu.Lock() s.hasCall = false s.mu.Unlock() } } } }() } <-s.quit } func (s *Service) DelayAutoQuit() { s.mu.Lock() s.hasCall = true s.mu.Unlock() } func (s *Service) SetAutoQuitHandler(interval time.Duration, canQuit func() bool) { s.quitCheckInterval = interval s.canQuit = canQuit } func (s *Service) GetConnPID(name string) (pid uint32, err error) { err = s.conn.BusObject().Call(orgFreedesktopDBus+".GetConnectionUnixProcessID", 0, name).Store(&pid) return } func (s *Service) GetConnUID(name string) (uid uint32, err error) { err = s.conn.BusObject().Call(orgFreedesktopDBus+".GetConnectionUnixUser", 0, name).Store(&uid) return } func (s *Service) GetNameOwner(name string) (owner string, err error) { err = s.conn.BusObject().Call(orgFreedesktopDBus+".GetNameOwner", 0, name).Store(&owner) return } func (s *Service) NameHasOwner(name string) (hasOwner bool, err error) { err = s.conn.BusObject().Call(orgFreedesktopDBus+".NameHasOwner", 0, name).Store(&hasOwner) return } func (s *Service) DumpProperties(v Implementer) (string, error) { so := s.GetServerObject(v) if so == nil { return "", errors.New("not exported") } impl := so.getImplementer(v.GetInterfaceName()) implStatic := impl.getStatic(s) var buf bytes.Buffer var propNames []string for name := range impl.props { propNames = append(propNames, name) } sort.Strings(propNames) for _, name := range propNames { p := impl.props[name] fmt.Fprintln(&buf, "property name:", name) fmt.Fprintf(&buf, "valueMu: %p\n", p.valueMu) propStatic := implStatic.props[name] fmt.Fprintln(&buf, "signature:", propStatic.signature) fmt.Fprintln(&buf, "access:", propStatic.access) fmt.Fprintln(&buf, "emit:", propStatic.emit) buf.WriteString("\n") } return buf.String(), nil } go-lib-5.6.0.9/dbusutil/service_test.go000664 000000 000000 00000102623 13753517240 017716 0ustar00rootroot000000 000000 package dbusutil import ( "errors" "os" "reflect" "strings" "sync" "testing" "time" "github.com/godbus/dbus" ) func TestService_GetNameOwner(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } owner, err := service.GetNameOwner(orgFreedesktopDBus) if err != nil { t.Error("Unexpected error calling GetNameOwner:", err) } if owner != orgFreedesktopDBus { t.Errorf("expected owner %q got %q", orgFreedesktopDBus, owner) } _, err = service.GetNameOwner("xxx.yyy.zzz.123") if err == nil { t.Error("Expected error due to service xxx.yyy.zzz.123 not exist") } } func TestService_NameHasOwner(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } hasOwner, err := service.NameHasOwner(orgFreedesktopDBus) if err != nil { t.Error("Unexpected error calling NameHasOwner:", err) } if !hasOwner { t.Error("hasOwner expected true") } hasOwner, err = service.NameHasOwner("xxx.yyy.zzz.123") if err != nil { t.Error("Unexpected error calling NameHasOwner:", err) } if hasOwner { t.Error("hasOwner expected false") } } func TestService_RequestName(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } const name = "com.deepin.lib.RequestName" err = service.RequestName(name) if err != nil { t.Error("Unexpected error calling RequestName:", err) } err = service.ReleaseName(name) if err != nil { t.Error("Unexpected error calling ReleaseName:", err) } } //nolint type srvObject1 struct { methods *struct { Method1 func() `out:"num"` } } func (*srvObject1) GetInterfaceName() string { return "com.deepin.lib.Object1" } func (*srvObject1) Method1() (int, *dbus.Error) { return 1, nil } type srvObject12 struct{} func (srvObject12) GetInterfaceName() string { return "com.deepin.lib.Object12" } type srvString string func (srvString) GetInterfaceName() string { return "com.deepin.lib.String" } func TestService_Export(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj1 := &srvObject1{} err = service.Export("/com/deepin/lib/Object1", srvObj1) if err != nil { t.Error("Unexpected error exporting srvObj1:", err) } err = service.RequestName("com.deepin.lib.Object1") if err != nil { t.Error("Unexpected error calling RequestName:", err) } clientObj1 := service.conn.Object("com.deepin.lib.Object1", "/com/deepin/lib/Object1") var num int err = clientObj1.Call("com.deepin.lib.Object1.Method1", 0).Store(&num) if err != nil { t.Error("Unexpected error calling srvObj1.Method1:", err) } if num != 1 { t.Errorf("expect 1 but got %d", num) } if !service.IsExported(srvObj1) { t.Error("IsExported expected true") } _ = service.StopExport(srvObj1) if service.IsExported(srvObj1) { t.Error("IsExported expected false") } srvObj12 := srvObject12{} err = service.Export("/com/deepin/lib/Object12", srvObj12) if err == nil { t.Error("Expected error due to srvObj12 is not a struct pointer") } srvStr := srvString("hello") err = service.Export("/com/deepin/lib/String", srvStr) if err == nil { t.Error("Expected error due to srvStr is not a struct pointer") } } //nolint type srvObject2 struct { signals *struct { Signal1 struct{} Signal2 struct { Arg1 string Arg2 uint32 } } } func (*srvObject2) GetInterfaceName() string { return "com.deepin.lib.Object2" } func processSignal(conn *dbus.Conn, fn func(signal *dbus.Signal) bool) { signalChan := make(chan *dbus.Signal, 10) conn.Signal(signalChan) for sig := range signalChan { shouldContinue := fn(sig) if !shouldContinue { break } } conn.RemoveSignal(signalChan) close(signalChan) } func TestService_Emit(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj2 := &srvObject2{} const srvObj2Path = "/com/deepin/lib/Object2" err = service.Export(srvObj2Path, srvObj2) if err != nil { t.Error("Unexpected error exporting srvObj2:", err) } // Test Signal1 // rule for watch Signal1 ruleSig1 := NewMatchRuleBuilder().ExtSignal(srvObj2Path, srvObj2.GetInterfaceName(), "Signal1").Build() err = ruleSig1.AddTo(service.conn) if err != nil { t.Error("unaxpected error adding match rule:", err) } ch1 := make(chan int) go processSignal(service.conn, func(sig *dbus.Signal) bool { if sig.Name == "com.deepin.lib.Object2.Signal1" && sig.Path == "/com/deepin/lib/Object2" { ch1 <- 1 if len(sig.Body) != 0 { t.Errorf("len(sig.Body) expected 0 got %d", len(sig.Body)) } return false } return true }) err = service.Emit(srvObj2, "Signal1") if err != nil { t.Error("Unexpected error emitting Sig1:", err) } select { case <-ch1: close(ch1) case <-time.After(30 * time.Second): t.Errorf("Failed to announce that the Signal1 was emitted") } err = ruleSig1.RemoveFrom(service.conn) if err != nil { t.Error("Unexpected error removing match rule:", err) } // Test Signal2 // rule for watch Signal2 ruleSig2 := NewMatchRuleBuilder().ExtSignal(srvObj2Path, srvObj2.GetInterfaceName(), "Signal2").Build() err = ruleSig2.AddTo(service.conn) if err != nil { t.Error("unaxpected error adding match rule:", err) } ch2 := make(chan int) go processSignal(service.conn, func(sig *dbus.Signal) bool { if sig.Name == "com.deepin.lib.Object2.Signal2" && sig.Path == "/com/deepin/lib/Object2" { ch2 <- 1 expectedBody := []interface{}{"hello", uint32(1)} if !reflect.DeepEqual(sig.Body, expectedBody) { t.Errorf("sig.Body expected %#v got %#v", expectedBody, sig.Body) } return false } return true }) err = service.Emit(srvObj2, "Signal2", "hello", uint32(1)) if err != nil { t.Error("Unexpected error emitting Sig2:", err) } select { case <-ch2: close(ch2) case <-time.After(30 * time.Second): t.Errorf("Failed to announce that the Signal2 was emitted") } err = ruleSig2.RemoveFrom(service.conn) if err != nil { t.Error("Unexpected error removing match rule:", err) } err = service.Emit(srvObj2, "Signal3") if err == nil { t.Error("Expected error due to srvObj2 don't have signal Signal3") } err = service.Emit(srvObj2, "Signal2") if err == nil { t.Error("Expected error due to Signal2 signature not match") } err = service.Emit(srvObj2, "Signal2", byte(1), uint32(1)) if err == nil { t.Error("Expected error due to Signal2 signature not match") } } type srvObject3 struct { PropsMu sync.RWMutex Prop1 string Prop2 uint32 } func (*srvObject3) GetInterfaceName() string { return "com.deepin.lib.Object3" } var serviceEmitPropertyChangedTests = []struct { PropName string Value interface{} Err bool FailMsg string }{ {"Prop1", "abc", false, "Unexpected error emitting property Prop1 changed"}, {"Prop2", uint32(1), false, "Unexpected error emitting property Prop2 changed"}, {"Prop3", "", true, "Expected error due to property Prop2 doest not exist"}, {"Prop1", 0, true, "Expected error due to type of Prop1 is not int"}, {"Prop2", "abc", true, "Expected error due to type of Prop2 is not string"}, } func TestService_EmitPropertyChanged(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj3 := &srvObject3{} const srvObj3Path = "/com/deepin/lib/Object3" err = service.Export(srvObj3Path, srvObj3) if err != nil { t.Error("Unexpected error exporting srvObj3:", err) } // rule for watch PropertiesChanged signal rule := NewMatchRuleBuilder().ExtPropertiesChanged(srvObj3Path, srvObj3.GetInterfaceName()).Build() err = rule.AddTo(service.conn) if err != nil { t.Error("Unexpected error adding match rule:", err) } for _, testCase := range serviceEmitPropertyChangedTests { ch := make(chan int) if !testCase.Err { go processSignal(service.conn, func(sig *dbus.Signal) bool { propName := testCase.PropName if sig.Path == "/com/deepin/lib/Object3" && sig.Name == "org.freedesktop.DBus.Properties.PropertiesChanged" { ch <- 1 propVarMap := sig.Body[1].(map[string]dbus.Variant) _, ok := propVarMap[propName] if !ok { t.Error("propVarMap expected has key:", propName) } return false } return true }) } err = service.EmitPropertyChanged(srvObj3, testCase.PropName, testCase.Value) if testCase.Err { if err == nil { t.Error(testCase) } } else { if err != nil { t.Error(testCase) } select { case <-ch: close(ch) case <-time.After(5 * time.Second): t.Error("Failed to announce that the PropertiesChanged signal was emitted") } } } err = rule.RemoveFrom(service.conn) if err != nil { t.Error("Unexpected error removing match rule:", err) } } type srvObject4 struct { PropsMu sync.RWMutex Prop1 string Prop2 uint32 } func (*srvObject4) GetInterfaceName() string { return "com.deepin.lib.Object4" } var serviceEmitPropertiesChangedTest = []struct { propValueMap map[string]interface{} invalidateProps []string Err bool FailMsg string }{ { map[string]interface{}{ "Prop1": "abc", "Prop2": uint32(0), }, nil, false, "Unexpected error emitting properties changed", }, { map[string]interface{}{ "Prop1": "abc", }, []string{"Prop2"}, false, "Unexpected error emitting properties changed", }, { nil, nil, false, "Unexpected error emitting empty properties changed", }, { map[string]interface{}{ "Prop1": "abc", "Prop3": 1, }, []string{"Prop2"}, true, "Expected error due to property Prop3 does not exist", }, { map[string]interface{}{ "Prop1": "abc", }, []string{"Prop2", "Prop4"}, true, "Expected error due to property Prop4 does not exist", }, { map[string]interface{}{ "Prop1": uint32(1), }, []string{"Prop2"}, true, "Expected error due to type of property Prop1 is not uint32", }, { map[string]interface{}{ "Prop1": uint32(1), }, []string{"Prop1"}, true, "Expected error due to Prop1 appears in both propValueMap and invalidateProps", }, } func TestService_EmitPropertiesChanged(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj4 := &srvObject4{} err = service.Export("/com/deepin/lib/Object4", srvObj4) if err != nil { t.Error("Unexpected error exporting srvObj4:", err) } for _, testCase := range serviceEmitPropertiesChangedTest { err = service.EmitPropertiesChanged(srvObj4, testCase.propValueMap, testCase.invalidateProps...) if testCase.Err { if err == nil { t.Error(testCase) } } else { if err != nil { t.Error(testCase) } } } } type srvObject5 struct { s *Service } func (*srvObject5) GetInterfaceName() string { return "com.deepin.lib.Object5" } func (obj *srvObject5) Method1() *dbus.Error { obj.s.DelayAutoQuit() return nil } func TestService_AutoQuit(t *testing.T) { ch := make(chan struct{}) bus, err := dbus.SessionBusPrivate() if err != nil { t.Error("Unexpected error connecting to session bus:", err) } err = bus.Auth(nil) if err != nil { t.Error("Unexpected error auth for bus:", err) } err = bus.Hello() if err != nil { t.Error("Unexpected error say Hello:", err) } service := NewService(bus) srvObj5 := &srvObject5{ s: service, } err = service.Export("/com/deepin/lib/Object5", srvObj5) if err != nil { t.Error("Unexpected error exporting srvObj5:", err) } err = service.RequestName("com.deepin.lib.Object5") if err != nil { t.Error("Unexpected error calling RequestName:", err) } service.SetAutoQuitHandler(100*time.Millisecond, func() bool { return true }) go func() { service.Wait() ch <- struct{}{} }() go func() { clientObj5 := service.conn.Object("com.deepin.lib.Object5", "/com/deepin/lib/Object5") for i := 0; i < 5; i++ { err = clientObj5.Call("com.deepin.lib.Object5.Method1", 0).Err if err != nil { t.Error("Unexpected error calling srvObject5.Method1") } t.Log("call Method1") } }() select { case <-ch: // ok close(ch) case <-time.After(5 * time.Second): t.Error("Failed to announce that the service has quit") } } func TestService_GetConnPIDAndUID(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } names := service.conn.Names() uniqueName := names[0] t.Log(uniqueName) pid, err := service.GetConnPID(uniqueName) if err != nil { t.Error("Unexpected error calling GetConnPID:", err) } if int(pid) != os.Getpid() { t.Errorf("pid expected %d, got %d", os.Getpid(), pid) } uid, err := service.GetConnUID(uniqueName) if err != nil { t.Error("Unexpected error calling GetConnUID:", err) } if int(uid) != os.Getuid() { t.Errorf("uid expected %d, got %d", os.Getuid(), uid) } } type srvObject6 struct { Prop1 string prop1ReadCount int } func (*srvObject6) GetInterfaceName() string { return "com.deepin.lib.Object6" } func TestService_SetReadCallback(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj6 := &srvObject6{ Prop1: "apple", } serverObject6, err := service.NewServerObject("/com/deepin/lib/Object6", srvObj6) if err != nil { t.Error("Unexpected error:", err) } err = serverObject6.SetReadCallback(srvObj6, "Prop1", func(read *PropertyRead) *dbus.Error { srvObj6.prop1ReadCount++ return nil }) if err != nil { t.Error("Unexpected error set read callabck for Prop1:", err) } err = serverObject6.Export() if err != nil { t.Error("Unexpected error exporting srvObj6:", err) } err = service.RequestName("com.deepin.lib.Object6") if err != nil { t.Error("Unexpected error calling RequestName:", err) } clientObj6 := service.conn.Object("com.deepin.lib.Object6", "/com/deepin/lib/Object6") var prop1Value interface{} err = clientObj6.Call(orgFreedesktopDBus+".Properties.Get", 0, "com.deepin.lib.Object6", "Prop1").Store(&prop1Value) if err != nil { t.Error("Unexpected error getting Prop1 value") } if prop1ValStr, ok := prop1Value.(string); !ok { t.Error("prop1Value is not string") } else { if prop1ValStr != "apple" { t.Errorf("prop1ValStr expected %q, got %q", "abcdef", prop1ValStr) } } if srvObj6.prop1ReadCount != 1 { t.Errorf("prop1ReadCount expected 1, got %d", srvObj6.prop1ReadCount) } _ = serverObject6.SetReadCallback(srvObj6, "Prop1", func(read *PropertyRead) *dbus.Error { srvObj6.prop1ReadCount++ return dbus.MakeFailedError(errors.New("xxx err msg")) }) err = clientObj6.Call(orgFreedesktopDBus+".Properties.Get", 0, "com.deepin.lib.Object6", "Prop1").Store(&prop1Value) if err == nil { t.Error("Expected error due to read callback return error") } if srvObj6.prop1ReadCount != 2 { t.Errorf("prop1ReadCount expected 2, got %d", srvObj6.prop1ReadCount) } } type srvObject7 struct { Prop1 string `prop:"access:rw"` prop1WriteCount int } func (*srvObject7) GetInterfaceName() string { return "com.deepin.lib.Object7" } func TestService_SetWriteCallback(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj7 := &srvObject7{ Prop1: "apple", } serverObject7, err := service.NewServerObject("/com/deepin/lib/Object7", srvObj7) if err != nil { t.Error("Unexpected error:", err) } err = serverObject7.SetWriteCallback(srvObj7, "Prop1", func(write *PropertyWrite) *dbus.Error { srvObj7.prop1WriteCount++ return nil }) if err != nil { t.Error("Unexpected error set write callabck for Prop1:", err) } err = serverObject7.Export() if err != nil { t.Error("Unexpected error exporting srvObj7:", err) } err = service.RequestName("com.deepin.lib.Object7") if err != nil { t.Error("Unexpected error calling RequestName:", err) } clientObj7 := service.conn.Object("com.deepin.lib.Object7", "/com/deepin/lib/Object7") err = clientObj7.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object7", "Prop1", dbus.MakeVariant("orange")).Err if err != nil { t.Error("Unexpected error setting prop1 value:", err) } if srvObj7.prop1WriteCount != 1 { t.Errorf("prop1WriteCount expected 1, got %d", srvObj7.prop1WriteCount) } if srvObj7.Prop1 != "orange" { t.Errorf("prop1 expected %q, got %q", "orange", srvObj7.Prop1) } err = serverObject7.SetWriteCallback(srvObj7, "Prop1", func(write *PropertyWrite) *dbus.Error { srvObj7.prop1WriteCount++ return dbus.MakeFailedError(errors.New("xxx err msg")) }) if err != nil { t.Error("Unexpected error set write callabck for Prop1:", err) } err = clientObj7.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object7", "Prop1", dbus.MakeVariant("banana")).Err if err == nil { t.Error("Expected error due to write callback return error:") } if srvObj7.prop1WriteCount != 2 { t.Errorf("prop1WriteCount expected 1, got %d", srvObj7.prop1WriteCount) } if srvObj7.Prop1 != "orange" { t.Errorf("prop1 expected %q, got %q", "orange", srvObj7.Prop1) } } type srvObject8 struct { Prop1 string `prop:"access:rw"` changedCountA int changedCountB int } func (*srvObject8) GetInterfaceName() string { return "com.deepin.lib.Object8" } func TestService_ConnectChanged(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj8 := &srvObject8{ Prop1: "apple", } serverObject8, err := service.NewServerObject("/com/deepin/lib/Object8", srvObj8) if err != nil { t.Error("Unexpected error:", err) } err = serverObject8.ConnectChanged(srvObj8, "Prop1", func(change *PropertyChanged) { srvObj8.changedCountA++ }) if err != nil { t.Error("Unexpected error set write callabck for Prop1:", err) } err = serverObject8.ConnectChanged(srvObj8, "Prop1", func(change *PropertyChanged) { srvObj8.changedCountB += 2 }) if err != nil { t.Error("Unexpected error set write callabck for Prop1:", err) } err = serverObject8.Export() if err != nil { t.Error("Unexpected error exporting srvObj8:", err) } err = service.RequestName("com.deepin.lib.Object8") if err != nil { t.Error("Unexpected error calling RequestName:", err) } clientObj8 := service.conn.Object("com.deepin.lib.Object8", "/com/deepin/lib/Object8") err = clientObj8.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object8", "Prop1", dbus.MakeVariant("banana")).Err if err != nil { t.Error("Unexpected error setting prop1 value:", err) } if srvObj8.changedCountA != 1 { t.Errorf("changedCountA expected 1, got %d", srvObj8.changedCountA) } if srvObj8.changedCountB != 2 { t.Errorf("changedCountB expected 2, got %d", srvObj8.changedCountB) } if srvObj8.Prop1 != "banana" { t.Errorf("prop1 expected %q, got %q", "123abc", srvObj8.Prop1) } // Set the same value to Prop1 again err = clientObj8.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object8", "Prop1", dbus.MakeVariant("banana")).Err if err != nil { t.Error("Unexpected error setting prop1 value:", err) } if srvObj8.changedCountA != 1 { t.Errorf("changedCountA expected 1, got %d", srvObj8.changedCountA) } if srvObj8.changedCountB != 2 { t.Errorf("changedCountB expected 2, got %d", srvObj8.changedCountB) } } type srvObject9 struct { Prop0 int32 `prop:"-"` Prop1 int32 `prop:"access:rw"` Prop2 int32 `prop:"access:r"` Prop3 int32 `prop:"access:w"` Prop4 int32 `prop:"access:rw,emit:true"` Prop5 int32 `prop:"access:rw,emit:invalidates"` Prop6 int32 `prop:"access:rw,emit:false"` } func (*srvObject9) GetInterfaceName() string { return "com.deepin.lib.Object9" } func TestService_PropTag(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj9 := &srvObject9{ Prop0: 11, Prop1: 1, Prop2: 2, Prop3: 3, } const srvObj9Path = "/com/deepin/lib/Object9" err = service.Export(srvObj9Path, srvObj9) if err != nil { t.Error("Unexpected error exporting srvObj9:", err) } err = service.RequestName("com.deepin.lib.Object9") if err != nil { t.Error("Unexpected error calling RequestName:", err) } clientObj9 := service.conn.Object("com.deepin.lib.Object9", "/com/deepin/lib/Object9") // prop0 ignored _, err = clientObj9.GetProperty("com.deepin.lib.Object9.Prop0") if err == nil { t.Error("Expected error due to Prop0 should be ignored") } else { if !strings.Contains(err.Error(), "PropertyNotFound") { t.Error("Expected error is PropertyNotFound") } } // prop1 access rw - readwrite err = clientObj9.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object9", "Prop1", dbus.MakeVariant(int32(11))).Err if err != nil { t.Error("Unexpected error setting Prop1 value:", err) } if srvObj9.Prop1 != 11 { t.Errorf("prop1 expected 11 got %d", srvObj9.Prop1) } var prop1Value uint32 err = clientObj9.Call(orgFreedesktopDBus+".Properties.Get", 0, "com.deepin.lib.Object9", "Prop1").Store(&prop1Value) if err != nil { t.Error("Unexpected error getting Prop1 value:", err) } if prop1Value != 11 { t.Errorf("prop1Value expected 11, got %d", prop1Value) } // prop2 access r - read only var prop2Value uint32 err = clientObj9.Call(orgFreedesktopDBus+".Properties.Get", 0, "com.deepin.lib.Object9", "Prop2").Store(&prop2Value) if err != nil { t.Error("Unexpected error getting Prop2 value:", err) } if prop2Value != 2 { t.Errorf("prop2Value expected 2, got %d", prop2Value) } err = clientObj9.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object9", "Prop2", dbus.MakeVariant(int32(12))).Err if err == nil { t.Error("Expected error due to Prop2 read only") } // prop3 access w - write only err = clientObj9.Call(orgFreedesktopDBus+".Properties.Get", 0, "com.deepin.lib.Object9", "Prop3").Err if err == nil { t.Error("Expected error due to Prop2 write only") } err = clientObj9.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object9", "Prop3", dbus.MakeVariant(int32(13))).Err if err != nil { t.Error("Unexpected error setting Prop3 value:", err) } if srvObj9.Prop3 != 13 { t.Errorf("prop3 expected 13 got %d", srvObj9.Prop3) } // rule for watch PropertiesChanged signal rulePC := NewMatchRuleBuilder().ExtPropertiesChanged(srvObj9Path, srvObj9.GetInterfaceName()).Build() _ = rulePC.AddTo(service.conn) // Test Prop4 emit: true chP4 := make(chan int) go processSignal(service.conn, func(sig *dbus.Signal) bool { if sig.Name == "org.freedesktop.DBus.Properties.PropertiesChanged" && sig.Path == "/com/deepin/lib/Object9" { chP4 <- 1 interfaceName := sig.Body[0].(string) expectedInterface := "com.deepin.lib.Object9" if interfaceName != expectedInterface { t.Errorf("interfaceName expected %q got %q", expectedInterface, interfaceName) } propVarMap := sig.Body[1].(map[string]dbus.Variant) variant, ok := propVarMap["Prop4"] if !ok { t.Error("propVarMap expected has key Prop4") } val := variant.Value().(int32) if val != 14 { t.Errorf("val expected 14 got %d", variant.Value()) } return false } return true }) err = clientObj9.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object9", "Prop4", dbus.MakeVariant(int32(14))).Err if err != nil { t.Error("Unexpected error setting Prop3 value:", err) } if srvObj9.Prop4 != 14 { t.Errorf("prop4 expected 4 got %d", srvObj9.Prop4) } select { case <-chP4: close(chP4) case <-time.After(5 * time.Second): t.Error("Failed to announce that the Prop4 PropertyChanged signal emitted") } // Test Prop5 emit: invalidates chP5 := make(chan int) go processSignal(service.conn, func(sig *dbus.Signal) bool { if sig.Name == "org.freedesktop.DBus.Properties.PropertiesChanged" && sig.Path == "/com/deepin/lib/Object9" { chP5 <- 1 interfaceName := sig.Body[0].(string) expectedInterface := "com.deepin.lib.Object9" if interfaceName != expectedInterface { t.Errorf("interfaceName expected %q got %q", expectedInterface, interfaceName) } propVarMap := sig.Body[1].(map[string]dbus.Variant) if len(propVarMap) != 0 { t.Errorf("len(propVarMap) expected 0 got %d", len(propVarMap)) } invalidatesProps := sig.Body[2].([]string) expectedProps := []string{"Prop5"} if !reflect.DeepEqual(invalidatesProps, expectedProps) { t.Errorf("invalidatesProps expected %#v got %#v", expectedProps, invalidatesProps) } return false } return true }) err = clientObj9.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object9", "Prop5", dbus.MakeVariant(int32(15))).Err if err != nil { t.Error("Unexpected error setting Prop3 value:", err) } if srvObj9.Prop5 != 15 { t.Errorf("prop5 expected 15 got %d", srvObj9.Prop5) } select { case <-chP5: close(chP5) case <-time.After(5 * time.Second): t.Error("Failed to announce that the Prop5 PropertyChanged signal emitted") } // Test Prop6 emit: false chP6 := make(chan int) go processSignal(service.conn, func(sig *dbus.Signal) bool { if sig.Name == "org.freedesktop.DBus.Properties.PropertiesChanged" && sig.Path == "/com/deepin/lib/Object9" { chP6 <- 1 return false } return true }) err = clientObj9.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object9", "Prop6", dbus.MakeVariant(int32(16))).Err if err != nil { t.Error("Unexpected error setting Prop3 value:", err) } if srvObj9.Prop6 != 16 { t.Errorf("prop6 expected 16 got %d", srvObj9.Prop6) } select { case <-chP6: t.Error("Failed to announce that the Prop6 PropertyChanged signal was not emitted") case <-time.After(1 * time.Second): // ok } // Test End _ = rulePC.RemoveFrom(service.conn) } type rect struct { X, Y uint32 W, H int32 } type twoRect struct { A, B rect } type srvObject10 struct { Prop1 rect `prop:"access:rw"` prop1ChangedCount int Prop2 []rect `prop:"access:rw"` prop2ChangedCount int Prop3 map[string]rect `prop:"access:rw"` prop3ChangedCount int Prop4 twoRect `prop:"access:rw"` prop4ChangedCount int } func (*srvObject10) GetInterfaceName() string { return "com.deepin.lib.Object10" } func TestService_StructProp(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj10 := &srvObject10{ Prop1: rect{1, 2, 3, 4}, } serverObject10, err := service.NewServerObject("/com/deepin/lib/Object10", srvObj10) _ = serverObject10.ConnectChanged(srvObj10, "Prop1", func(change *PropertyChanged) { srvObj10.prop1ChangedCount++ }) _ = serverObject10.ConnectChanged(srvObj10, "Prop2", func(change *PropertyChanged) { srvObj10.prop2ChangedCount++ }) _ = serverObject10.ConnectChanged(srvObj10, "Prop3", func(change *PropertyChanged) { srvObj10.prop3ChangedCount++ }) _ = serverObject10.ConnectChanged(srvObj10, "Prop4", func(change *PropertyChanged) { srvObj10.prop4ChangedCount++ }) err = serverObject10.Export() if err != nil { t.Error("Unexpected error exporting srvObj10:", err) } _ = service.RequestName("com.deepin.lib.Object10") if err != nil { t.Error("Unexpected error calling RequestName:", err) } clientObj10 := service.conn.Object("com.deepin.lib.Object10", "/com/deepin/lib/Object10") // Test Prop1 expectedProp1 := rect{2, 4, 6, 8} testProp1 := func() { err = clientObj10.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object10", "Prop1", dbus.MakeVariant(expectedProp1)).Err if err != nil { t.Error("Unexpected error setting Prop1:", err) } if srvObj10.Prop1 != expectedProp1 { t.Errorf("prop1 expected %#v got %#v", expectedProp1, srvObj10.Prop1) } if srvObj10.prop1ChangedCount != 1 { t.Errorf("prop1ChangedCount expected 1 got %d", srvObj10.prop1ChangedCount) } } testProp1() testProp1() // Set the same value to Prop1 again // Test Prop2 expectedProp2 := []rect{ {1, 3, 5, 7}, {2, 4, 6, 8}, } testProp2 := func() { err = clientObj10.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object10", "Prop2", dbus.MakeVariant(expectedProp2)).Err if err != nil { t.Error("Unexpected error setting Prop2:", err) } if !reflect.DeepEqual(srvObj10.Prop2, expectedProp2) { t.Errorf("prop2 expected %#v got %#v", expectedProp2, srvObj10.Prop2) } if srvObj10.prop2ChangedCount != 1 { t.Errorf("prop2ChangedCount expected 1 got %d", srvObj10.prop2ChangedCount) } } testProp2() testProp2() // Test Prop3 expectedProp3 := map[string]rect{ "a": {1, 3, 5, 7}, "b": {2, 4, 6, 8}, } testProp3 := func() { err = clientObj10.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object10", "Prop3", dbus.MakeVariant(expectedProp3)).Err if err != nil { t.Error("Unexpected error setting Prop3", err) } if !reflect.DeepEqual(srvObj10.Prop3, expectedProp3) { t.Errorf("prop3 expected %#v got %#v", expectedProp3, srvObj10.Prop3) } if srvObj10.prop3ChangedCount != 1 { t.Errorf("prop3ChangedCount expected 1 got %d", srvObj10.prop3ChangedCount) } } testProp3() testProp3() // Test Prop4 expectedProp4 := twoRect{ A: rect{1, 3, 5, 7}, B: rect{2, 4, 6, 8}, } testProp4 := func() { err = clientObj10.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object10", "Prop4", dbus.MakeVariant(expectedProp4)).Err if err != nil { t.Error("Unexpected error setting Prop4:", err) } if !reflect.DeepEqual(srvObj10.Prop4, expectedProp4) { t.Errorf("prop4 expected %#v got %#v", expectedProp4, srvObj10.Prop4) } if srvObj10.prop4ChangedCount != 1 { t.Errorf("prop4ChangedCount expected 1 got %d", srvObj10.prop4ChangedCount) } } testProp4() testProp4() } type srvObject11 struct { PropsMu sync.RWMutex Prop1 uint32 Prop2 uint64 Prop3 string Prop4 map[string]uint32 Prop4Mu sync.RWMutex Prop5 *customProperty } func (*srvObject11) GetInterfaceName() string { return "com.deepin.lib.Object11" } type customProperty struct { value int32 } func (*customProperty) SetValue(val interface{}) (changed bool, err *dbus.Error) { return false, nil } func (cp *customProperty) GetValue() (val interface{}, err *dbus.Error) { return cp.value, nil } func (*customProperty) SetNotifyChangedFunc(func(val interface{})) { } func (cp *customProperty) GetType() reflect.Type { return reflect.TypeOf(cp.value) } func TestService_DumpProperties(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj11 := &srvObject11{ Prop5: &customProperty{5}, } err = service.Export("/com/deepin/lib/Object11", srvObj11) if err != nil { t.Error("Unexpected error exporting srvObj11:", err) } propsInfo, err := service.DumpProperties(srvObj11) if err != nil { t.Error("Unexpected error dumping properties info:", err) } t.Log(propsInfo) t.Logf("PropsMu: %p", &srvObj11.PropsMu) t.Logf("Prop4Mu: %p", &srvObj11.Prop4Mu) } type integers struct { A int B uint } type srvObject13 struct { Prop1 int `prop:"access:rw"` prop1ChangedCount int Prop2 uint `prop:"access:rw"` prop2ChangedCount int Prop3 integers `prop:"access:rw"` prop3ChangedCount int } func (*srvObject13) GetInterfaceName() string { return "com.deepin.lib.Object13" } func TestService_IntUintProp(t *testing.T) { service, err := NewSessionService() if err != nil { t.Error("Unexpected error:", err) } srvObj13 := &srvObject13{ Prop1: 1, Prop2: 2, Prop3: integers{3, 4}, } serverObject13, err := service.NewServerObject("/com/deepin/lib/Object13", srvObj13) if err != nil { t.Error("Unexpected error:", err) } _ = serverObject13.ConnectChanged(srvObj13, "Prop1", func(change *PropertyChanged) { srvObj13.prop1ChangedCount++ }) _ = serverObject13.ConnectChanged(srvObj13, "Prop2", func(change *PropertyChanged) { srvObj13.prop2ChangedCount++ }) _ = serverObject13.ConnectChanged(srvObj13, "Prop3", func(change *PropertyChanged) { srvObj13.prop3ChangedCount++ }) err = serverObject13.Export() if err != nil { t.Error("Unexpected error exporting srvObj13:", err) } _ = service.RequestName("com.deepin.lib.Object13") if err != nil { t.Error("Unexpected error calling RequestName:", err) } clientObj13 := service.conn.Object("com.deepin.lib.Object13", "/com/deepin/lib/Object13") // Test Prop1 testProp1 := func() { err = clientObj13.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object13", "Prop1", dbus.MakeVariant(int32(11))).Err if err != nil { t.Error("Unexpected error setting Prop1:", err) } if srvObj13.Prop1 != 11 { t.Errorf("prop1 expected 11 got %d", srvObj13.Prop1) } if srvObj13.prop1ChangedCount != 1 { t.Errorf("prop1ChangedCount expected 1 got %d", srvObj13.prop1ChangedCount) } } testProp1() testProp1() // Test Prop2 testProp2 := func() { err = clientObj13.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object13", "Prop2", dbus.MakeVariant(uint32(12))).Err if err != nil { t.Error("Unexpected error setting Prop2:", err) } if srvObj13.Prop2 != 12 { t.Errorf("prop2 expected 12 got %d", srvObj13.Prop2) } if srvObj13.prop2ChangedCount != 1 { t.Errorf("prop2ChangedCount expected 1 got %d", srvObj13.prop2ChangedCount) } } testProp2() testProp2() // Test Prop3 expectedProp3 := integers{6, 7} testProp3 := func() { err = clientObj13.Call(orgFreedesktopDBus+".Properties.Set", 0, "com.deepin.lib.Object13", "Prop3", dbus.MakeVariant(struct { A int32 B uint32 }{6, 7})).Err if err != nil { t.Error("Unexpected error setting Prop3:", err) } if srvObj13.Prop3 != expectedProp3 { t.Errorf("prop3 expected %#v got %#v", expectedProp3, srvObj13.Prop3) } if srvObj13.prop3ChangedCount != 1 { t.Errorf("prop3ChangedCount expected 1 got %d", srvObj13.prop3ChangedCount) } } testProp3() testProp3() } go-lib-5.6.0.9/dbusutil/signal.go000664 000000 000000 00000004121 13753517240 016466 0ustar00rootroot000000 000000 package dbusutil import ( "sync" "github.com/godbus/dbus" ) type SignalHandlerId int type SignalLoop struct { conn *dbus.Conn bufSize int ch chan *dbus.Signal mu sync.Mutex handlers map[SignalHandlerId]SignalHandler nextHandlerId SignalHandlerId } func NewSignalLoop(conn *dbus.Conn, bufSize int) *SignalLoop { pl := &SignalLoop{ conn: conn, bufSize: bufSize, handlers: make(map[SignalHandlerId]SignalHandler), nextHandlerId: 1, } return pl } func (sl *SignalLoop) Conn() *dbus.Conn { return sl.conn } func (sl *SignalLoop) Start() { ch := make(chan *dbus.Signal, sl.bufSize) sl.conn.Signal(ch) sl.ch = ch go func() { for signal := range ch { sl.process(signal) } }() } func (sl *SignalLoop) process(signal *dbus.Signal) { var cbs []SignalHandlerFunc sl.mu.Lock() for _, handler := range sl.handlers { if handler.rule.match(signal) { if handler.cb != nil { cbs = append(cbs, handler.cb) } } } sl.mu.Unlock() for _, cb := range cbs { cb(signal) } } func (sl *SignalLoop) Stop() { sl.conn.RemoveSignal(sl.ch) close(sl.ch) } func (sl *SignalLoop) AddHandler(rule *SignalRule, cb SignalHandlerFunc) SignalHandlerId { sl.mu.Lock() defer sl.mu.Unlock() id := sl.nextHandlerId sl.nextHandlerId++ sl.handlers[id] = SignalHandler{ rule: rule, cb: cb, } return id } func (sl *SignalLoop) RemoveHandler(id SignalHandlerId) { if id < 0 { return } sl.mu.Lock() delete(sl.handlers, id) sl.mu.Unlock() } type SignalHandler struct { rule *SignalRule cb SignalHandlerFunc } type SignalRule struct { Sender string Path dbus.ObjectPath Name string } func (m *SignalRule) match(sig *dbus.Signal) bool { if m == nil { return true } if m.Sender != "" && m.Sender != sig.Sender { // define sender, but not equal return false } if m.Path != "" && m.Path != sig.Path { // define path, but not equal return false } if m.Name != "" && m.Name != sig.Name { // define name, but not equal return false } return true } type SignalHandlerFunc func(sig *dbus.Signal) go-lib-5.6.0.9/debian/000775 000000 000000 00000000000 13753517240 014253 5ustar00rootroot000000 000000 go-lib-5.6.0.9/debian/abi.json000775 000000 000000 00002273027 13753517240 015721 0ustar00rootroot000000 000000 {"Filepath":"misc.go","Functions":[{"Uniquefunname":"func UniqueOnSession(name string) bool","Funname":"UniqueOnSession","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func UniqueOnSystem(name string) bool","Funname":"UniqueOnSystem","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func UniqueOnSession(name string) bool","Funname":"lib.UniqueOnSession","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func UniqueOnSystem(name string) bool","Funname":"lib.UniqueOnSystem","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func uniqueOnAny(bus *dbus.Conn, name string) bool","Funname":"lib.uniqueOnAny","Returntype":"bool","Args":"bus *dbus.Conn, name string"},{"Uniquefunname":"func uniqueOnAny(bus *dbus.Conn, name string) bool","Funname":"uniqueOnAny","Returntype":"bool","Args":"bus *dbus.Conn, name string"}],"Records":[{"Name":"const:lib","Fields":["lib.SessionBus","lib.SystemBus"]}]} {"Filepath":"app/app.go","Functions":[{"Uniquefunname":"func (app *App) Command(name string, desc string) *kingpin.CmdClause","Funname":"Command","Returntype":"*kingpin.CmdClause","Args":"name string, desc string"},{"Uniquefunname":"func (app *App) CpuProf() string","Funname":"CpuProf","Returntype":"string","Args":""},{"Uniquefunname":"func (app *App) EnableNoShutdownHook(noShutdownHook bool)","Funname":"EnableNoShutdownHook","Returntype":"","Args":"noShutdownHook bool"},{"Uniquefunname":"func (app *App) Flag(longName string, desc string) *kingpin.FlagClause","Funname":"Flag","Returntype":"*kingpin.FlagClause","Args":"longName string, desc string"},{"Uniquefunname":"func (app *App) IsLogLevelNone() bool","Funname":"IsLogLevelNone","Returntype":"bool","Args":""},{"Uniquefunname":"func (app *App) LogLevel() log.Priority","Funname":"LogLevel","Returntype":"log.Priority","Args":""},{"Uniquefunname":"func (app *App) MemProf() string","Funname":"MemProf","Returntype":"string","Args":""},{"Uniquefunname":"func New(name string, desc string, version string) *App","Funname":"New","Returntype":"*App","Args":"name string, desc string, version string"},{"Uniquefunname":"func (app *App) ParseCommandLine(args []string) string","Funname":"ParseCommandLine","Returntype":"string","Args":"args []string"},{"Uniquefunname":"func (app *App) StartProfile() error","Funname":"StartProfile","Returntype":"error","Args":""},{"Uniquefunname":"func (app *App) StopProfile()","Funname":"StopProfile","Returntype":"","Args":""},{"Uniquefunname":"func (app *App) Command(name string, desc string) *kingpin.CmdClause","Funname":"app.App.Command","Returntype":"*kingpin.CmdClause","Args":"name string, desc string"},{"Uniquefunname":"func (app *App) CpuProf() string","Funname":"app.App.CpuProf","Returntype":"string","Args":""},{"Uniquefunname":"func (app *App) EnableNoShutdownHook(noShutdownHook bool)","Funname":"app.App.EnableNoShutdownHook","Returntype":"","Args":"noShutdownHook bool"},{"Uniquefunname":"func (app *App) Flag(longName string, desc string) *kingpin.FlagClause","Funname":"app.App.Flag","Returntype":"*kingpin.FlagClause","Args":"longName string, desc string"},{"Uniquefunname":"func (app *App) IsLogLevelNone() bool","Funname":"app.App.IsLogLevelNone","Returntype":"bool","Args":""},{"Uniquefunname":"func (app *App) LogLevel() log.Priority","Funname":"app.App.LogLevel","Returntype":"log.Priority","Args":""},{"Uniquefunname":"func (app *App) MemProf() string","Funname":"app.App.MemProf","Returntype":"string","Args":""},{"Uniquefunname":"func (app *App) ParseCommandLine(args []string) string","Funname":"app.App.ParseCommandLine","Returntype":"string","Args":"args []string"},{"Uniquefunname":"func (app *App) StartProfile() error","Funname":"app.App.StartProfile","Returntype":"error","Args":""},{"Uniquefunname":"func (app *App) StopProfile()","Funname":"app.App.StopProfile","Returntype":"","Args":""},{"Uniquefunname":"func New(name string, desc string, version string) *App","Funname":"app.New","Returntype":"*App","Args":"name string, desc string, version string"},{"Uniquefunname":"func toLogLevel(name string) (log.Priority, error)","Funname":"app.toLogLevel","Returntype":"(log.Priority, error)","Args":"name string"},{"Uniquefunname":"func toLogLevel(name string) (log.Priority, error)","Funname":"toLogLevel","Returntype":"(log.Priority, error)","Args":"name string"}],"Records":[{"Name":"struct:app.App","Fields":["app.App.cmd *kingpin.Application","app.App.cpuprof *string","app.App.logLevel *string","app.App.memprof *string","app.App.profile *profile.Config","app.App.verbose *bool"]}]} {"Filepath":"app/app_test.go","Functions":[{"Uniquefunname":"func ExampleApp()","Funname":"ExampleApp","Returntype":"","Args":""},{"Uniquefunname":"func ExampleApp()","Funname":"app.ExampleApp","Returntype":"","Args":""}],"Records":null} {"Filepath":"appinfo/appinfo.go","Functions":null,"Records":[{"Name":"interface","Fields":["appinfo.AppInfo"]}]} {"Filepath":"appinfo/applaunchcontext.go","Functions":[{"Uniquefunname":"func (ctx *AppLaunchContext) GetCmdPrefixes() []string","Funname":"GetCmdPrefixes","Returntype":"[]string","Args":""},{"Uniquefunname":"func (ctx *AppLaunchContext) GetCmdSuffixes() []string","Funname":"GetCmdSuffixes","Returntype":"[]string","Args":""},{"Uniquefunname":"func GetStartupNotifyId(appInfo AppInfo, files []string)(string, error)","Funname":"GetStartupNotifyId","Returntype":"(string, error)","Args":"appInfo AppInfo, files []string"},{"Uniquefunname":"func (ctx *AppLaunchContext) GetTimestamp() uint32","Funname":"GetTimestamp","Returntype":"uint32","Args":""},{"Uniquefunname":"func (ctx *AppLaunchContext) LaunchFailed(startupNotifyId string) error","Funname":"LaunchFailed","Returntype":"error","Args":"startupNotifyId string"},{"Uniquefunname":"func NewAppLaunchContext(conn *x.Conn) *AppLaunchContext","Funname":"NewAppLaunchContext","Returntype":"*AppLaunchContext","Args":"conn *x.Conn"},{"Uniquefunname":"func (ctx *AppLaunchContext) SetCmdPrefixes(v []string)","Funname":"SetCmdPrefixes","Returntype":"","Args":"v []string"},{"Uniquefunname":"func (ctx *AppLaunchContext) SetCmdSuffixes(v []string)","Funname":"SetCmdSuffixes","Returntype":"","Args":"v []string"},{"Uniquefunname":"func (ctx *AppLaunchContext) SetTimestamp(timestamp uint32)","Funname":"SetTimestamp","Returntype":"","Args":"timestamp uint32"},{"Uniquefunname":"func (ctx *AppLaunchContext) GetCmdPrefixes() []string","Funname":"appinfo.AppLaunchContext.GetCmdPrefixes","Returntype":"[]string","Args":""},{"Uniquefunname":"func (ctx *AppLaunchContext) GetCmdSuffixes() []string","Funname":"appinfo.AppLaunchContext.GetCmdSuffixes","Returntype":"[]string","Args":""},{"Uniquefunname":"func appinfo.AppLaunchContext.GetStartupNotifyId(appInfo AppInfo, files []string)(string, error)","Funname":"appinfo.AppLaunchContext.GetStartupNotifyId","Returntype":"(string, error)","Args":"appInfo AppInfo, files []string"},{"Uniquefunname":"func (ctx *AppLaunchContext) GetTimestamp() uint32","Funname":"appinfo.AppLaunchContext.GetTimestamp","Returntype":"uint32","Args":""},{"Uniquefunname":"func (ctx *AppLaunchContext) LaunchFailed(startupNotifyId string) error","Funname":"appinfo.AppLaunchContext.LaunchFailed","Returntype":"error","Args":"startupNotifyId string"},{"Uniquefunname":"func (ctx *AppLaunchContext) SetCmdPrefixes(v []string)","Funname":"appinfo.AppLaunchContext.SetCmdPrefixes","Returntype":"","Args":"v []string"},{"Uniquefunname":"func (ctx *AppLaunchContext) SetCmdSuffixes(v []string)","Funname":"appinfo.AppLaunchContext.SetCmdSuffixes","Returntype":"","Args":"v []string"},{"Uniquefunname":"func (ctx *AppLaunchContext) SetTimestamp(timestamp uint32)","Funname":"appinfo.AppLaunchContext.SetTimestamp","Returntype":"","Args":"timestamp uint32"},{"Uniquefunname":"func NewAppLaunchContext(conn *x.Conn) *AppLaunchContext","Funname":"appinfo.NewAppLaunchContext","Returntype":"*AppLaunchContext","Args":"conn *x.Conn"},{"Uniquefunname":"func init()","Funname":"appinfo.init","Returntype":"","Args":""},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""}],"Records":[{"Name":"struct:appinfo.AppLaunchContext","Fields":["appinfo.AppLaunchContext.cmdPrefixes []string","appinfo.AppLaunchContext.cmdSuffixes []string","appinfo.AppLaunchContext.conn *x.Conn","appinfo.AppLaunchContext.count uint","appinfo.AppLaunchContext.timestamp uint32"]},{"Name":"var:appinfo","Fields":["appinfo.hostname","appinfo.pid","appinfo.prog"]}]} {"Filepath":"appinfo/startup_notify_msg.go","Functions":[{"Uniquefunname":"func (msg *StartupNotifyMessage) Broadcast(conn *x.Conn) error","Funname":"Broadcast","Returntype":"error","Args":"conn *x.Conn"},{"Uniquefunname":"func (msg *StartupNotifyMessage) Broadcast(conn *x.Conn) error","Funname":"appinfo.StartupNotifyMessage.Broadcast","Returntype":"error","Args":"conn *x.Conn"},{"Uniquefunname":"func (msg *StartupNotifyMessage) fillBuffer() *bytes.Buffer","Funname":"appinfo.StartupNotifyMessage.fillBuffer","Returntype":"*bytes.Buffer","Args":""},{"Uniquefunname":"func appinfo.broadcastXMessage(conn *x.Conn, atomMsgType, atomMsgTypeBegin x.Atom, msgReader io.Reader)error","Funname":"appinfo.broadcastXMessage","Returntype":"error","Args":"conn *x.Conn, atomMsgType, atomMsgTypeBegin x.Atom, msgReader io.Reader"},{"Uniquefunname":"func broadcastXMessage(conn *x.Conn, atomMsgType, atomMsgTypeBegin x.Atom, msgReader io.Reader)error","Funname":"broadcastXMessage","Returntype":"error","Args":"conn *x.Conn, atomMsgType, atomMsgTypeBegin x.Atom, msgReader io.Reader"},{"Uniquefunname":"func (msg *StartupNotifyMessage) fillBuffer() *bytes.Buffer","Funname":"fillBuffer","Returntype":"*bytes.Buffer","Args":""}],"Records":[{"Name":"struct:appinfo.StartupNotifyMessage","Fields":["appinfo.StartupNotifyMessage.KeyValues map[string]string","appinfo.StartupNotifyMessage.Type string"]}]} {"Filepath":"appinfo/desktopappinfo/desktopappinfo.go","Functions":[{"Uniquefunname":"func (ai *DesktopAppInfo) GetActions() []DesktopAction","Funname":"GetActions","Returntype":"[]DesktopAction","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetCategories() []string","Funname":"GetCategories","Returntype":"[]string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetCommandline() string","Funname":"GetCommandline","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetComment() string","Funname":"GetComment","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetDBusActivatable() bool","Funname":"GetDBusActivatable","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetDisplayName() string","Funname":"GetDisplayName","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetExecutable() string","Funname":"GetExecutable","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetFileName() string","Funname":"GetFileName","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetGenericName() string","Funname":"GetGenericName","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetIcon() string","Funname":"GetIcon","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetId() string","Funname":"GetId","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetIsHidden() bool","Funname":"GetIsHidden","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetIsHiden() bool","Funname":"GetIsHiden","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetKeywords() []string","Funname":"GetKeywords","Returntype":"[]string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetMimeTypes() []string","Funname":"GetMimeTypes","Returntype":"[]string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetName() string","Funname":"GetName","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetNoDisplay() bool","Funname":"GetNoDisplay","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetPath() string","Funname":"GetPath","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetShowIn(desktopEnvs []string) bool","Funname":"GetShowIn","Returntype":"bool","Args":"desktopEnvs []string"},{"Uniquefunname":"func (ai *DesktopAppInfo) GetStartupNotify() bool","Funname":"GetStartupNotify","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetStartupWMClass() string","Funname":"GetStartupWMClass","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetTerminal() bool","Funname":"GetTerminal","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetTryExec() string","Funname":"GetTryExec","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) IsExecutableOk() bool","Funname":"IsExecutableOk","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) IsInstalled() bool","Funname":"IsInstalled","Returntype":"bool","Args":""},{"Uniquefunname":"func Launch(files []string, launchContext *appinfo.AppLaunchContext)error","Funname":"Launch","Returntype":"error","Args":"files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func Launch(files []string, launchContext *appinfo.AppLaunchContext)error","Funname":"Launch","Returntype":"error","Args":"files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func NewDesktopAppInfo(id string) *DesktopAppInfo","Funname":"NewDesktopAppInfo","Returntype":"*DesktopAppInfo","Args":"id string"},{"Uniquefunname":"func NewDesktopAppInfoFromFile(filename string) (*DesktopAppInfo, error)","Funname":"NewDesktopAppInfoFromFile","Returntype":"(*DesktopAppInfo, error)","Args":"filename string"},{"Uniquefunname":"func NewDesktopAppInfoFromKeyFile(kfile *keyfile.KeyFile) (*DesktopAppInfo, error)","Funname":"NewDesktopAppInfoFromKeyFile","Returntype":"(*DesktopAppInfo, error)","Args":"kfile *keyfile.KeyFile"},{"Uniquefunname":"func SetDataDirs(dirs []string)","Funname":"SetDataDirs","Returntype":"","Args":"dirs []string"},{"Uniquefunname":"func (ai *DesktopAppInfo) ShouldShow() bool","Funname":"ShouldShow","Returntype":"bool","Args":""},{"Uniquefunname":"func StartCommand(files []string, launchContext *appinfo.AppLaunchContext)(*exec.Cmd, error)","Funname":"StartCommand","Returntype":"(*exec.Cmd, error)","Args":"files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func StartCommand(files []string, launchContext *appinfo.AppLaunchContext)(*exec.Cmd, error)","Funname":"StartCommand","Returntype":"(*exec.Cmd, error)","Args":"files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func desktopappinfo.DesktopAction.Launch(files []string, launchContext *appinfo.AppLaunchContext)error","Funname":"desktopappinfo.DesktopAction.Launch","Returntype":"error","Args":"files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func desktopappinfo.DesktopAction.StartCommand(files []string, launchContext *appinfo.AppLaunchContext)(*exec.Cmd, error)","Funname":"desktopappinfo.DesktopAction.StartCommand","Returntype":"(*exec.Cmd, error)","Args":"files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func (ai *DesktopAppInfo) GetActions() []DesktopAction","Funname":"desktopappinfo.DesktopAppInfo.GetActions","Returntype":"[]DesktopAction","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetCategories() []string","Funname":"desktopappinfo.DesktopAppInfo.GetCategories","Returntype":"[]string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetCommandline() string","Funname":"desktopappinfo.DesktopAppInfo.GetCommandline","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetComment() string","Funname":"desktopappinfo.DesktopAppInfo.GetComment","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetDBusActivatable() bool","Funname":"desktopappinfo.DesktopAppInfo.GetDBusActivatable","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetDisplayName() string","Funname":"desktopappinfo.DesktopAppInfo.GetDisplayName","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetExecutable() string","Funname":"desktopappinfo.DesktopAppInfo.GetExecutable","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetFileName() string","Funname":"desktopappinfo.DesktopAppInfo.GetFileName","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetGenericName() string","Funname":"desktopappinfo.DesktopAppInfo.GetGenericName","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetIcon() string","Funname":"desktopappinfo.DesktopAppInfo.GetIcon","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetId() string","Funname":"desktopappinfo.DesktopAppInfo.GetId","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetIsHidden() bool","Funname":"desktopappinfo.DesktopAppInfo.GetIsHidden","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetIsHiden() bool","Funname":"desktopappinfo.DesktopAppInfo.GetIsHiden","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetKeywords() []string","Funname":"desktopappinfo.DesktopAppInfo.GetKeywords","Returntype":"[]string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetMimeTypes() []string","Funname":"desktopappinfo.DesktopAppInfo.GetMimeTypes","Returntype":"[]string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetName() string","Funname":"desktopappinfo.DesktopAppInfo.GetName","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetNoDisplay() bool","Funname":"desktopappinfo.DesktopAppInfo.GetNoDisplay","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetPath() string","Funname":"desktopappinfo.DesktopAppInfo.GetPath","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetShowIn(desktopEnvs []string) bool","Funname":"desktopappinfo.DesktopAppInfo.GetShowIn","Returntype":"bool","Args":"desktopEnvs []string"},{"Uniquefunname":"func (ai *DesktopAppInfo) GetStartupNotify() bool","Funname":"desktopappinfo.DesktopAppInfo.GetStartupNotify","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetStartupWMClass() string","Funname":"desktopappinfo.DesktopAppInfo.GetStartupWMClass","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetTerminal() bool","Funname":"desktopappinfo.DesktopAppInfo.GetTerminal","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) GetTryExec() string","Funname":"desktopappinfo.DesktopAppInfo.GetTryExec","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) IsExecutableOk() bool","Funname":"desktopappinfo.DesktopAppInfo.IsExecutableOk","Returntype":"bool","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) IsInstalled() bool","Funname":"desktopappinfo.DesktopAppInfo.IsInstalled","Returntype":"bool","Args":""},{"Uniquefunname":"func desktopappinfo.DesktopAppInfo.Launch(files []string, launchContext *appinfo.AppLaunchContext)error","Funname":"desktopappinfo.DesktopAppInfo.Launch","Returntype":"error","Args":"files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func (ai *DesktopAppInfo) ShouldShow() bool","Funname":"desktopappinfo.DesktopAppInfo.ShouldShow","Returntype":"bool","Args":""},{"Uniquefunname":"func desktopappinfo.DesktopAppInfo.StartCommand(files []string, launchContext *appinfo.AppLaunchContext)(*exec.Cmd, error)","Funname":"desktopappinfo.DesktopAppInfo.StartCommand","Returntype":"(*exec.Cmd, error)","Args":"files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func NewDesktopAppInfo(id string) *DesktopAppInfo","Funname":"desktopappinfo.NewDesktopAppInfo","Returntype":"*DesktopAppInfo","Args":"id string"},{"Uniquefunname":"func NewDesktopAppInfoFromFile(filename string) (*DesktopAppInfo, error)","Funname":"desktopappinfo.NewDesktopAppInfoFromFile","Returntype":"(*DesktopAppInfo, error)","Args":"filename string"},{"Uniquefunname":"func NewDesktopAppInfoFromKeyFile(kfile *keyfile.KeyFile) (*DesktopAppInfo, error)","Funname":"desktopappinfo.NewDesktopAppInfoFromKeyFile","Returntype":"(*DesktopAppInfo, error)","Args":"kfile *keyfile.KeyFile"},{"Uniquefunname":"func SetDataDirs(dirs []string)","Funname":"desktopappinfo.SetDataDirs","Returntype":"","Args":"dirs []string"},{"Uniquefunname":"func getCurrentDesktop() []string","Funname":"desktopappinfo.getCurrentDesktop","Returntype":"[]string","Args":""},{"Uniquefunname":"func getId(filename string) string","Funname":"desktopappinfo.getId","Returntype":"string","Args":"filename string"},{"Uniquefunname":"func init()","Funname":"desktopappinfo.init","Returntype":"","Args":""},{"Uniquefunname":"func isDesktopAction(name string) bool","Funname":"desktopappinfo.isDesktopAction","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func desktopappinfo.launch(ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext)error","Funname":"desktopappinfo.launch","Returntype":"error","Args":"ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func newDesktopAppInfoFromFile(filename string) (*DesktopAppInfo, error)","Funname":"desktopappinfo.newDesktopAppInfoFromFile","Returntype":"(*DesktopAppInfo, error)","Args":"filename string"},{"Uniquefunname":"func desktopappinfo.startCommand(ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext)(*exec.Cmd, error)","Funname":"desktopappinfo.startCommand","Returntype":"(*exec.Cmd, error)","Args":"ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func getCurrentDesktop() []string","Funname":"getCurrentDesktop","Returntype":"[]string","Args":""},{"Uniquefunname":"func getId(filename string) string","Funname":"getId","Returntype":"string","Args":"filename string"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func isDesktopAction(name string) bool","Funname":"isDesktopAction","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func launch(ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext)error","Funname":"launch","Returntype":"error","Args":"ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext"},{"Uniquefunname":"func newDesktopAppInfoFromFile(filename string) (*DesktopAppInfo, error)","Funname":"newDesktopAppInfoFromFile","Returntype":"(*DesktopAppInfo, error)","Args":"filename string"},{"Uniquefunname":"func startCommand(ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext)(*exec.Cmd, error)","Funname":"startCommand","Returntype":"(*exec.Cmd, error)","Args":"ai *DesktopAppInfo, cmdline string, files []string, launchContext *appinfo.AppLaunchContext"}],"Records":[{"Name":"struct:desktopappinfo.DesktopAction","Fields":["desktopappinfo.DesktopAction.Exec string","desktopappinfo.DesktopAction.Name string","desktopappinfo.DesktopAction.Section string","desktopappinfo.DesktopAction.parent *DesktopAppInfo"]},{"Name":"struct:desktopappinfo.DesktopAppInfo","Fields":["desktopappinfo.DesktopAppInfo.filename string","desktopappinfo.DesktopAppInfo.icon string","desktopappinfo.DesktopAppInfo.id string","desktopappinfo.DesktopAppInfo.name string"]},{"Name":"var:desktopappinfo","Fields":["desktopappinfo.ErrInvalidFileExt","desktopappinfo.ErrInvalidFirstSection","desktopappinfo.ErrInvalidType","desktopappinfo.currentDesktops","desktopappinfo.currentDesktopsOnce","desktopappinfo.keyReg","desktopappinfo.xdgAppDirs","desktopappinfo.xdgDataDirs"]},{"Name":"const:desktopappinfo","Fields":["desktopappinfo.KeyActions","desktopappinfo.KeyCategories","desktopappinfo.KeyComment","desktopappinfo.KeyDBusActivatable","desktopappinfo.KeyExec","desktopappinfo.KeyGenericName","desktopappinfo.KeyHidden","desktopappinfo.KeyIcon","desktopappinfo.KeyKeywords","desktopappinfo.KeyMimeType","desktopappinfo.KeyName","desktopappinfo.KeyNoDisplay","desktopappinfo.KeyNotShowIn","desktopappinfo.KeyOnlyShowIn","desktopappinfo.KeyPath","desktopappinfo.KeyStartupNotify","desktopappinfo.KeyStartupWMClass","desktopappinfo.KeyTerminal","desktopappinfo.KeyTryExec","desktopappinfo.KeyType","desktopappinfo.KeyURL","desktopappinfo.KeyVersion","desktopappinfo.MainSection","desktopappinfo.TypeApplication","desktopappinfo.TypeDirectory","desktopappinfo.TypeLink","desktopappinfo.desktopExt","desktopappinfo.enableInvoker","desktopappinfo.envDesktopEnv","desktopappinfo.errMsg","desktopappinfo.faliedMsg","desktopappinfo.gsSchemaStartdde"]}]} {"Filepath":"appinfo/desktopappinfo/desktopappinfo_test.go","Functions":[{"Uniquefunname":"func TestGetActions(t *testing.T)","Funname":"TestGetActions","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetCurrentDestkops(t *testing.T)","Funname":"TestGetCurrentDestkops","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetExecutable(t *testing.T)","Funname":"TestGetExecutable","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetShowIn(t *testing.T)","Funname":"TestGetShowIn","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestNewDesktopAppInfo(t *testing.T)","Funname":"TestNewDesktopAppInfo","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestNewDesktopAppInfoFromKeyFile(t *testing.T)","Funname":"TestNewDesktopAppInfoFromKeyFile","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_expandFieldCode(t *testing.T)","Funname":"Test_expandFieldCode","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_splitExec(t *testing.T)","Funname":"Test_splitExec","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetActions(t *testing.T)","Funname":"desktopappinfo.TestGetActions","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetCurrentDestkops(t *testing.T)","Funname":"desktopappinfo.TestGetCurrentDestkops","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetExecutable(t *testing.T)","Funname":"desktopappinfo.TestGetExecutable","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetShowIn(t *testing.T)","Funname":"desktopappinfo.TestGetShowIn","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestNewDesktopAppInfo(t *testing.T)","Funname":"desktopappinfo.TestNewDesktopAppInfo","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestNewDesktopAppInfoFromKeyFile(t *testing.T)","Funname":"desktopappinfo.TestNewDesktopAppInfoFromKeyFile","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_expandFieldCode(t *testing.T)","Funname":"desktopappinfo.Test_expandFieldCode","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_splitExec(t *testing.T)","Funname":"desktopappinfo.Test_splitExec","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"desktopappinfo.init","Returntype":"","Args":""},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""}],"Records":[{"Name":"const:desktopappinfo","Fields":["desktopappinfo.desktopFileContent0","desktopappinfo.desktopFileContent1","desktopappinfo.desktopFileContent10","desktopappinfo.desktopFileContent11","desktopappinfo.desktopFileContent2","desktopappinfo.desktopFileContent3","desktopappinfo.desktopFileContent4","desktopappinfo.desktopFileContent5","desktopappinfo.desktopFileContent6","desktopappinfo.desktopFileContent7","desktopappinfo.desktopFileContent8","desktopappinfo.desktopFileContent9"]}]} {"Filepath":"appinfo/desktopappinfo/exec.go","Functions":[{"Uniquefunname":"func (err ErrCharNotEscaped) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err ErrInvalidEscapeSequence) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err ErrReservedCharNotQuoted) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (ai *DesktopAppInfo) expandFieldCode(cmdline, files []string) ([]string, error)","Funname":"desktopappinfo.DesktopAppInfo.expandFieldCode","Returntype":"([]string, error)","Args":"cmdline, files []string"},{"Uniquefunname":"func (err ErrCharNotEscaped) Error() string","Funname":"desktopappinfo.ErrCharNotEscaped.Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err ErrInvalidEscapeSequence) Error() string","Funname":"desktopappinfo.ErrInvalidEscapeSequence.Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err ErrReservedCharNotQuoted) Error() string","Funname":"desktopappinfo.ErrReservedCharNotQuoted.Error","Returntype":"string","Args":""},{"Uniquefunname":"func eatAllSpace(reader *strings.Reader)","Funname":"desktopappinfo.eatAllSpace","Returntype":"","Args":"reader *strings.Reader"},{"Uniquefunname":"func desktopappinfo.expandFieldCode(cmdline, files []string, translatedName, icon, desktopFile string)([]string, error)","Funname":"desktopappinfo.expandFieldCode","Returntype":"([]string, error)","Args":"cmdline, files []string, translatedName, icon, desktopFile string"},{"Uniquefunname":"func getDefaultTerminal() (exec string, execArg string)","Funname":"desktopappinfo.getDefaultTerminal","Returntype":"(exec string, execArg string)","Args":""},{"Uniquefunname":"func isReservedChar(ch byte) bool","Funname":"desktopappinfo.isReservedChar","Returntype":"bool","Args":"ch byte"},{"Uniquefunname":"func shouldEscapeChar(ch byte) bool","Funname":"desktopappinfo.shouldEscapeChar","Returntype":"bool","Args":"ch byte"},{"Uniquefunname":"func splitExec(exec string) ([]string, error)","Funname":"desktopappinfo.splitExec","Returntype":"([]string, error)","Args":"exec string"},{"Uniquefunname":"func toLocalPath(in string) string","Funname":"desktopappinfo.toLocalPath","Returntype":"string","Args":"in string"},{"Uniquefunname":"func toURL(path string) string","Funname":"desktopappinfo.toURL","Returntype":"string","Args":"path string"},{"Uniquefunname":"func eatAllSpace(reader *strings.Reader)","Funname":"eatAllSpace","Returntype":"","Args":"reader *strings.Reader"},{"Uniquefunname":"func (ai *DesktopAppInfo) expandFieldCode(cmdline, files []string) ([]string, error)","Funname":"expandFieldCode","Returntype":"([]string, error)","Args":"cmdline, files []string"},{"Uniquefunname":"func expandFieldCode(cmdline, files []string, translatedName, icon, desktopFile string)([]string, error)","Funname":"expandFieldCode","Returntype":"([]string, error)","Args":"cmdline, files []string, translatedName, icon, desktopFile string"},{"Uniquefunname":"func getDefaultTerminal() (exec string, execArg string)","Funname":"getDefaultTerminal","Returntype":"(exec string, execArg string)","Args":""},{"Uniquefunname":"func isReservedChar(ch byte) bool","Funname":"isReservedChar","Returntype":"bool","Args":"ch byte"},{"Uniquefunname":"func shouldEscapeChar(ch byte) bool","Funname":"shouldEscapeChar","Returntype":"bool","Args":"ch byte"},{"Uniquefunname":"func splitExec(exec string) ([]string, error)","Funname":"splitExec","Returntype":"([]string, error)","Args":"exec string"},{"Uniquefunname":"func toLocalPath(in string) string","Funname":"toLocalPath","Returntype":"string","Args":"in string"},{"Uniquefunname":"func toURL(path string) string","Funname":"toURL","Returntype":"string","Args":"path string"}],"Records":[{"Name":"var:desktopappinfo","Fields":["desktopappinfo.ErrBadFieldCode","desktopappinfo.ErrEscapeCharAtEnd","desktopappinfo.ErrNoSpaceAfterQuoting","desktopappinfo.ErrQuotingNotClosed","desktopappinfo.escapeChars","desktopappinfo.reservedChars"]},{"Name":"struct:desktopappinfo.ErrCharNotEscaped","Fields":["desktopappinfo.ErrCharNotEscaped.Char byte"]},{"Name":"struct:desktopappinfo.ErrInvalidEscapeSequence","Fields":["desktopappinfo.ErrInvalidEscapeSequence.Char byte"]},{"Name":"struct:desktopappinfo.ErrReservedCharNotQuoted","Fields":["desktopappinfo.ErrReservedCharNotQuoted.Char byte"]}]} {"Filepath":"appinfo/desktopappinfo/get_all.go","Functions":[{"Uniquefunname":"func GetAll(skipDirs map[string][]string) []*DesktopAppInfo","Funname":"GetAll","Returntype":"[]*DesktopAppInfo","Args":"skipDirs map[string][]string"},{"Uniquefunname":"func Walk(root string, walkFn WalkFunc)","Funname":"Walk","Returntype":"","Args":"root string, walkFn WalkFunc"},{"Uniquefunname":"func GetAll(skipDirs map[string][]string) []*DesktopAppInfo","Funname":"desktopappinfo.GetAll","Returntype":"[]*DesktopAppInfo","Args":"skipDirs map[string][]string"},{"Uniquefunname":"func Walk(root string, walkFn WalkFunc)","Funname":"desktopappinfo.Walk","Returntype":"","Args":"root string, walkFn WalkFunc"},{"Uniquefunname":"func getAppNames(root string, skipDirs []string) map[string]int","Funname":"desktopappinfo.getAppNames","Returntype":"map[string]int","Args":"root string, skipDirs []string"},{"Uniquefunname":"func getDirs(skipDirs map[string][]string) []AppsDir","Funname":"desktopappinfo.getDirs","Returntype":"[]AppsDir","Args":"skipDirs map[string][]string"},{"Uniquefunname":"func readDirNames(dirname string) ([]string, error)","Funname":"desktopappinfo.readDirNames","Returntype":"([]string, error)","Args":"dirname string"},{"Uniquefunname":"func stringSliceContains(slice []string, str string) bool","Funname":"desktopappinfo.stringSliceContains","Returntype":"bool","Args":"slice []string, str string"},{"Uniquefunname":"func walk(root, name0 string, info os.FileInfo, walkFn WalkFunc)","Funname":"desktopappinfo.walk","Returntype":"","Args":"root, name0 string, info os.FileInfo, walkFn WalkFunc"},{"Uniquefunname":"func getAppNames(root string, skipDirs []string) map[string]int","Funname":"getAppNames","Returntype":"map[string]int","Args":"root string, skipDirs []string"},{"Uniquefunname":"func getDirs(skipDirs map[string][]string) []AppsDir","Funname":"getDirs","Returntype":"[]AppsDir","Args":"skipDirs map[string][]string"},{"Uniquefunname":"func readDirNames(dirname string) ([]string, error)","Funname":"readDirNames","Returntype":"([]string, error)","Args":"dirname string"},{"Uniquefunname":"func stringSliceContains(slice []string, str string) bool","Funname":"stringSliceContains","Returntype":"bool","Args":"slice []string, str string"},{"Uniquefunname":"func walk(root, name0 string, info os.FileInfo, walkFn WalkFunc)","Funname":"walk","Returntype":"","Args":"root, name0 string, info os.FileInfo, walkFn WalkFunc"}],"Records":[{"Name":"struct:desktopappinfo.AppsDir","Fields":["desktopappinfo.AppsDir.AppNames map[string]int","desktopappinfo.AppsDir.Path string"]}]} {"Filepath":"arch/arch.go","Functions":[{"Uniquefunname":"func Get() ArchFamilyType","Funname":"Get","Returntype":"ArchFamilyType","Args":""},{"Uniquefunname":"func Get() ArchFamilyType","Funname":"arch.Get","Returntype":"ArchFamilyType","Args":""}],"Records":[{"Name":"const:arch","Fields":["arch.AMD64","arch.Sunway","arch.Unknown"]}]} {"Filepath":"archive/archive.go","Functions":[{"Uniquefunname":"func CompressDir(src, dest string) error","Funname":"CompressDir","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func CompressFiles(files []string, dest string) error","Funname":"CompressFiles","Returntype":"error","Args":"files []string, dest string"},{"Uniquefunname":"func Extracte(src, dest string) ([]string, error)","Funname":"Extracte","Returntype":"([]string, error)","Args":"src, dest string"},{"Uniquefunname":"func CompressDir(src, dest string) error","Funname":"archive.CompressDir","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func CompressFiles(files []string, dest string) error","Funname":"archive.CompressFiles","Returntype":"error","Args":"files []string, dest string"},{"Uniquefunname":"func Extracte(src, dest string) ([]string, error)","Funname":"archive.Extracte","Returntype":"([]string, error)","Args":"src, dest string"},{"Uniquefunname":"func getCompressType(file string) int32","Funname":"archive.getCompressType","Returntype":"int32","Args":"file string"},{"Uniquefunname":"func getCompressType(file string) int32","Funname":"getCompressType","Returntype":"int32","Args":"file string"}],"Records":[{"Name":"const:archive","Fields":["archive.CompressTypeTar","archive.CompressTypeTarBz2","archive.CompressTypeTarGz","archive.CompressTypeUnkown","archive.CompressTypeZip"]}]} {"Filepath":"archive/archive_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestTarCompresssFiles(c *C.C)","Funname":"TestTarCompresssFiles","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestTarExtracteFile(c *C.C)","Funname":"TestTarExtracteFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func Test(t *testing.T)","Funname":"archive.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"archive.init","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) TestTarCompresssFiles(c *C.C)","Funname":"archive.testWrapper.TestTarCompresssFiles","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestTarExtracteFile(c *C.C)","Funname":"archive.testWrapper.TestTarExtracteFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""}],"Records":null} {"Filepath":"archive/tar.go","Functions":[{"Uniquefunname":"func tarCompressFiles(files []string, dest string) error","Funname":"archive.tarCompressFiles","Returntype":"error","Args":"files []string, dest string"},{"Uniquefunname":"func tarExtracteFile(src, dest string) ([]string, error)","Funname":"archive.tarExtracteFile","Returntype":"([]string, error)","Args":"src, dest string"},{"Uniquefunname":"func tarCompressFiles(files []string, dest string) error","Funname":"tarCompressFiles","Returntype":"error","Args":"files []string, dest string"},{"Uniquefunname":"func tarExtracteFile(src, dest string) ([]string, error)","Funname":"tarExtracteFile","Returntype":"([]string, error)","Args":"src, dest string"}],"Records":null} {"Filepath":"archive/gzip/gzip.go","Functions":[{"Uniquefunname":"func CompressDir(src, dest string, t int32) error","Funname":"CompressDir","Returntype":"error","Args":"src, dest string, t int32"},{"Uniquefunname":"func CompressFiles(files []string, dest string, t int32) error","Funname":"CompressFiles","Returntype":"error","Args":"files []string, dest string, t int32"},{"Uniquefunname":"func Extracte(src, destDir string, t int32) ([]string, error)","Funname":"Extracte","Returntype":"([]string, error)","Args":"src, destDir string, t int32"},{"Uniquefunname":"func CompressDir(src, dest string, t int32) error","Funname":"gzip.CompressDir","Returntype":"error","Args":"src, dest string, t int32"},{"Uniquefunname":"func CompressFiles(files []string, dest string, t int32) error","Funname":"gzip.CompressFiles","Returntype":"error","Args":"files []string, dest string, t int32"},{"Uniquefunname":"func Extracte(src, destDir string, t int32) ([]string, error)","Funname":"gzip.Extracte","Returntype":"([]string, error)","Args":"src, destDir string, t int32"}],"Records":[{"Name":"const:gzip","Fields":["gzip.ArchiveTypeRar","gzip.ArchiveTypeTar","gzip.ArchiveTypeZip"]}]} {"Filepath":"archive/gzip/gzip_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestTarCompresssFiles(c *C.C)","Funname":"TestTarCompresssFiles","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestTarExtracteFile(c *C.C)","Funname":"TestTarExtracteFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func Test(t *testing.T)","Funname":"gzip.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"gzip.init","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) TestTarCompresssFiles(c *C.C)","Funname":"gzip.testWrapper.TestTarCompresssFiles","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestTarExtracteFile(c *C.C)","Funname":"gzip.testWrapper.TestTarExtracteFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""}],"Records":null} {"Filepath":"archive/gzip/tar.go","Functions":[{"Uniquefunname":"func tarCompressFiles(files []string, dest string) error","Funname":"gzip.tarCompressFiles","Returntype":"error","Args":"files []string, dest string"},{"Uniquefunname":"func tarExtracte(src, dest string) ([]string, error)","Funname":"gzip.tarExtracte","Returntype":"([]string, error)","Args":"src, dest string"},{"Uniquefunname":"func tarCompressFiles(files []string, dest string) error","Funname":"tarCompressFiles","Returntype":"error","Args":"files []string, dest string"},{"Uniquefunname":"func tarExtracte(src, dest string) ([]string, error)","Funname":"tarExtracte","Returntype":"([]string, error)","Args":"src, dest string"}],"Records":null} {"Filepath":"archive/utils/tar.go","Functions":[{"Uniquefunname":"func TarReaderExtracte(reader *tar.Reader, dest string) ([]string, error)","Funname":"TarReaderExtracte","Returntype":"([]string, error)","Args":"reader *tar.Reader, dest string"},{"Uniquefunname":"func TarWriterCompressFiles(writer *tar.Writer, files []string) error","Funname":"TarWriterCompressFiles","Returntype":"error","Args":"writer *tar.Writer, files []string"},{"Uniquefunname":"func tarWriterCompressDir(tw *tar.Writer, dir, parent string) error","Funname":"tarWriterCompressDir","Returntype":"error","Args":"tw *tar.Writer, dir, parent string"},{"Uniquefunname":"func tarWriterCompressFile(tw *tar.Writer, file, parent string) error","Funname":"tarWriterCompressFile","Returntype":"error","Args":"tw *tar.Writer, file, parent string"},{"Uniquefunname":"func TarReaderExtracte(reader *tar.Reader, dest string) ([]string, error)","Funname":"utils.TarReaderExtracte","Returntype":"([]string, error)","Args":"reader *tar.Reader, dest string"},{"Uniquefunname":"func TarWriterCompressFiles(writer *tar.Writer, files []string) error","Funname":"utils.TarWriterCompressFiles","Returntype":"error","Args":"writer *tar.Writer, files []string"},{"Uniquefunname":"func tarWriterCompressDir(tw *tar.Writer, dir, parent string) error","Funname":"utils.tarWriterCompressDir","Returntype":"error","Args":"tw *tar.Writer, dir, parent string"},{"Uniquefunname":"func tarWriterCompressFile(tw *tar.Writer, file, parent string) error","Funname":"utils.tarWriterCompressFile","Returntype":"error","Args":"tw *tar.Writer, file, parent string"}],"Records":null} {"Filepath":"asound/asound.go","Functions":[{"Uniquefunname":"func (m Mixer) Attach(name string) error","Funname":"Attach","Returntype":"error","Args":"name string"},{"Uniquefunname":"func CTLOpen(name string, mode int) (CTL, error)","Funname":"CTLOpen","Returntype":"(CTL, error)","Args":"name string, mode int"},{"Uniquefunname":"func (ctl CTL) CardInfo(info CTLCardInfo) error","Funname":"CardInfo","Returntype":"error","Args":"info CTLCardInfo"},{"Uniquefunname":"func CardLoad(card int) bool","Funname":"CardLoad","Returntype":"bool","Args":"card int"},{"Uniquefunname":"func CardNext(rcard *int) error","Funname":"CardNext","Returntype":"error","Args":"rcard *int"},{"Uniquefunname":"func (ctl CTL) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (m Mixer) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (o Output) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (subformat PCMSubformat) Desc() string","Funname":"Desc","Returntype":"string","Args":""},{"Uniquefunname":"func (pcm PCM) Drain() error","Funname":"Drain","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Drop() error","Funname":"Drop","Returntype":"error","Args":""},{"Uniquefunname":"func (params PCMHwParams) Dump(out Output) error","Funname":"Dump","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (pcm PCM) Dump(out Output) error","Funname":"Dump","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (pcm PCM) DumpHwSetup(out Output) error","Funname":"DumpHwSetup","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (pcm PCM) DumpSetup(out Output) error","Funname":"DumpSetup","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (pcm PCM) DumpSwSetup(out Output) error","Funname":"DumpSwSetup","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (err *Error) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (m Mixer) FindSelem(id MixerSelemId) MixerElem","Funname":"FindSelem","Returntype":"MixerElem","Args":"id MixerSelemId"},{"Uniquefunname":"func (m Mixer) FirstElem() MixerElem","Funname":"FirstElem","Returntype":"MixerElem","Args":""},{"Uniquefunname":"func (o Output) Flush() error","Funname":"Flush","Returntype":"error","Args":""},{"Uniquefunname":"func (id MixerSelemId) Free()","Funname":"Free","Returntype":"","Args":""},{"Uniquefunname":"func (info CTLCardInfo) Free()","Funname":"Free","Returntype":"","Args":""},{"Uniquefunname":"func (info PCMInfo) Free()","Funname":"Free","Returntype":"","Args":""},{"Uniquefunname":"func (m Mixer) Free()","Funname":"Free","Returntype":"","Args":""},{"Uniquefunname":"func (opt *MixerSelemRegopt) Free()","Funname":"Free","Returntype":"","Args":""},{"Uniquefunname":"func (params PCMHwParams) Free()","Funname":"Free","Returntype":"","Args":""},{"Uniquefunname":"func (v DeviceNameHints) Free()","Funname":"Free","Returntype":"","Args":""},{"Uniquefunname":"func (iter DeviceNameHintsIter) Get(id string) string","Funname":"Get","Returntype":"string","Args":"id string"},{"Uniquefunname":"func (params PCMHwParams) GetBufferTimeMax() (val uint, dir int, err error)","Funname":"GetBufferTimeMax","Returntype":"(val uint, dir int, err error)","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetCard() int","Funname":"GetCard","Returntype":"int","Args":""},{"Uniquefunname":"func (info PCMInfo) GetCard() int","Funname":"GetCard","Returntype":"int","Args":""},{"Uniquefunname":"func (info PCMInfo) GetClass() PCMClass","Funname":"GetClass","Returntype":"PCMClass","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetComponents() string","Funname":"GetComponents","Returntype":"string","Args":""},{"Uniquefunname":"func GetDeviceNameHints(card int, iface string) (DeviceNameHints, error)","Funname":"GetDeviceNameHints","Returntype":"(DeviceNameHints, error)","Args":"card int, iface string"},{"Uniquefunname":"func (info CTLCardInfo) GetDriver() string","Funname":"GetDriver","Returntype":"string","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetID() string","Funname":"GetID","Returntype":"string","Args":""},{"Uniquefunname":"func (info PCMInfo) GetID() string","Funname":"GetID","Returntype":"string","Args":""},{"Uniquefunname":"func (id MixerSelemId) GetIndex() uint","Funname":"GetIndex","Returntype":"uint","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetLongName() string","Funname":"GetLongName","Returntype":"string","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetMixerName() string","Funname":"GetMixerName","Returntype":"string","Args":""},{"Uniquefunname":"func (id MixerSelemId) GetName() string","Funname":"GetName","Returntype":"string","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetName() string","Funname":"GetName","Returntype":"string","Args":""},{"Uniquefunname":"func (info PCMInfo) GetName() string","Funname":"GetName","Returntype":"string","Args":""},{"Uniquefunname":"func (params PCMHwParams) GetPeriodSize() (PCMUFrames, int, error)","Funname":"GetPeriodSize","Returntype":"(PCMUFrames, int, error)","Args":""},{"Uniquefunname":"func (params PCMHwParams) GetPeriodTime() (uint, int, error)","Funname":"GetPeriodTime","Returntype":"(uint, int, error)","Args":""},{"Uniquefunname":"func (e MixerElem) GetSelemId(id MixerSelemId)","Funname":"GetSelemId","Returntype":"","Args":"id MixerSelemId"},{"Uniquefunname":"func (info PCMInfo) GetStream() PCMStream","Funname":"GetStream","Returntype":"PCMStream","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubclass() PCMSubclass","Funname":"GetSubclass","Returntype":"PCMSubclass","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubdevice() uint","Funname":"GetSubdevice","Returntype":"uint","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubdeviceName() string","Funname":"GetSubdeviceName","Returntype":"string","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubdevicesAvail() uint","Funname":"GetSubdevicesAvail","Returntype":"uint","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubdevicesCount() uint","Funname":"GetSubdevicesCount","Returntype":"uint","Args":""},{"Uniquefunname":"func (pcm PCM) HwFree() error","Funname":"HwFree","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) HwParams(params PCMHwParams) error","Funname":"HwParams","Returntype":"error","Args":"params PCMHwParams"},{"Uniquefunname":"func (pcm PCM) HwParamsAny(params PCMHwParams)","Funname":"HwParamsAny","Returntype":"","Args":"params PCMHwParams"},{"Uniquefunname":"func (pcm PCM) HwParamsSetAccess(params PCMHwParams, access PCMAccess) error","Funname":"HwParamsSetAccess","Returntype":"error","Args":"params PCMHwParams, access PCMAccess"},{"Uniquefunname":"func (pcm PCM) HwParamsSetBufferSize(params PCMHwParams, val PCMUFrames) error","Funname":"HwParamsSetBufferSize","Returntype":"error","Args":"params PCMHwParams, val PCMUFrames"},{"Uniquefunname":"func (pcm PCM) HwParamsSetBufferTimeNear(params PCMHwParams, val *uint) (int, error)","Funname":"HwParamsSetBufferTimeNear","Returntype":"(int, error)","Args":"params PCMHwParams, val *uint"},{"Uniquefunname":"func (pcm PCM) HwParamsSetChannels(params PCMHwParams, val uint) error","Funname":"HwParamsSetChannels","Returntype":"error","Args":"params PCMHwParams, val uint"},{"Uniquefunname":"func (pcm PCM) HwParamsSetFormat(params PCMHwParams, format PCMFormat) error","Funname":"HwParamsSetFormat","Returntype":"error","Args":"params PCMHwParams, format PCMFormat"},{"Uniquefunname":"func (pcm PCM) HwParamsSetPeriodSize(params PCMHwParams, val PCMUFrames, dir int) error","Funname":"HwParamsSetPeriodSize","Returntype":"error","Args":"params PCMHwParams, val PCMUFrames, dir int"},{"Uniquefunname":"func HwParamsSetPeriodSizeNear(params PCMHwParams, val PCMUFrames)(PCMUFrames, int, error)","Funname":"HwParamsSetPeriodSizeNear","Returntype":"(PCMUFrames, int, error)","Args":"params PCMHwParams, val PCMUFrames"},{"Uniquefunname":"func (pcm PCM) HwParamsSetPeriodTimeNear(params PCMHwParams, val *uint) (int, error)","Funname":"HwParamsSetPeriodTimeNear","Returntype":"(int, error)","Args":"params PCMHwParams, val *uint"},{"Uniquefunname":"func (pcm PCM) HwParamsSetRate(params PCMHwParams, val uint, dir int) error","Funname":"HwParamsSetRate","Returntype":"error","Args":"params PCMHwParams, val uint, dir int"},{"Uniquefunname":"func (pcm PCM) HwParamsSetRateNear(params PCMHwParams, val *uint) (int, error)","Funname":"HwParamsSetRateNear","Returntype":"(int, error)","Args":"params PCMHwParams, val *uint"},{"Uniquefunname":"func (pcm PCM) Info(info PCMInfo) error","Funname":"Info","Returntype":"error","Args":"info PCMInfo"},{"Uniquefunname":"func (v DeviceNameHints) Iter() *DeviceNameHintsIter","Funname":"Iter","Returntype":"*DeviceNameHintsIter","Args":""},{"Uniquefunname":"func (m Mixer) Load() error","Funname":"Load","Returntype":"error","Args":""},{"Uniquefunname":"func (access PCMAccess) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (format PCMFormat) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (id MixerSelemChannelId) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (pcm PCM) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (stream PCMStream) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (subformat PCMSubformat) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (typ PCMType) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func NewCTLCardInfo() (CTLCardInfo, error)","Funname":"NewCTLCardInfo","Returntype":"(CTLCardInfo, error)","Args":""},{"Uniquefunname":"func NewMixerSelemId() (MixerSelemId, error)","Funname":"NewMixerSelemId","Returntype":"(MixerSelemId, error)","Args":""},{"Uniquefunname":"func NewPCMHwParams() (PCMHwParams, error)","Funname":"NewPCMHwParams","Returntype":"(PCMHwParams, error)","Args":""},{"Uniquefunname":"func NewPCMInfo() (PCMInfo, error)","Funname":"NewPCMInfo","Returntype":"(PCMInfo, error)","Args":""},{"Uniquefunname":"func (e MixerElem) Next() MixerElem","Funname":"Next","Returntype":"MixerElem","Args":""},{"Uniquefunname":"func (iter *DeviceNameHintsIter) Next() bool","Funname":"Next","Returntype":"bool","Args":""},{"Uniquefunname":"func OpenMixer(mode int) (Mixer, error)","Funname":"OpenMixer","Returntype":"(Mixer, error)","Args":"mode int"},{"Uniquefunname":"func OpenOutput(file, mode string) (Output, error)","Funname":"OpenOutput","Returntype":"(Output, error)","Args":"file, mode string"},{"Uniquefunname":"func OpenPCM(name string, stream PCMStream, mode int) (PCM, error)","Funname":"OpenPCM","Returntype":"(PCM, error)","Args":"name string, stream PCMStream, mode int"},{"Uniquefunname":"func (ctl CTL) PCMInfo(info PCMInfo) error","Funname":"PCMInfo","Returntype":"error","Args":"info PCMInfo"},{"Uniquefunname":"func (ctl CTL) PCMNextDevice(device *int) error","Funname":"PCMNextDevice","Returntype":"error","Args":"device *int"},{"Uniquefunname":"func (pcm PCM) Pause(enable bool) error","Funname":"Pause","Returntype":"error","Args":"enable bool"},{"Uniquefunname":"func (pcm PCM) Prepare() error","Funname":"Prepare","Returntype":"error","Args":""},{"Uniquefunname":"func (e MixerElem) Prev() MixerElem","Funname":"Prev","Returntype":"MixerElem","Args":""},{"Uniquefunname":"func (o Output) Printf(format string, a ...interface","Funname":"Printf","Returntype":"error","Args":"format string, a ...interface{}"},{"Uniquefunname":"func (o Output) Println(a ...interface","Funname":"Println","Returntype":"error","Args":"a ...interface{}"},{"Uniquefunname":"func (pcm PCM) Recover(err int, silent bool) error","Funname":"Recover","Returntype":"error","Args":"err int, silent bool"},{"Uniquefunname":"func (pcm PCM) Reset() error","Funname":"Reset","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Resume() error","Funname":"Resume","Returntype":"error","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureDB(channel MixerSelemChannelId) (int, error)","Funname":"SelemGetCaptureDB","Returntype":"(int, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureDBRange() (min, max int)","Funname":"SelemGetCaptureDBRange","Returntype":"(min, max int)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureGroup() int","Funname":"SelemGetCaptureGroup","Returntype":"int","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureSwitch(channel MixerSelemChannelId) (bool, error)","Funname":"SelemGetCaptureSwitch","Returntype":"(bool, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureVolume(channel MixerSelemChannelId) (int, error)","Funname":"SelemGetCaptureVolume","Returntype":"(int, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureVolumeRange() (min, max int)","Funname":"SelemGetCaptureVolumeRange","Returntype":"(min, max int)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetEnumItem(channel MixerSelemChannelId) (uint, error)","Funname":"SelemGetEnumItem","Returntype":"(uint, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetEnumItemName(item uint, maxLen int) (string, error)","Funname":"SelemGetEnumItemName","Returntype":"(string, error)","Args":"item uint, maxLen int"},{"Uniquefunname":"func (e MixerElem) SelemGetEnumItems() (int, error)","Funname":"SelemGetEnumItems","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackDB(channel MixerSelemChannelId) (int, error)","Funname":"SelemGetPlaybackDB","Returntype":"(int, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackDBRange() (min, max int)","Funname":"SelemGetPlaybackDBRange","Returntype":"(min, max int)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackSwitch(channel MixerSelemChannelId) (bool, error)","Funname":"SelemGetPlaybackSwitch","Returntype":"(bool, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackVolume(channel MixerSelemChannelId) (int, error)","Funname":"SelemGetPlaybackVolume","Returntype":"(int, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackVolumeRange() (min, max int)","Funname":"SelemGetPlaybackVolumeRange","Returntype":"(min, max int)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureChannel(channel MixerSelemChannelId) bool","Funname":"SelemHasCaptureChannel","Returntype":"bool","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureSwitch() bool","Funname":"SelemHasCaptureSwitch","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureSwitchExclusive() bool","Funname":"SelemHasCaptureSwitchExclusive","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureSwitchJoined() bool","Funname":"SelemHasCaptureSwitchJoined","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureVolume() bool","Funname":"SelemHasCaptureVolume","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureVolumeJoined() bool","Funname":"SelemHasCaptureVolumeJoined","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCommonSwitch() bool","Funname":"SelemHasCommonSwitch","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCommonVolume() bool","Funname":"SelemHasCommonVolume","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackChannel(channel MixerSelemChannelId) bool","Funname":"SelemHasPlaybackChannel","Returntype":"bool","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackSwitch() bool","Funname":"SelemHasPlaybackSwitch","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackSwitchJoined() bool","Funname":"SelemHasPlaybackSwitchJoined","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackVolume() bool","Funname":"SelemHasPlaybackVolume","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackVolumeJoined() bool","Funname":"SelemHasPlaybackVolumeJoined","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsActive() bool","Funname":"SelemIsActive","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsCaptureMono() bool","Funname":"SelemIsCaptureMono","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsEnumCapture() bool","Funname":"SelemIsEnumCapture","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsEnumPlayback() bool","Funname":"SelemIsEnumPlayback","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsEnumerated() bool","Funname":"SelemIsEnumerated","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsPlaybackMono() bool","Funname":"SelemIsPlaybackMono","Returntype":"bool","Args":""},{"Uniquefunname":"func (m Mixer) SelemRegister(options *MixerSelemRegopt, class *MixerClass) error","Funname":"SelemRegister","Returntype":"error","Args":"options *MixerSelemRegopt, class *MixerClass"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureDB(channel MixerSelemChannelId, value, dir int) error","Funname":"SelemSetCaptureDB","Returntype":"error","Args":"channel MixerSelemChannelId, value, dir int"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureDBAll(value, dir int) error","Funname":"SelemSetCaptureDBAll","Returntype":"error","Args":"value, dir int"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureSwitch(channel MixerSelemChannelId, value bool) error","Funname":"SelemSetCaptureSwitch","Returntype":"error","Args":"channel MixerSelemChannelId, value bool"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureSwitchAll(value bool) error","Funname":"SelemSetCaptureSwitchAll","Returntype":"error","Args":"value bool"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureVolume(channel MixerSelemChannelId, value int) error","Funname":"SelemSetCaptureVolume","Returntype":"error","Args":"channel MixerSelemChannelId, value int"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureVolumeAll(value int) error","Funname":"SelemSetCaptureVolumeAll","Returntype":"error","Args":"value int"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackDB(channel MixerSelemChannelId, value, dir int) error","Funname":"SelemSetPlaybackDB","Returntype":"error","Args":"channel MixerSelemChannelId, value, dir int"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackDBAll(value, dir int) error","Funname":"SelemSetPlaybackDBAll","Returntype":"error","Args":"value, dir int"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackSwitch(channel MixerSelemChannelId, value bool) error","Funname":"SelemSetPlaybackSwitch","Returntype":"error","Args":"channel MixerSelemChannelId, value bool"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackSwitchAll(value bool) error","Funname":"SelemSetPlaybackSwitchAll","Returntype":"error","Args":"value bool"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackVolume(channel MixerSelemChannelId, value int) error","Funname":"SelemSetPlaybackVolume","Returntype":"error","Args":"channel MixerSelemChannelId, value int"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackVolumeAll(value int) error","Funname":"SelemSetPlaybackVolumeAll","Returntype":"error","Args":"value int"},{"Uniquefunname":"func (opt *MixerSelemRegopt) SetCapturePCM(pcm PCM)","Funname":"SetCapturePCM","Returntype":"","Args":"pcm PCM"},{"Uniquefunname":"func (info PCMInfo) SetDevice(val uint)","Funname":"SetDevice","Returntype":"","Args":"val uint"},{"Uniquefunname":"func (opt *MixerSelemRegopt) SetDevice(device string)","Funname":"SetDevice","Returntype":"","Args":"device string"},{"Uniquefunname":"func (opt *MixerSelemRegopt) SetPlaybackPCM(pcm PCM)","Funname":"SetPlaybackPCM","Returntype":"","Args":"pcm PCM"},{"Uniquefunname":"func (info PCMInfo) SetStream(val PCMStream)","Funname":"SetStream","Returntype":"","Args":"val PCMStream"},{"Uniquefunname":"func (info PCMInfo) SetSubdevice(val uint)","Funname":"SetSubdevice","Returntype":"","Args":"val uint"},{"Uniquefunname":"func (opt *MixerSelemRegopt) SetVer(ver int)","Funname":"SetVer","Returntype":"","Args":"ver int"},{"Uniquefunname":"func (format PCMFormat) Size(samples uint) int","Funname":"Size","Returntype":"int","Args":"samples uint"},{"Uniquefunname":"func (pcm PCM) Start() error","Funname":"Start","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) State() PCMState","Funname":"State","Returntype":"PCMState","Args":""},{"Uniquefunname":"func (pcm PCM) Stream() PCMStream","Funname":"Stream","Returntype":"PCMStream","Args":""},{"Uniquefunname":"func (pcm PCM) Type() PCMType","Funname":"Type","Returntype":"PCMType","Args":""},{"Uniquefunname":"func (o Output) WriteString(str string) error","Funname":"WriteString","Returntype":"error","Args":"str string"},{"Uniquefunname":"func (pcm PCM) Writei(buffer unsafe.Pointer, size PCMUFrames) (PCMUFrames, error)","Funname":"Writei","Returntype":"(PCMUFrames, error)","Args":"buffer unsafe.Pointer, size PCMUFrames"},{"Uniquefunname":"func (ctl CTL) CardInfo(info CTLCardInfo) error","Funname":"asound.CTL.CardInfo","Returntype":"error","Args":"info CTLCardInfo"},{"Uniquefunname":"func (ctl CTL) Close() error","Funname":"asound.CTL.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (ctl CTL) PCMInfo(info PCMInfo) error","Funname":"asound.CTL.PCMInfo","Returntype":"error","Args":"info PCMInfo"},{"Uniquefunname":"func (ctl CTL) PCMNextDevice(device *int) error","Funname":"asound.CTL.PCMNextDevice","Returntype":"error","Args":"device *int"},{"Uniquefunname":"func (v CTL) native() *C.snd_ctl_t","Funname":"asound.CTL.native","Returntype":"*C.snd_ctl_t","Args":""},{"Uniquefunname":"func (info CTLCardInfo) Free()","Funname":"asound.CTLCardInfo.Free","Returntype":"","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetCard() int","Funname":"asound.CTLCardInfo.GetCard","Returntype":"int","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetComponents() string","Funname":"asound.CTLCardInfo.GetComponents","Returntype":"string","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetDriver() string","Funname":"asound.CTLCardInfo.GetDriver","Returntype":"string","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetID() string","Funname":"asound.CTLCardInfo.GetID","Returntype":"string","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetLongName() string","Funname":"asound.CTLCardInfo.GetLongName","Returntype":"string","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetMixerName() string","Funname":"asound.CTLCardInfo.GetMixerName","Returntype":"string","Args":""},{"Uniquefunname":"func (info CTLCardInfo) GetName() string","Funname":"asound.CTLCardInfo.GetName","Returntype":"string","Args":""},{"Uniquefunname":"func (v CTLCardInfo) native() *C.snd_ctl_card_info_t","Funname":"asound.CTLCardInfo.native","Returntype":"*C.snd_ctl_card_info_t","Args":""},{"Uniquefunname":"func CTLOpen(name string, mode int) (CTL, error)","Funname":"asound.CTLOpen","Returntype":"(CTL, error)","Args":"name string, mode int"},{"Uniquefunname":"func CardLoad(card int) bool","Funname":"asound.CardLoad","Returntype":"bool","Args":"card int"},{"Uniquefunname":"func CardNext(rcard *int) error","Funname":"asound.CardNext","Returntype":"error","Args":"rcard *int"},{"Uniquefunname":"func (v DeviceNameHints) Free()","Funname":"asound.DeviceNameHints.Free","Returntype":"","Args":""},{"Uniquefunname":"func (v DeviceNameHints) Iter() *DeviceNameHintsIter","Funname":"asound.DeviceNameHints.Iter","Returntype":"*DeviceNameHintsIter","Args":""},{"Uniquefunname":"func (iter DeviceNameHintsIter) Get(id string) string","Funname":"asound.DeviceNameHintsIter.Get","Returntype":"string","Args":"id string"},{"Uniquefunname":"func (iter *DeviceNameHintsIter) Next() bool","Funname":"asound.DeviceNameHintsIter.Next","Returntype":"bool","Args":""},{"Uniquefunname":"func (err *Error) Error() string","Funname":"asound.Error.Error","Returntype":"string","Args":""},{"Uniquefunname":"func GetDeviceNameHints(card int, iface string) (DeviceNameHints, error)","Funname":"asound.GetDeviceNameHints","Returntype":"(DeviceNameHints, error)","Args":"card int, iface string"},{"Uniquefunname":"func (m Mixer) Attach(name string) error","Funname":"asound.Mixer.Attach","Returntype":"error","Args":"name string"},{"Uniquefunname":"func (m Mixer) Close() error","Funname":"asound.Mixer.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (m Mixer) FindSelem(id MixerSelemId) MixerElem","Funname":"asound.Mixer.FindSelem","Returntype":"MixerElem","Args":"id MixerSelemId"},{"Uniquefunname":"func (m Mixer) FirstElem() MixerElem","Funname":"asound.Mixer.FirstElem","Returntype":"MixerElem","Args":""},{"Uniquefunname":"func (m Mixer) Free()","Funname":"asound.Mixer.Free","Returntype":"","Args":""},{"Uniquefunname":"func (m Mixer) Load() error","Funname":"asound.Mixer.Load","Returntype":"error","Args":""},{"Uniquefunname":"func (m Mixer) SelemRegister(options *MixerSelemRegopt, class *MixerClass) error","Funname":"asound.Mixer.SelemRegister","Returntype":"error","Args":"options *MixerSelemRegopt, class *MixerClass"},{"Uniquefunname":"func (m Mixer) native() *C.snd_mixer_t","Funname":"asound.Mixer.native","Returntype":"*C.snd_mixer_t","Args":""},{"Uniquefunname":"func (e MixerElem) GetSelemId(id MixerSelemId)","Funname":"asound.MixerElem.GetSelemId","Returntype":"","Args":"id MixerSelemId"},{"Uniquefunname":"func (e MixerElem) Next() MixerElem","Funname":"asound.MixerElem.Next","Returntype":"MixerElem","Args":""},{"Uniquefunname":"func (e MixerElem) Prev() MixerElem","Funname":"asound.MixerElem.Prev","Returntype":"MixerElem","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureDB(channel MixerSelemChannelId) (int, error)","Funname":"asound.MixerElem.SelemGetCaptureDB","Returntype":"(int, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureDBRange() (min, max int)","Funname":"asound.MixerElem.SelemGetCaptureDBRange","Returntype":"(min, max int)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureGroup() int","Funname":"asound.MixerElem.SelemGetCaptureGroup","Returntype":"int","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureSwitch(channel MixerSelemChannelId) (bool, error)","Funname":"asound.MixerElem.SelemGetCaptureSwitch","Returntype":"(bool, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureVolume(channel MixerSelemChannelId) (int, error)","Funname":"asound.MixerElem.SelemGetCaptureVolume","Returntype":"(int, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetCaptureVolumeRange() (min, max int)","Funname":"asound.MixerElem.SelemGetCaptureVolumeRange","Returntype":"(min, max int)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetEnumItem(channel MixerSelemChannelId) (uint, error)","Funname":"asound.MixerElem.SelemGetEnumItem","Returntype":"(uint, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetEnumItemName(item uint, maxLen int) (string, error)","Funname":"asound.MixerElem.SelemGetEnumItemName","Returntype":"(string, error)","Args":"item uint, maxLen int"},{"Uniquefunname":"func (e MixerElem) SelemGetEnumItems() (int, error)","Funname":"asound.MixerElem.SelemGetEnumItems","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackDB(channel MixerSelemChannelId) (int, error)","Funname":"asound.MixerElem.SelemGetPlaybackDB","Returntype":"(int, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackDBRange() (min, max int)","Funname":"asound.MixerElem.SelemGetPlaybackDBRange","Returntype":"(min, max int)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackSwitch(channel MixerSelemChannelId) (bool, error)","Funname":"asound.MixerElem.SelemGetPlaybackSwitch","Returntype":"(bool, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackVolume(channel MixerSelemChannelId) (int, error)","Funname":"asound.MixerElem.SelemGetPlaybackVolume","Returntype":"(int, error)","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemGetPlaybackVolumeRange() (min, max int)","Funname":"asound.MixerElem.SelemGetPlaybackVolumeRange","Returntype":"(min, max int)","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureChannel(channel MixerSelemChannelId) bool","Funname":"asound.MixerElem.SelemHasCaptureChannel","Returntype":"bool","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureSwitch() bool","Funname":"asound.MixerElem.SelemHasCaptureSwitch","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureSwitchExclusive() bool","Funname":"asound.MixerElem.SelemHasCaptureSwitchExclusive","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureSwitchJoined() bool","Funname":"asound.MixerElem.SelemHasCaptureSwitchJoined","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureVolume() bool","Funname":"asound.MixerElem.SelemHasCaptureVolume","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCaptureVolumeJoined() bool","Funname":"asound.MixerElem.SelemHasCaptureVolumeJoined","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCommonSwitch() bool","Funname":"asound.MixerElem.SelemHasCommonSwitch","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasCommonVolume() bool","Funname":"asound.MixerElem.SelemHasCommonVolume","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackChannel(channel MixerSelemChannelId) bool","Funname":"asound.MixerElem.SelemHasPlaybackChannel","Returntype":"bool","Args":"channel MixerSelemChannelId"},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackSwitch() bool","Funname":"asound.MixerElem.SelemHasPlaybackSwitch","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackSwitchJoined() bool","Funname":"asound.MixerElem.SelemHasPlaybackSwitchJoined","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackVolume() bool","Funname":"asound.MixerElem.SelemHasPlaybackVolume","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemHasPlaybackVolumeJoined() bool","Funname":"asound.MixerElem.SelemHasPlaybackVolumeJoined","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsActive() bool","Funname":"asound.MixerElem.SelemIsActive","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsCaptureMono() bool","Funname":"asound.MixerElem.SelemIsCaptureMono","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsEnumCapture() bool","Funname":"asound.MixerElem.SelemIsEnumCapture","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsEnumPlayback() bool","Funname":"asound.MixerElem.SelemIsEnumPlayback","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsEnumerated() bool","Funname":"asound.MixerElem.SelemIsEnumerated","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemIsPlaybackMono() bool","Funname":"asound.MixerElem.SelemIsPlaybackMono","Returntype":"bool","Args":""},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureDB(channel MixerSelemChannelId, value, dir int) error","Funname":"asound.MixerElem.SelemSetCaptureDB","Returntype":"error","Args":"channel MixerSelemChannelId, value, dir int"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureDBAll(value, dir int) error","Funname":"asound.MixerElem.SelemSetCaptureDBAll","Returntype":"error","Args":"value, dir int"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureSwitch(channel MixerSelemChannelId, value bool) error","Funname":"asound.MixerElem.SelemSetCaptureSwitch","Returntype":"error","Args":"channel MixerSelemChannelId, value bool"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureSwitchAll(value bool) error","Funname":"asound.MixerElem.SelemSetCaptureSwitchAll","Returntype":"error","Args":"value bool"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureVolume(channel MixerSelemChannelId, value int) error","Funname":"asound.MixerElem.SelemSetCaptureVolume","Returntype":"error","Args":"channel MixerSelemChannelId, value int"},{"Uniquefunname":"func (e MixerElem) SelemSetCaptureVolumeAll(value int) error","Funname":"asound.MixerElem.SelemSetCaptureVolumeAll","Returntype":"error","Args":"value int"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackDB(channel MixerSelemChannelId, value, dir int) error","Funname":"asound.MixerElem.SelemSetPlaybackDB","Returntype":"error","Args":"channel MixerSelemChannelId, value, dir int"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackDBAll(value, dir int) error","Funname":"asound.MixerElem.SelemSetPlaybackDBAll","Returntype":"error","Args":"value, dir int"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackSwitch(channel MixerSelemChannelId, value bool) error","Funname":"asound.MixerElem.SelemSetPlaybackSwitch","Returntype":"error","Args":"channel MixerSelemChannelId, value bool"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackSwitchAll(value bool) error","Funname":"asound.MixerElem.SelemSetPlaybackSwitchAll","Returntype":"error","Args":"value bool"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackVolume(channel MixerSelemChannelId, value int) error","Funname":"asound.MixerElem.SelemSetPlaybackVolume","Returntype":"error","Args":"channel MixerSelemChannelId, value int"},{"Uniquefunname":"func (e MixerElem) SelemSetPlaybackVolumeAll(value int) error","Funname":"asound.MixerElem.SelemSetPlaybackVolumeAll","Returntype":"error","Args":"value int"},{"Uniquefunname":"func (e MixerElem) native() *C.snd_mixer_elem_t","Funname":"asound.MixerElem.native","Returntype":"*C.snd_mixer_elem_t","Args":""},{"Uniquefunname":"func (id MixerSelemChannelId) Name() string","Funname":"asound.MixerSelemChannelId.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (id MixerSelemId) Free()","Funname":"asound.MixerSelemId.Free","Returntype":"","Args":""},{"Uniquefunname":"func (id MixerSelemId) GetIndex() uint","Funname":"asound.MixerSelemId.GetIndex","Returntype":"uint","Args":""},{"Uniquefunname":"func (id MixerSelemId) GetName() string","Funname":"asound.MixerSelemId.GetName","Returntype":"string","Args":""},{"Uniquefunname":"func (id MixerSelemId) native() *C.snd_mixer_selem_id_t","Funname":"asound.MixerSelemId.native","Returntype":"*C.snd_mixer_selem_id_t","Args":""},{"Uniquefunname":"func (opt *MixerSelemRegopt) Free()","Funname":"asound.MixerSelemRegopt.Free","Returntype":"","Args":""},{"Uniquefunname":"func (opt *MixerSelemRegopt) SetCapturePCM(pcm PCM)","Funname":"asound.MixerSelemRegopt.SetCapturePCM","Returntype":"","Args":"pcm PCM"},{"Uniquefunname":"func (opt *MixerSelemRegopt) SetDevice(device string)","Funname":"asound.MixerSelemRegopt.SetDevice","Returntype":"","Args":"device string"},{"Uniquefunname":"func (opt *MixerSelemRegopt) SetPlaybackPCM(pcm PCM)","Funname":"asound.MixerSelemRegopt.SetPlaybackPCM","Returntype":"","Args":"pcm PCM"},{"Uniquefunname":"func (opt *MixerSelemRegopt) SetVer(ver int)","Funname":"asound.MixerSelemRegopt.SetVer","Returntype":"","Args":"ver int"},{"Uniquefunname":"func NewCTLCardInfo() (CTLCardInfo, error)","Funname":"asound.NewCTLCardInfo","Returntype":"(CTLCardInfo, error)","Args":""},{"Uniquefunname":"func NewMixerSelemId() (MixerSelemId, error)","Funname":"asound.NewMixerSelemId","Returntype":"(MixerSelemId, error)","Args":""},{"Uniquefunname":"func NewPCMHwParams() (PCMHwParams, error)","Funname":"asound.NewPCMHwParams","Returntype":"(PCMHwParams, error)","Args":""},{"Uniquefunname":"func NewPCMInfo() (PCMInfo, error)","Funname":"asound.NewPCMInfo","Returntype":"(PCMInfo, error)","Args":""},{"Uniquefunname":"func OpenMixer(mode int) (Mixer, error)","Funname":"asound.OpenMixer","Returntype":"(Mixer, error)","Args":"mode int"},{"Uniquefunname":"func OpenOutput(file, mode string) (Output, error)","Funname":"asound.OpenOutput","Returntype":"(Output, error)","Args":"file, mode string"},{"Uniquefunname":"func OpenPCM(name string, stream PCMStream, mode int) (PCM, error)","Funname":"asound.OpenPCM","Returntype":"(PCM, error)","Args":"name string, stream PCMStream, mode int"},{"Uniquefunname":"func (o Output) Close() error","Funname":"asound.Output.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (o Output) Flush() error","Funname":"asound.Output.Flush","Returntype":"error","Args":""},{"Uniquefunname":"func (o Output) Printf(format string, a ...interface","Funname":"asound.Output.Printf","Returntype":"error","Args":"format string, a ...interface{}"},{"Uniquefunname":"func (o Output) Println(a ...interface","Funname":"asound.Output.Println","Returntype":"error","Args":"a ...interface{}"},{"Uniquefunname":"func (o Output) WriteString(str string) error","Funname":"asound.Output.WriteString","Returntype":"error","Args":"str string"},{"Uniquefunname":"func (v Output) native() *C.snd_output_t","Funname":"asound.Output.native","Returntype":"*C.snd_output_t","Args":""},{"Uniquefunname":"func (pcm PCM) Close() error","Funname":"asound.PCM.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Drain() error","Funname":"asound.PCM.Drain","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Drop() error","Funname":"asound.PCM.Drop","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Dump(out Output) error","Funname":"asound.PCM.Dump","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (pcm PCM) DumpHwSetup(out Output) error","Funname":"asound.PCM.DumpHwSetup","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (pcm PCM) DumpSetup(out Output) error","Funname":"asound.PCM.DumpSetup","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (pcm PCM) DumpSwSetup(out Output) error","Funname":"asound.PCM.DumpSwSetup","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (pcm PCM) HwFree() error","Funname":"asound.PCM.HwFree","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) HwParams(params PCMHwParams) error","Funname":"asound.PCM.HwParams","Returntype":"error","Args":"params PCMHwParams"},{"Uniquefunname":"func (pcm PCM) HwParamsAny(params PCMHwParams)","Funname":"asound.PCM.HwParamsAny","Returntype":"","Args":"params PCMHwParams"},{"Uniquefunname":"func (pcm PCM) HwParamsSetAccess(params PCMHwParams, access PCMAccess) error","Funname":"asound.PCM.HwParamsSetAccess","Returntype":"error","Args":"params PCMHwParams, access PCMAccess"},{"Uniquefunname":"func (pcm PCM) HwParamsSetBufferSize(params PCMHwParams, val PCMUFrames) error","Funname":"asound.PCM.HwParamsSetBufferSize","Returntype":"error","Args":"params PCMHwParams, val PCMUFrames"},{"Uniquefunname":"func (pcm PCM) HwParamsSetBufferTimeNear(params PCMHwParams, val *uint) (int, error)","Funname":"asound.PCM.HwParamsSetBufferTimeNear","Returntype":"(int, error)","Args":"params PCMHwParams, val *uint"},{"Uniquefunname":"func (pcm PCM) HwParamsSetChannels(params PCMHwParams, val uint) error","Funname":"asound.PCM.HwParamsSetChannels","Returntype":"error","Args":"params PCMHwParams, val uint"},{"Uniquefunname":"func (pcm PCM) HwParamsSetFormat(params PCMHwParams, format PCMFormat) error","Funname":"asound.PCM.HwParamsSetFormat","Returntype":"error","Args":"params PCMHwParams, format PCMFormat"},{"Uniquefunname":"func (pcm PCM) HwParamsSetPeriodSize(params PCMHwParams, val PCMUFrames, dir int) error","Funname":"asound.PCM.HwParamsSetPeriodSize","Returntype":"error","Args":"params PCMHwParams, val PCMUFrames, dir int"},{"Uniquefunname":"func asound.PCM.HwParamsSetPeriodSizeNear(params PCMHwParams, val PCMUFrames)(PCMUFrames, int, error)","Funname":"asound.PCM.HwParamsSetPeriodSizeNear","Returntype":"(PCMUFrames, int, error)","Args":"params PCMHwParams, val PCMUFrames"},{"Uniquefunname":"func (pcm PCM) HwParamsSetPeriodTimeNear(params PCMHwParams, val *uint) (int, error)","Funname":"asound.PCM.HwParamsSetPeriodTimeNear","Returntype":"(int, error)","Args":"params PCMHwParams, val *uint"},{"Uniquefunname":"func (pcm PCM) HwParamsSetRate(params PCMHwParams, val uint, dir int) error","Funname":"asound.PCM.HwParamsSetRate","Returntype":"error","Args":"params PCMHwParams, val uint, dir int"},{"Uniquefunname":"func (pcm PCM) HwParamsSetRateNear(params PCMHwParams, val *uint) (int, error)","Funname":"asound.PCM.HwParamsSetRateNear","Returntype":"(int, error)","Args":"params PCMHwParams, val *uint"},{"Uniquefunname":"func (pcm PCM) Info(info PCMInfo) error","Funname":"asound.PCM.Info","Returntype":"error","Args":"info PCMInfo"},{"Uniquefunname":"func (pcm PCM) Name() string","Funname":"asound.PCM.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (pcm PCM) Pause(enable bool) error","Funname":"asound.PCM.Pause","Returntype":"error","Args":"enable bool"},{"Uniquefunname":"func (pcm PCM) Prepare() error","Funname":"asound.PCM.Prepare","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Recover(err int, silent bool) error","Funname":"asound.PCM.Recover","Returntype":"error","Args":"err int, silent bool"},{"Uniquefunname":"func (pcm PCM) Reset() error","Funname":"asound.PCM.Reset","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Resume() error","Funname":"asound.PCM.Resume","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) Start() error","Funname":"asound.PCM.Start","Returntype":"error","Args":""},{"Uniquefunname":"func (pcm PCM) State() PCMState","Funname":"asound.PCM.State","Returntype":"PCMState","Args":""},{"Uniquefunname":"func (pcm PCM) Stream() PCMStream","Funname":"asound.PCM.Stream","Returntype":"PCMStream","Args":""},{"Uniquefunname":"func (pcm PCM) Type() PCMType","Funname":"asound.PCM.Type","Returntype":"PCMType","Args":""},{"Uniquefunname":"func (pcm PCM) Writei(buffer unsafe.Pointer, size PCMUFrames) (PCMUFrames, error)","Funname":"asound.PCM.Writei","Returntype":"(PCMUFrames, error)","Args":"buffer unsafe.Pointer, size PCMUFrames"},{"Uniquefunname":"func (v PCM) native() *C.snd_pcm_t","Funname":"asound.PCM.native","Returntype":"*C.snd_pcm_t","Args":""},{"Uniquefunname":"func (access PCMAccess) Name() string","Funname":"asound.PCMAccess.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (format PCMFormat) Name() string","Funname":"asound.PCMFormat.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (format PCMFormat) Size(samples uint) int","Funname":"asound.PCMFormat.Size","Returntype":"int","Args":"samples uint"},{"Uniquefunname":"func (params PCMHwParams) Dump(out Output) error","Funname":"asound.PCMHwParams.Dump","Returntype":"error","Args":"out Output"},{"Uniquefunname":"func (params PCMHwParams) Free()","Funname":"asound.PCMHwParams.Free","Returntype":"","Args":""},{"Uniquefunname":"func (params PCMHwParams) GetBufferTimeMax() (val uint, dir int, err error)","Funname":"asound.PCMHwParams.GetBufferTimeMax","Returntype":"(val uint, dir int, err error)","Args":""},{"Uniquefunname":"func (params PCMHwParams) GetPeriodSize() (PCMUFrames, int, error)","Funname":"asound.PCMHwParams.GetPeriodSize","Returntype":"(PCMUFrames, int, error)","Args":""},{"Uniquefunname":"func (params PCMHwParams) GetPeriodTime() (uint, int, error)","Funname":"asound.PCMHwParams.GetPeriodTime","Returntype":"(uint, int, error)","Args":""},{"Uniquefunname":"func (v PCMHwParams) native() *C.snd_pcm_hw_params_t","Funname":"asound.PCMHwParams.native","Returntype":"*C.snd_pcm_hw_params_t","Args":""},{"Uniquefunname":"func (info PCMInfo) Free()","Funname":"asound.PCMInfo.Free","Returntype":"","Args":""},{"Uniquefunname":"func (info PCMInfo) GetCard() int","Funname":"asound.PCMInfo.GetCard","Returntype":"int","Args":""},{"Uniquefunname":"func (info PCMInfo) GetClass() PCMClass","Funname":"asound.PCMInfo.GetClass","Returntype":"PCMClass","Args":""},{"Uniquefunname":"func (info PCMInfo) GetID() string","Funname":"asound.PCMInfo.GetID","Returntype":"string","Args":""},{"Uniquefunname":"func (info PCMInfo) GetName() string","Funname":"asound.PCMInfo.GetName","Returntype":"string","Args":""},{"Uniquefunname":"func (info PCMInfo) GetStream() PCMStream","Funname":"asound.PCMInfo.GetStream","Returntype":"PCMStream","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubclass() PCMSubclass","Funname":"asound.PCMInfo.GetSubclass","Returntype":"PCMSubclass","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubdevice() uint","Funname":"asound.PCMInfo.GetSubdevice","Returntype":"uint","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubdeviceName() string","Funname":"asound.PCMInfo.GetSubdeviceName","Returntype":"string","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubdevicesAvail() uint","Funname":"asound.PCMInfo.GetSubdevicesAvail","Returntype":"uint","Args":""},{"Uniquefunname":"func (info PCMInfo) GetSubdevicesCount() uint","Funname":"asound.PCMInfo.GetSubdevicesCount","Returntype":"uint","Args":""},{"Uniquefunname":"func (info PCMInfo) SetDevice(val uint)","Funname":"asound.PCMInfo.SetDevice","Returntype":"","Args":"val uint"},{"Uniquefunname":"func (info PCMInfo) SetStream(val PCMStream)","Funname":"asound.PCMInfo.SetStream","Returntype":"","Args":"val PCMStream"},{"Uniquefunname":"func (info PCMInfo) SetSubdevice(val uint)","Funname":"asound.PCMInfo.SetSubdevice","Returntype":"","Args":"val uint"},{"Uniquefunname":"func (v PCMInfo) native() *C.snd_pcm_info_t","Funname":"asound.PCMInfo.native","Returntype":"*C.snd_pcm_info_t","Args":""},{"Uniquefunname":"func (stream PCMStream) Name() string","Funname":"asound.PCMStream.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (subformat PCMSubformat) Desc() string","Funname":"asound.PCMSubformat.Desc","Returntype":"string","Args":""},{"Uniquefunname":"func (subformat PCMSubformat) Name() string","Funname":"asound.PCMSubformat.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (typ PCMType) Name() string","Funname":"asound.PCMType.Name","Returntype":"string","Args":""},{"Uniquefunname":"func newError(fn string, code C.int) error","Funname":"asound.newError","Returntype":"error","Args":"fn string, code C.int"},{"Uniquefunname":"func wrapCTL(p *C.snd_ctl_t) CTL","Funname":"asound.wrapCTL","Returntype":"CTL","Args":"p *C.snd_ctl_t"},{"Uniquefunname":"func wrapCTLCardInfo(ptr *C.snd_ctl_card_info_t) CTLCardInfo","Funname":"asound.wrapCTLCardInfo","Returntype":"CTLCardInfo","Args":"ptr *C.snd_ctl_card_info_t"},{"Uniquefunname":"func wrapMixer(ptr *C.snd_mixer_t) Mixer","Funname":"asound.wrapMixer","Returntype":"Mixer","Args":"ptr *C.snd_mixer_t"},{"Uniquefunname":"func wrapMixerElem(ptr *C.snd_mixer_elem_t) MixerElem","Funname":"asound.wrapMixerElem","Returntype":"MixerElem","Args":"ptr *C.snd_mixer_elem_t"},{"Uniquefunname":"func wrapMixerSelemId(ptr *C.snd_mixer_selem_id_t) MixerSelemId","Funname":"asound.wrapMixerSelemId","Returntype":"MixerSelemId","Args":"ptr *C.snd_mixer_selem_id_t"},{"Uniquefunname":"func wrapPCM(ptr *C.snd_pcm_t) PCM","Funname":"asound.wrapPCM","Returntype":"PCM","Args":"ptr *C.snd_pcm_t"},{"Uniquefunname":"func wrapPCMHwParams(ptr *C.snd_pcm_hw_params_t) PCMHwParams","Funname":"asound.wrapPCMHwParams","Returntype":"PCMHwParams","Args":"ptr *C.snd_pcm_hw_params_t"},{"Uniquefunname":"func wrapPCMInfo(ptr *C.snd_pcm_info_t) PCMInfo","Funname":"asound.wrapPCMInfo","Returntype":"PCMInfo","Args":"ptr *C.snd_pcm_info_t"},{"Uniquefunname":"func (e MixerElem) native() *C.snd_mixer_elem_t","Funname":"native","Returntype":"*C.snd_mixer_elem_t","Args":""},{"Uniquefunname":"func (id MixerSelemId) native() *C.snd_mixer_selem_id_t","Funname":"native","Returntype":"*C.snd_mixer_selem_id_t","Args":""},{"Uniquefunname":"func (m Mixer) native() *C.snd_mixer_t","Funname":"native","Returntype":"*C.snd_mixer_t","Args":""},{"Uniquefunname":"func (v CTL) native() *C.snd_ctl_t","Funname":"native","Returntype":"*C.snd_ctl_t","Args":""},{"Uniquefunname":"func (v CTLCardInfo) native() *C.snd_ctl_card_info_t","Funname":"native","Returntype":"*C.snd_ctl_card_info_t","Args":""},{"Uniquefunname":"func (v Output) native() *C.snd_output_t","Funname":"native","Returntype":"*C.snd_output_t","Args":""},{"Uniquefunname":"func (v PCM) native() *C.snd_pcm_t","Funname":"native","Returntype":"*C.snd_pcm_t","Args":""},{"Uniquefunname":"func (v PCMHwParams) native() *C.snd_pcm_hw_params_t","Funname":"native","Returntype":"*C.snd_pcm_hw_params_t","Args":""},{"Uniquefunname":"func (v PCMInfo) native() *C.snd_pcm_info_t","Funname":"native","Returntype":"*C.snd_pcm_info_t","Args":""},{"Uniquefunname":"func newError(fn string, code C.int) error","Funname":"newError","Returntype":"error","Args":"fn string, code C.int"},{"Uniquefunname":"func wrapCTL(p *C.snd_ctl_t) CTL","Funname":"wrapCTL","Returntype":"CTL","Args":"p *C.snd_ctl_t"},{"Uniquefunname":"func wrapCTLCardInfo(ptr *C.snd_ctl_card_info_t) CTLCardInfo","Funname":"wrapCTLCardInfo","Returntype":"CTLCardInfo","Args":"ptr *C.snd_ctl_card_info_t"},{"Uniquefunname":"func wrapMixer(ptr *C.snd_mixer_t) Mixer","Funname":"wrapMixer","Returntype":"Mixer","Args":"ptr *C.snd_mixer_t"},{"Uniquefunname":"func wrapMixerElem(ptr *C.snd_mixer_elem_t) MixerElem","Funname":"wrapMixerElem","Returntype":"MixerElem","Args":"ptr *C.snd_mixer_elem_t"},{"Uniquefunname":"func wrapMixerSelemId(ptr *C.snd_mixer_selem_id_t) MixerSelemId","Funname":"wrapMixerSelemId","Returntype":"MixerSelemId","Args":"ptr *C.snd_mixer_selem_id_t"},{"Uniquefunname":"func wrapPCM(ptr *C.snd_pcm_t) PCM","Funname":"wrapPCM","Returntype":"PCM","Args":"ptr *C.snd_pcm_t"},{"Uniquefunname":"func wrapPCMHwParams(ptr *C.snd_pcm_hw_params_t) PCMHwParams","Funname":"wrapPCMHwParams","Returntype":"PCMHwParams","Args":"ptr *C.snd_pcm_hw_params_t"},{"Uniquefunname":"func wrapPCMInfo(ptr *C.snd_pcm_info_t) PCMInfo","Funname":"wrapPCMInfo","Returntype":"PCMInfo","Args":"ptr *C.snd_pcm_info_t"}],"Records":[{"Name":"struct:asound.CTL","Fields":["asound.CTL.Ptr unsafe.Pointer"]},{"Name":"struct:asound.CTLCardInfo","Fields":["asound.CTLCardInfo.Ptr unsafe.Pointer"]},{"Name":"struct:asound.DeviceNameHints","Fields":["asound.DeviceNameHints.Ptr *unsafe.Pointer"]},{"Name":"struct:asound.DeviceNameHintsIter","Fields":["asound.DeviceNameHintsIter.hints *unsafe.Pointer","asound.DeviceNameHintsIter.n *unsafe.Pointer"]},{"Name":"var:asound","Fields":["asound.ErrUnderrun"]},{"Name":"struct:asound.Error","Fields":["asound.Error.code C.int","asound.Error.fn string"]},{"Name":"struct:asound.Mixer","Fields":["asound.Mixer.Ptr unsafe.Pointer"]},{"Name":"struct:asound.MixerClass","Fields":["asound.MixerClass.Ptr unsafe.Pointer"]},{"Name":"struct:asound.MixerElem","Fields":["asound.MixerElem.Ptr unsafe.Pointer"]},{"Name":"const:asound","Fields":["asound.MixerSAbstractBasic","asound.MixerSAbstractNone","asound.MixerSChanFrontCenter","asound.MixerSChanFrontLeft","asound.MixerSChanFrontRight","asound.MixerSChanLast","asound.MixerSChanMono","asound.MixerSChanRearCenter","asound.MixerSChanRearLeft","asound.MixerSChanRearRight","asound.MixerSChanSideLeft","asound.MixerSChanSideRight","asound.MixerSChanUnknown","asound.MixerSChanWoofer","asound.PCMAccessMMapComplex","asound.PCMAccessMMapInterleaved","asound.PCMAccessMMapNonInterleaved","asound.PCMAccessRWInterleaved","asound.PCMAccessRWNonInterleaved","asound.PCMFormatFloat64BE","asound.PCMFormatFloat64LE","asound.PCMFormatFloatBE","asound.PCMFormatFloatLE","asound.PCMFormatS16BE","asound.PCMFormatS16LE","asound.PCMFormatS24BE","asound.PCMFormatS24LE","asound.PCMFormatS32BE","asound.PCMFormatS32LE","asound.PCMFormatS8","asound.PCMFormatU16BE","asound.PCMFormatU16LE","asound.PCMFormatU24BE","asound.PCMFormatU24LE","asound.PCMFormatU32BE","asound.PCMFormatU32LE","asound.PCMFormatU8","asound.PCMStreamCapture","asound.PCMStreamPlayback","asound.sizeOfPointer"]},{"Name":"struct:asound.MixerSelem","Fields":["asound.MixerSelem.Ptr unsafe.Pointer"]},{"Name":"struct:asound.MixerSelemId","Fields":["asound.MixerSelemId.Ptr unsafe.Pointer"]},{"Name":"struct:asound.MixerSelemRegopt","Fields":["asound.MixerSelemRegopt.c C.struct_snd_mixer_selem_regopt","asound.MixerSelemRegopt.device *C.char"]},{"Name":"struct:asound.Output","Fields":["asound.Output.Ptr unsafe.Pointer"]},{"Name":"struct:asound.PCM","Fields":["asound.PCM.Ptr unsafe.Pointer"]},{"Name":"struct:asound.PCMHwParams","Fields":["asound.PCMHwParams.Ptr unsafe.Pointer"]},{"Name":"struct:asound.PCMInfo","Fields":["asound.PCMInfo.Ptr unsafe.Pointer"]}]} {"Filepath":"backlight/common/common.go","Functions":[{"Uniquefunname":"func (c *Controller) GetBrightness() (int, error)","Funname":"GetBrightness","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (c *Controller) GetPropBytes(name string) ([]byte, error)","Funname":"GetPropBytes","Returntype":"([]byte, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetPropInt(name string) (int, error)","Funname":"GetPropInt","Returntype":"(int, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetPropString(name string) (string, error)","Funname":"GetPropString","Returntype":"(string, error)","Args":"name string"},{"Uniquefunname":"func ListControllerPaths(dir string) ([]string, error)","Funname":"ListControllerPaths","Returntype":"([]string, error)","Args":"dir string"},{"Uniquefunname":"func NewController(path string) (*Controller, error)","Funname":"NewController","Returntype":"(*Controller, error)","Args":"path string"},{"Uniquefunname":"func (c *Controller) GetBrightness() (int, error)","Funname":"common.Controller.GetBrightness","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (c *Controller) GetPropBytes(name string) ([]byte, error)","Funname":"common.Controller.GetPropBytes","Returntype":"([]byte, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetPropInt(name string) (int, error)","Funname":"common.Controller.GetPropInt","Returntype":"(int, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetPropString(name string) (string, error)","Funname":"common.Controller.GetPropString","Returntype":"(string, error)","Args":"name string"},{"Uniquefunname":"func ListControllerPaths(dir string) ([]string, error)","Funname":"common.ListControllerPaths","Returntype":"([]string, error)","Args":"dir string"},{"Uniquefunname":"func NewController(path string) (*Controller, error)","Funname":"common.NewController","Returntype":"(*Controller, error)","Args":"path string"}],"Records":[{"Name":"struct:common.Controller","Fields":["common.Controller.MaxBrightness int","common.Controller.Name string","common.Controller.Path string"]},{"Name":"var:common","Fields":["common.errMaxBrightnessIsZero"]}]} {"Filepath":"backlight/display/display.go","Functions":[{"Uniquefunname":"func (c *Controller) GetActualBrightness() (int, error)","Funname":"GetActualBrightness","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (cs Controllers) GetByEDID(edid []byte) *Controller","Funname":"GetByEDID","Returntype":"*Controller","Args":"edid []byte"},{"Uniquefunname":"func (cs Controllers) GetByName(name string) *Controller","Funname":"GetByName","Returntype":"*Controller","Args":"name string"},{"Uniquefunname":"func List() (Controllers, error)","Funname":"List","Returntype":"(Controllers, error)","Args":""},{"Uniquefunname":"func NewController(path string) (*Controller, error)","Funname":"NewController","Returntype":"(*Controller, error)","Args":"path string"},{"Uniquefunname":"func byteSliceEqual(a, b []byte) bool","Funname":"byteSliceEqual","Returntype":"bool","Args":"a, b []byte"},{"Uniquefunname":"func (c *Controller) GetActualBrightness() (int, error)","Funname":"display.Controller.GetActualBrightness","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (cs Controllers) GetByEDID(edid []byte) *Controller","Funname":"display.Controllers.GetByEDID","Returntype":"*Controller","Args":"edid []byte"},{"Uniquefunname":"func (cs Controllers) GetByName(name string) *Controller","Funname":"display.Controllers.GetByName","Returntype":"*Controller","Args":"name string"},{"Uniquefunname":"func List() (Controllers, error)","Funname":"display.List","Returntype":"(Controllers, error)","Args":""},{"Uniquefunname":"func NewController(path string) (*Controller, error)","Funname":"display.NewController","Returntype":"(*Controller, error)","Args":"path string"},{"Uniquefunname":"func byteSliceEqual(a, b []byte) bool","Funname":"display.byteSliceEqual","Returntype":"bool","Args":"a, b []byte"},{"Uniquefunname":"func list(dir string) (Controllers, error)","Funname":"display.list","Returntype":"(Controllers, error)","Args":"dir string"},{"Uniquefunname":"func list(dir string) (Controllers, error)","Funname":"list","Returntype":"(Controllers, error)","Args":"dir string"}],"Records":[{"Name":"struct:display.Controller","Fields":["display.Controller.DeviceEDID []byte","display.Controller.Type ControllerType"]},{"Name":"const:display","Fields":["display.controllersDir"]}]} {"Filepath":"backlight/display/display_test.go","Functions":[{"Uniquefunname":"func TestList(t *testing.T)","Funname":"TestList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_list(t *testing.T)","Funname":"Test_list","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestList(t *testing.T)","Funname":"display.TestList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_list(t *testing.T)","Funname":"display.Test_list","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func getControllerByName(cs []*Controller, name string) *Controller","Funname":"display.getControllerByName","Returntype":"*Controller","Args":"cs []*Controller, name string"},{"Uniquefunname":"func getControllerByName(cs []*Controller, name string) *Controller","Funname":"getControllerByName","Returntype":"*Controller","Args":"cs []*Controller, name string"}],"Records":[{"Name":"var:display","Fields":["display.edid0","display.edid1"]}]} {"Filepath":"backlight/display/type.go","Functions":[{"Uniquefunname":"func ControllerTypeFromString(str string) ControllerType","Funname":"ControllerTypeFromString","Returntype":"ControllerType","Args":"str string"},{"Uniquefunname":"func (t ControllerType) String() string","Funname":"String","Returntype":"string","Args":""},{"Uniquefunname":"func (t ControllerType) String() string","Funname":"display.ControllerType.String","Returntype":"string","Args":""},{"Uniquefunname":"func ControllerTypeFromString(str string) ControllerType","Funname":"display.ControllerTypeFromString","Returntype":"ControllerType","Args":"str string"}],"Records":[{"Name":"const:display","Fields":["display.ControllerTypeFirmware","display.ControllerTypePlatform","display.ControllerTypeRaw","display.ControllerTypeUnknown"]}]} {"Filepath":"backlight/keyboard/keyboard.go","Functions":[{"Uniquefunname":"func List() ([]*Controller, error)","Funname":"List","Returntype":"([]*Controller, error)","Args":""},{"Uniquefunname":"func List() ([]*Controller, error)","Funname":"keyboard.List","Returntype":"([]*Controller, error)","Args":""},{"Uniquefunname":"func list(dir string) ([]*Controller, error)","Funname":"keyboard.list","Returntype":"([]*Controller, error)","Args":"dir string"},{"Uniquefunname":"func list(dir string) ([]*Controller, error)","Funname":"list","Returntype":"([]*Controller, error)","Args":"dir string"}],"Records":[{"Name":"const:keyboard","Fields":["keyboard.controllersDir"]}]} {"Filepath":"backlight/keyboard/keyboard_test.go","Functions":[{"Uniquefunname":"func TestList(t *testing.T)","Funname":"TestList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_list(t *testing.T)","Funname":"Test_list","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestList(t *testing.T)","Funname":"keyboard.TestList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_list(t *testing.T)","Funname":"keyboard.Test_list","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/calendar.go","Functions":[{"Uniquefunname":"func SolarToLunar(year, month, day int) (LunarDayInfo, bool)","Funname":"SolarToLunar","Returntype":"(LunarDayInfo, bool)","Args":"year, month, day int"},{"Uniquefunname":"func SolarToLunar(year, month, day int) (LunarDayInfo, bool)","Funname":"calendar.SolarToLunar","Returntype":"(LunarDayInfo, bool)","Args":"year, month, day int"}],"Records":[{"Name":"struct:calendar.LunarDayInfo","Fields":["calendar.LunarDayInfo.GanZhiDay string","calendar.LunarDayInfo.GanZhiMonth string","calendar.LunarDayInfo.GanZhiYear string","calendar.LunarDayInfo.LunarDayName string","calendar.LunarDayInfo.LunarFestival string","calendar.LunarDayInfo.LunarLeapMonth int32","calendar.LunarDayInfo.LunarMonthName string","calendar.LunarDayInfo.SolarFestival string","calendar.LunarDayInfo.Term string","calendar.LunarDayInfo.Worktime int32","calendar.LunarDayInfo.Zodiac string"]}]} {"Filepath":"calendar/calendar_test.go","Functions":[{"Uniquefunname":"func Test_SolarToLunar(t *testing.T)","Funname":"Test_SolarToLunar","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_SolarToLunar(t *testing.T)","Funname":"calendar.Test_SolarToLunar","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/day.go","Functions":[{"Uniquefunname":"func (d *Day) Festival() string","Funname":"Festival","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) Festival() string","Funname":"calendar.Day.Festival","Returntype":"string","Args":""},{"Uniquefunname":"func festivalForFatherAndMother(year, month, day int) string","Funname":"calendar.festivalForFatherAndMother","Returntype":"string","Args":"year, month, day int"},{"Uniquefunname":"func festivalForFatherAndMother(year, month, day int) string","Funname":"festivalForFatherAndMother","Returntype":"string","Args":"year, month, day int"}],"Records":[{"Name":"struct:calendar.Day","Fields":["calendar.Day.Day int","calendar.Day.Month int","calendar.Day.Year int"]},{"Name":"struct:calendar.festival","Fields":["calendar.festival.name string","calendar.festival.startYear int"]},{"Name":"var:calendar","Fields":["calendar.solarFestivals"]}]} {"Filepath":"calendar/lunar/day.go","Functions":[{"Uniquefunname":"func (d *Day) DayName() string","Funname":"DayName","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) Festival() string","Funname":"Festival","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) GanZhiDay() string","Funname":"GanZhiDay","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) GanZhiMonth() string","Funname":"GanZhiMonth","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) GanZhiYear() string","Funname":"GanZhiYear","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) MonthName() string","Funname":"MonthName","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) SolarTermName() string","Funname":"SolarTermName","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) YearZodiac() string","Funname":"YearZodiac","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) DayName() string","Funname":"lunar.Day.DayName","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) Festival() string","Funname":"lunar.Day.Festival","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) GanZhiDay() string","Funname":"lunar.Day.GanZhiDay","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) GanZhiMonth() string","Funname":"lunar.Day.GanZhiMonth","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) GanZhiYear() string","Funname":"lunar.Day.GanZhiYear","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) MonthName() string","Funname":"lunar.Day.MonthName","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) SolarTermName() string","Funname":"lunar.Day.SolarTermName","Returntype":"string","Args":""},{"Uniquefunname":"func (d *Day) YearZodiac() string","Funname":"lunar.Day.YearZodiac","Returntype":"string","Args":""}],"Records":[{"Name":"struct:lunar.Day","Fields":["lunar.Day.Day int","lunar.Day.LunarDay int","lunar.Day.LunarMonth *Month","lunar.Day.LunarYear int","lunar.Day.Month int","lunar.Day.MonthZhi int","lunar.Day.SolarTerm int","lunar.Day.Year int"]},{"Name":"var:lunar","Fields":["lunar.dayNames","lunar.lunarFestival","lunar.monthNames"]}]} {"Filepath":"calendar/lunar/day_test.go","Functions":[{"Uniquefunname":"func TestDay(t *testing.T)","Funname":"TestDay","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestDay(t *testing.T)","Funname":"lunar.TestDay","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/lunar/elp82.go","Functions":[{"Uniquefunname":"func CalcMoonECLongitudePeriodic(D, M, Mp, F, E float64) float64","Funname":"CalcMoonECLongitudePeriodic","Returntype":"float64","Args":"D, M, Mp, F, E float64"},{"Uniquefunname":"func CalcMoonLongitudePerturbation(T, Lp, F float64) float64","Funname":"CalcMoonLongitudePerturbation","Returntype":"float64","Args":"T, Lp, F float64"},{"Uniquefunname":"func GetMoonEclipticLongitudeEC(jd float64) float64","Funname":"GetMoonEclipticLongitudeEC","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetMoonEclipticParameter(T float64) (Lp, D, M, Mp, F, E float64)","Funname":"GetMoonEclipticParameter","Returntype":"(Lp, D, M, Mp, F, E float64)","Args":"T float64"},{"Uniquefunname":"func CalcMoonECLongitudePeriodic(D, M, Mp, F, E float64) float64","Funname":"lunar.CalcMoonECLongitudePeriodic","Returntype":"float64","Args":"D, M, Mp, F, E float64"},{"Uniquefunname":"func CalcMoonLongitudePerturbation(T, Lp, F float64) float64","Funname":"lunar.CalcMoonLongitudePerturbation","Returntype":"float64","Args":"T, Lp, F float64"},{"Uniquefunname":"func GetMoonEclipticLongitudeEC(jd float64) float64","Funname":"lunar.GetMoonEclipticLongitudeEC","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetMoonEclipticParameter(T float64) (Lp, D, M, Mp, F, E float64)","Funname":"lunar.GetMoonEclipticParameter","Returntype":"(Lp, D, M, Mp, F, E float64)","Args":"T float64"}],"Records":null} {"Filepath":"calendar/lunar/elp82_const.go","Functions":null,"Records":[{"Name":"struct:lunar.MoonEclipticLongitudeCoeff","Fields":["lunar.MoonEclipticLongitudeCoeff.D float64","lunar.MoonEclipticLongitudeCoeff.EiA float64","lunar.MoonEclipticLongitudeCoeff.ErA float64","lunar.MoonEclipticLongitudeCoeff.F float64","lunar.MoonEclipticLongitudeCoeff.M float64","lunar.MoonEclipticLongitudeCoeff.Mp float64"]},{"Name":"var:lunar","Fields":["lunar.MoonLongitude"]}]} {"Filepath":"calendar/lunar/elp82_test.go","Functions":[{"Uniquefunname":"func Test_CalcMoonECLongitudePeriodic(t *testing.T)","Funname":"Test_CalcMoonECLongitudePeriodic","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetMoonEclipticLongitudeEC(t *testing.T)","Funname":"Test_GetMoonEclipticLongitudeEC","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetMoonEclipticParameter(t *testing.T)","Funname":"Test_GetMoonEclipticParameter","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_CalcMoonECLongitudePeriodic(t *testing.T)","Funname":"lunar.Test_CalcMoonECLongitudePeriodic","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetMoonEclipticLongitudeEC(t *testing.T)","Funname":"lunar.Test_GetMoonEclipticLongitudeEC","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetMoonEclipticParameter(t *testing.T)","Funname":"lunar.Test_GetMoonEclipticParameter","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/lunar/iau1980.go","Functions":[{"Uniquefunname":"func CalcEarthLongitudeNutation(T float64) float64","Funname":"CalcEarthLongitudeNutation","Returntype":"float64","Args":"T float64"},{"Uniquefunname":"func CalcEarthObliquityNutation(dt float64) float64","Funname":"CalcEarthObliquityNutation","Returntype":"float64","Args":"dt float64"},{"Uniquefunname":"func GetEarthNutationParameter(T float64) (D, M, Mp, F, Omega float64)","Funname":"GetEarthNutationParameter","Returntype":"(D, M, Mp, F, Omega float64)","Args":"T float64"},{"Uniquefunname":"func CalcEarthLongitudeNutation(T float64) float64","Funname":"lunar.CalcEarthLongitudeNutation","Returntype":"float64","Args":"T float64"},{"Uniquefunname":"func CalcEarthObliquityNutation(dt float64) float64","Funname":"lunar.CalcEarthObliquityNutation","Returntype":"float64","Args":"dt float64"},{"Uniquefunname":"func GetEarthNutationParameter(T float64) (D, M, Mp, F, Omega float64)","Funname":"lunar.GetEarthNutationParameter","Returntype":"(D, M, Mp, F, Omega float64)","Args":"T float64"}],"Records":[{"Name":"struct:lunar.NuationCoefficient","Fields":["lunar.NuationCoefficient.Cosine1 float64","lunar.NuationCoefficient.Cosine2 float64","lunar.NuationCoefficient.D float64","lunar.NuationCoefficient.F float64","lunar.NuationCoefficient.M float64","lunar.NuationCoefficient.Mp float64","lunar.NuationCoefficient.Omega float64","lunar.NuationCoefficient.Sine1 float64","lunar.NuationCoefficient.Sine2 float64"]},{"Name":"var:lunar","Fields":["lunar.coefficient","lunar.nuation"]}]} {"Filepath":"calendar/lunar/iau1980_test.go","Functions":[{"Uniquefunname":"func Test_CalcEarthLongitudeNutation(t *testing.T)","Funname":"Test_CalcEarthLongitudeNutation","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_CalcEarthObliquityNutation(t *testing.T)","Funname":"Test_CalcEarthObliquityNutation","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_CalcEarthLongitudeNutation(t *testing.T)","Funname":"lunar.Test_CalcEarthLongitudeNutation","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_CalcEarthObliquityNutation(t *testing.T)","Funname":"lunar.Test_CalcEarthObliquityNutation","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/lunar/lunar.go","Functions":[{"Uniquefunname":"func GetDayGanZhi(year, month, day int) string","Funname":"GetDayGanZhi","Returntype":"string","Args":"year, month, day int"},{"Uniquefunname":"func GetYearGanZhi(year int) string","Funname":"GetYearGanZhi","Returntype":"string","Args":"year int"},{"Uniquefunname":"func GetYearZodiac(year int) string","Funname":"GetYearZodiac","Returntype":"string","Args":"year int"},{"Uniquefunname":"func New(year int) *Calendar","Funname":"New","Returntype":"*Calendar","Args":"year int"},{"Uniquefunname":"func (cc *Calendar) SolarDayToLunarDay(month, day int) *Day","Funname":"SolarDayToLunarDay","Returntype":"*Day","Args":"month, day int"},{"Uniquefunname":"func (m *Month) String() string","Funname":"String","Returntype":"string","Args":""},{"Uniquefunname":"func (cc *Calendar) calcLeapMonth()","Funname":"calcLeapMonth","Returntype":"","Args":""},{"Uniquefunname":"func (cc *Calendar) calcProcData()","Funname":"calcProcData","Returntype":"","Args":""},{"Uniquefunname":"func cyclical(num int) string","Funname":"cyclical","Returntype":"string","Args":"num int"},{"Uniquefunname":"func deltaDays(t1, t2 time.Time) int","Funname":"deltaDays","Returntype":"int","Args":"t1, t2 time.Time"},{"Uniquefunname":"func (cc *Calendar) fillMonths()","Funname":"fillMonths","Returntype":"","Args":""},{"Uniquefunname":"func get15NewMoonJDs(jd float64) *[15]float64","Funname":"get15NewMoonJDs","Returntype":"*[15]float64","Args":"jd float64"},{"Uniquefunname":"func get25SolarTermJDs(year, start int) *[25]float64","Funname":"get25SolarTermJDs","Returntype":"*[25]float64","Args":"year, start int"},{"Uniquefunname":"func (cc *Calendar) getMonthSolarTerms(month int) [2]*solarTermInfo","Funname":"getMonthSolarTerms","Returntype":"[2]*solarTermInfo","Args":"month int"},{"Uniquefunname":"func (cc *Calendar) getSolarTermInfo(index int) *solarTermInfo","Funname":"getSolarTermInfo","Returntype":"*solarTermInfo","Args":"index int"},{"Uniquefunname":"func (cc *Calendar) SolarDayToLunarDay(month, day int) *Day","Funname":"lunar.Calendar.SolarDayToLunarDay","Returntype":"*Day","Args":"month, day int"},{"Uniquefunname":"func (cc *Calendar) calcLeapMonth()","Funname":"lunar.Calendar.calcLeapMonth","Returntype":"","Args":""},{"Uniquefunname":"func (cc *Calendar) calcProcData()","Funname":"lunar.Calendar.calcProcData","Returntype":"","Args":""},{"Uniquefunname":"func (cc *Calendar) fillMonths()","Funname":"lunar.Calendar.fillMonths","Returntype":"","Args":""},{"Uniquefunname":"func (cc *Calendar) getMonthSolarTerms(month int) [2]*solarTermInfo","Funname":"lunar.Calendar.getMonthSolarTerms","Returntype":"[2]*solarTermInfo","Args":"month int"},{"Uniquefunname":"func (cc *Calendar) getSolarTermInfo(index int) *solarTermInfo","Funname":"lunar.Calendar.getSolarTermInfo","Returntype":"*solarTermInfo","Args":"index int"},{"Uniquefunname":"func GetDayGanZhi(year, month, day int) string","Funname":"lunar.GetDayGanZhi","Returntype":"string","Args":"year, month, day int"},{"Uniquefunname":"func GetYearGanZhi(year int) string","Funname":"lunar.GetYearGanZhi","Returntype":"string","Args":"year int"},{"Uniquefunname":"func GetYearZodiac(year int) string","Funname":"lunar.GetYearZodiac","Returntype":"string","Args":"year int"},{"Uniquefunname":"func (m *Month) String() string","Funname":"lunar.Month.String","Returntype":"string","Args":""},{"Uniquefunname":"func New(year int) *Calendar","Funname":"lunar.New","Returntype":"*Calendar","Args":"year int"},{"Uniquefunname":"func cyclical(num int) string","Funname":"lunar.cyclical","Returntype":"string","Args":"num int"},{"Uniquefunname":"func deltaDays(t1, t2 time.Time) int","Funname":"lunar.deltaDays","Returntype":"int","Args":"t1, t2 time.Time"},{"Uniquefunname":"func get15NewMoonJDs(jd float64) *[15]float64","Funname":"lunar.get15NewMoonJDs","Returntype":"*[15]float64","Args":"jd float64"},{"Uniquefunname":"func get25SolarTermJDs(year, start int) *[25]float64","Funname":"lunar.get25SolarTermJDs","Returntype":"*[25]float64","Args":"year, start int"},{"Uniquefunname":"func newCalendar(year int) *Calendar","Funname":"lunar.newCalendar","Returntype":"*Calendar","Args":"year int"},{"Uniquefunname":"func newCalendar(year int) *Calendar","Funname":"newCalendar","Returntype":"*Calendar","Args":"year int"}],"Records":[{"Name":"var:lunar","Fields":["lunar.Animals","lunar.Gan","lunar.Zhi","lunar.ccCache"]},{"Name":"struct:lunar.Calendar","Fields":["lunar.Calendar.Months []*Month","lunar.Calendar.NewMoonJDs *[15]float64","lunar.Calendar.SolarTermJDs *[25]float64","lunar.Calendar.SolarTermTimes *[25]time.Time","lunar.Calendar.Year int","lunar.Calendar.solarTermYearDays []int"]},{"Name":"struct:lunar.Month","Fields":["lunar.Month.Days int","lunar.Month.IsLeap bool","lunar.Month.LunarYear int","lunar.Month.Name int","lunar.Month.ShuoJD float64","lunar.Month.ShuoTime time.Time"]},{"Name":"struct:lunar.solarTermInfo","Fields":["lunar.solarTermInfo.Day int","lunar.solarTermInfo.SolarTerm int"]}]} {"Filepath":"calendar/lunar/lunar_test.go","Functions":[{"Uniquefunname":"func Test_GetYearGanZhi(t *testing.T)","Funname":"Test_GetYearGanZhi","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetYearZodiac(t *testing.T)","Funname":"Test_GetYearZodiac","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_New(t *testing.T)","Funname":"Test_New","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_cyclical(t *testing.T)","Funname":"Test_cyclical","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetYearGanZhi(t *testing.T)","Funname":"lunar.Test_GetYearGanZhi","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetYearZodiac(t *testing.T)","Funname":"lunar.Test_GetYearZodiac","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_New(t *testing.T)","Funname":"lunar.Test_New","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_cyclical(t *testing.T)","Funname":"lunar.Test_cyclical","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/lunar/mathutil.go","Functions":[{"Uniquefunname":"func DmsToDegrees(degrees int, mintues int, seconds float64) float64","Funname":"DmsToDegrees","Returntype":"float64","Args":"degrees int, mintues int, seconds float64"},{"Uniquefunname":"func DmsToRadians(d int, m int, s float64) float64","Funname":"DmsToRadians","Returntype":"float64","Args":"d int, m int, s float64"},{"Uniquefunname":"func DmsToSeconds(d int, m int, s float64) float64","Funname":"DmsToSeconds","Returntype":"float64","Args":"d int, m int, s float64"},{"Uniquefunname":"func Mod2Pi(r float64) float64","Funname":"Mod2Pi","Returntype":"float64","Args":"r float64"},{"Uniquefunname":"func ModPi(r float64) float64","Funname":"ModPi","Returntype":"float64","Args":"r float64"},{"Uniquefunname":"func NewtonIteration(f func(float64) float64, x0 float64) float64","Funname":"NewtonIteration","Returntype":"float64","Args":"f func(float64) float64, x0 float64"},{"Uniquefunname":"func SecondsToDegrees(seconds float64) float64","Funname":"SecondsToDegrees","Returntype":"float64","Args":"seconds float64"},{"Uniquefunname":"func SecondsToRadians(seconds float64) float64","Funname":"SecondsToRadians","Returntype":"float64","Args":"seconds float64"},{"Uniquefunname":"func ToDegrees(rad float64) float64","Funname":"ToDegrees","Returntype":"float64","Args":"rad float64"},{"Uniquefunname":"func ToRadians(degrees float64) float64","Funname":"ToRadians","Returntype":"float64","Args":"degrees float64"},{"Uniquefunname":"func DmsToDegrees(degrees int, mintues int, seconds float64) float64","Funname":"lunar.DmsToDegrees","Returntype":"float64","Args":"degrees int, mintues int, seconds float64"},{"Uniquefunname":"func DmsToRadians(d int, m int, s float64) float64","Funname":"lunar.DmsToRadians","Returntype":"float64","Args":"d int, m int, s float64"},{"Uniquefunname":"func DmsToSeconds(d int, m int, s float64) float64","Funname":"lunar.DmsToSeconds","Returntype":"float64","Args":"d int, m int, s float64"},{"Uniquefunname":"func Mod2Pi(r float64) float64","Funname":"lunar.Mod2Pi","Returntype":"float64","Args":"r float64"},{"Uniquefunname":"func ModPi(r float64) float64","Funname":"lunar.ModPi","Returntype":"float64","Args":"r float64"},{"Uniquefunname":"func NewtonIteration(f func(float64) float64, x0 float64) float64","Funname":"lunar.NewtonIteration","Returntype":"float64","Args":"f func(float64) float64, x0 float64"},{"Uniquefunname":"func SecondsToDegrees(seconds float64) float64","Funname":"lunar.SecondsToDegrees","Returntype":"float64","Args":"seconds float64"},{"Uniquefunname":"func SecondsToRadians(seconds float64) float64","Funname":"lunar.SecondsToRadians","Returntype":"float64","Args":"seconds float64"},{"Uniquefunname":"func ToDegrees(rad float64) float64","Funname":"lunar.ToDegrees","Returntype":"float64","Args":"rad float64"},{"Uniquefunname":"func ToRadians(degrees float64) float64","Funname":"lunar.ToRadians","Returntype":"float64","Args":"degrees float64"}],"Records":null} {"Filepath":"calendar/lunar/mathutil_test.go","Functions":[{"Uniquefunname":"func TestMathUtil(t *testing.T)","Funname":"TestMathUtil","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMathUtil(t *testing.T)","Funname":"lunar.TestMathUtil","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/lunar/newmoon.go","Functions":[{"Uniquefunname":"func getNewMoonJD(jd0 float64) float64","Funname":"getNewMoonJD","Returntype":"float64","Args":"jd0 float64"},{"Uniquefunname":"func getNewMoonJD(jd0 float64) float64","Funname":"lunar.getNewMoonJD","Returntype":"float64","Args":"jd0 float64"}],"Records":null} {"Filepath":"calendar/lunar/newmoon_test.go","Functions":[{"Uniquefunname":"func Test_getNewMoonJD(t *testing.T)","Funname":"Test_getNewMoonJD","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_getNewMoonJD(t *testing.T)","Funname":"lunar.Test_getNewMoonJD","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/lunar/solarterms.go","Functions":[{"Uniquefunname":"func GetSolarTermJD(year, order int) float64","Funname":"GetSolarTermJD","Returntype":"float64","Args":"year, order int"},{"Uniquefunname":"func GetSolarTermName(order int) string","Funname":"GetSolarTermName","Returntype":"string","Args":"order int"},{"Uniquefunname":"func GetSolarTermJD(year, order int) float64","Funname":"lunar.GetSolarTermJD","Returntype":"float64","Args":"year, order int"},{"Uniquefunname":"func GetSolarTermName(order int) string","Funname":"lunar.GetSolarTermName","Returntype":"string","Args":"order int"}],"Records":[{"Name":"const:lunar","Fields":["lunar.BaiLu","lunar.ChuShu","lunar.ChunFen","lunar.DaHan","lunar.DaShu","lunar.DaXue","lunar.DongZhi","lunar.GuYu","lunar.HanLu","lunar.JingZhe","lunar.LiChun","lunar.LiDong","lunar.LiQiu","lunar.LiXia","lunar.MangZhong","lunar.QingMing","lunar.QiuFen","lunar.ShuangJiang","lunar.XiaZhi","lunar.XiaoHan","lunar.XiaoMan","lunar.XiaoShu","lunar.XiaoXue","lunar.YuShui"]},{"Name":"var:lunar","Fields":["lunar.SolarTermNames"]}]} {"Filepath":"calendar/lunar/solarterms_test.go","Functions":[{"Uniquefunname":"func TestSolarTerms(t *testing.T)","Funname":"TestSolarTerms","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSolarTerms(t *testing.T)","Funname":"lunar.TestSolarTerms","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/lunar/vsop87earthd.go","Functions":[{"Uniquefunname":"func GetEarthEclipticLongitudeForSun(jd float64) float64","Funname":"GetEarthEclipticLongitudeForSun","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetSunEclipticLatitudeForEarth(jd float64) float64","Funname":"GetSunEclipticLatitudeForEarth","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetSunEclipticLongitudeForEarth(jd float64) float64","Funname":"GetSunEclipticLongitudeForEarth","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetSunRadiusForEarth(jd float64) float64","Funname":"GetSunRadiusForEarth","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func Vsop2Fk5LongitudeCorrection(l float64, b float64, jd float64) float64","Funname":"Vsop2Fk5LongitudeCorrection","Returntype":"float64","Args":"l float64, b float64, jd float64"},{"Uniquefunname":"func GetEarthEclipticLongitudeForSun(jd float64) float64","Funname":"lunar.GetEarthEclipticLongitudeForSun","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetSunEclipticLatitudeForEarth(jd float64) float64","Funname":"lunar.GetSunEclipticLatitudeForEarth","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetSunEclipticLongitudeForEarth(jd float64) float64","Funname":"lunar.GetSunEclipticLongitudeForEarth","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetSunRadiusForEarth(jd float64) float64","Funname":"lunar.GetSunRadiusForEarth","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func Vsop2Fk5LongitudeCorrection(l float64, b float64, jd float64) float64","Funname":"lunar.Vsop2Fk5LongitudeCorrection","Returntype":"float64","Args":"l float64, b float64, jd float64"}],"Records":[{"Name":"var:lunar","Fields":["lunar.lightAberration"]}]} {"Filepath":"calendar/lunar/vsop87earthd_const.go","Functions":[{"Uniquefunname":"func GetEarthB0(t float64) float64","Funname":"GetEarthB0","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB1(t float64) float64","Funname":"GetEarthB1","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB2(t float64) float64","Funname":"GetEarthB2","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB3(t float64) float64","Funname":"GetEarthB3","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB4(t float64) float64","Funname":"GetEarthB4","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL0(t float64) float64","Funname":"GetEarthL0","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL1(t float64) float64","Funname":"GetEarthL1","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL2(t float64) float64","Funname":"GetEarthL2","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL3(t float64) float64","Funname":"GetEarthL3","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL4(t float64) float64","Funname":"GetEarthL4","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL5(t float64) float64","Funname":"GetEarthL5","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR0(t float64) float64","Funname":"GetEarthR0","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR1(t float64) float64","Funname":"GetEarthR1","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR2(t float64) float64","Funname":"GetEarthR2","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR3(t float64) float64","Funname":"GetEarthR3","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR4(t float64) float64","Funname":"GetEarthR4","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR5(t float64) float64","Funname":"GetEarthR5","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB0(t float64) float64","Funname":"lunar.GetEarthB0","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB1(t float64) float64","Funname":"lunar.GetEarthB1","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB2(t float64) float64","Funname":"lunar.GetEarthB2","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB3(t float64) float64","Funname":"lunar.GetEarthB3","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthB4(t float64) float64","Funname":"lunar.GetEarthB4","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL0(t float64) float64","Funname":"lunar.GetEarthL0","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL1(t float64) float64","Funname":"lunar.GetEarthL1","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL2(t float64) float64","Funname":"lunar.GetEarthL2","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL3(t float64) float64","Funname":"lunar.GetEarthL3","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL4(t float64) float64","Funname":"lunar.GetEarthL4","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthL5(t float64) float64","Funname":"lunar.GetEarthL5","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR0(t float64) float64","Funname":"lunar.GetEarthR0","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR1(t float64) float64","Funname":"lunar.GetEarthR1","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR2(t float64) float64","Funname":"lunar.GetEarthR2","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR3(t float64) float64","Funname":"lunar.GetEarthR3","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR4(t float64) float64","Funname":"lunar.GetEarthR4","Returntype":"float64","Args":"t float64"},{"Uniquefunname":"func GetEarthR5(t float64) float64","Funname":"lunar.GetEarthR5","Returntype":"float64","Args":"t float64"}],"Records":null} {"Filepath":"calendar/lunar/vsop87earthd_test.go","Functions":[{"Uniquefunname":"func Test_GetEarthXX(te *testing.T)","Funname":"Test_GetEarthXX","Returntype":"","Args":"te *testing.T"},{"Uniquefunname":"func Test_GetSunEclipticLatitudeForEarth(t *testing.T)","Funname":"Test_GetSunEclipticLatitudeForEarth","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetSunEclipticLongitudeForEarth(t *testing.T)","Funname":"Test_GetSunEclipticLongitudeForEarth","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetSunRadiusForEarth(t *testing.T)","Funname":"Test_GetSunRadiusForEarth","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetEarthXX(te *testing.T)","Funname":"lunar.Test_GetEarthXX","Returntype":"","Args":"te *testing.T"},{"Uniquefunname":"func Test_GetSunEclipticLatitudeForEarth(t *testing.T)","Funname":"lunar.Test_GetSunEclipticLatitudeForEarth","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetSunEclipticLongitudeForEarth(t *testing.T)","Funname":"lunar.Test_GetSunEclipticLongitudeForEarth","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetSunRadiusForEarth(t *testing.T)","Funname":"lunar.Test_GetSunRadiusForEarth","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/util/julianday.go","Functions":[{"Uniquefunname":"func GetDateFromJulianDay(jd float64) (yy, mm, dd int)","Funname":"GetDateFromJulianDay","Returntype":"(yy, mm, dd int)","Args":"jd float64"},{"Uniquefunname":"func GetDateTimeFromJulianDay(jd float64) time.Time","Funname":"GetDateTimeFromJulianDay","Returntype":"time.Time","Args":"jd float64"},{"Uniquefunname":"func GetTimeFromJulianDay(jd float64) (hour, minute, second int)","Funname":"GetTimeFromJulianDay","Returntype":"(hour, minute, second int)","Args":"jd float64"},{"Uniquefunname":"func GetDateFromJulianDay(jd float64) (yy, mm, dd int)","Funname":"util.GetDateFromJulianDay","Returntype":"(yy, mm, dd int)","Args":"jd float64"},{"Uniquefunname":"func GetDateTimeFromJulianDay(jd float64) time.Time","Funname":"util.GetDateTimeFromJulianDay","Returntype":"time.Time","Args":"jd float64"},{"Uniquefunname":"func GetTimeFromJulianDay(jd float64) (hour, minute, second int)","Funname":"util.GetTimeFromJulianDay","Returntype":"(hour, minute, second int)","Args":"jd float64"}],"Records":null} {"Filepath":"calendar/util/julianday_test.go","Functions":[{"Uniquefunname":"func Test_GetDateFromJulianDay(t *testing.T)","Funname":"Test_GetDateFromJulianDay","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetDateTimeFromJulianDay(t *testing.T)","Funname":"Test_GetDateTimeFromJulianDay","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetTimeFromJulianDay(t *testing.T)","Funname":"Test_GetTimeFromJulianDay","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetDateFromJulianDay(t *testing.T)","Funname":"util.Test_GetDateFromJulianDay","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetDateTimeFromJulianDay(t *testing.T)","Funname":"util.Test_GetDateTimeFromJulianDay","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetTimeFromJulianDay(t *testing.T)","Funname":"util.Test_GetTimeFromJulianDay","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"calendar/util/util.go","Functions":[{"Uniquefunname":"func GetDeltaT(year, month int) float64","Funname":"GetDeltaT","Returntype":"float64","Args":"year, month int"},{"Uniquefunname":"func GetJulianCentury(jd float64) float64","Funname":"GetJulianCentury","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetJulianThousandYears(jd float64) float64","Funname":"GetJulianThousandYears","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetSolarMonthDays(year, month int) int","Funname":"GetSolarMonthDays","Returntype":"int","Args":"year, month int"},{"Uniquefunname":"func GetWeekday(y, m, d int) int","Funname":"GetWeekday","Returntype":"int","Args":"y, m, d int"},{"Uniquefunname":"func GetYearDaysCount(year int) int","Funname":"GetYearDaysCount","Returntype":"int","Args":"year int"},{"Uniquefunname":"func IsLeapYear(year int) bool","Funname":"IsLeapYear","Returntype":"bool","Args":"year int"},{"Uniquefunname":"func JDBeijingTime2UTC(bjtJD float64) float64","Funname":"JDBeijingTime2UTC","Returntype":"float64","Args":"bjtJD float64"},{"Uniquefunname":"func JDUTC2BeijingTime(utcJD float64) float64","Funname":"JDUTC2BeijingTime","Returntype":"float64","Args":"utcJD float64"},{"Uniquefunname":"func ToJulianDate(year, month, day int) int","Funname":"ToJulianDate","Returntype":"int","Args":"year, month, day int"},{"Uniquefunname":"func ToJulianDateHMS(year, month, day, hour, minute int, second float64) float64","Funname":"ToJulianDateHMS","Returntype":"float64","Args":"year, month, day, hour, minute int, second float64"},{"Uniquefunname":"func GetDeltaT(year, month int) float64","Funname":"util.GetDeltaT","Returntype":"float64","Args":"year, month int"},{"Uniquefunname":"func GetJulianCentury(jd float64) float64","Funname":"util.GetJulianCentury","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetJulianThousandYears(jd float64) float64","Funname":"util.GetJulianThousandYears","Returntype":"float64","Args":"jd float64"},{"Uniquefunname":"func GetSolarMonthDays(year, month int) int","Funname":"util.GetSolarMonthDays","Returntype":"int","Args":"year, month int"},{"Uniquefunname":"func GetWeekday(y, m, d int) int","Funname":"util.GetWeekday","Returntype":"int","Args":"y, m, d int"},{"Uniquefunname":"func GetYearDaysCount(year int) int","Funname":"util.GetYearDaysCount","Returntype":"int","Args":"year int"},{"Uniquefunname":"func IsLeapYear(year int) bool","Funname":"util.IsLeapYear","Returntype":"bool","Args":"year int"},{"Uniquefunname":"func JDBeijingTime2UTC(bjtJD float64) float64","Funname":"util.JDBeijingTime2UTC","Returntype":"float64","Args":"bjtJD float64"},{"Uniquefunname":"func JDUTC2BeijingTime(utcJD float64) float64","Funname":"util.JDUTC2BeijingTime","Returntype":"float64","Args":"utcJD float64"},{"Uniquefunname":"func ToJulianDate(year, month, day int) int","Funname":"util.ToJulianDate","Returntype":"int","Args":"year, month, day int"},{"Uniquefunname":"func ToJulianDateHMS(year, month, day, hour, minute int, second float64) float64","Funname":"util.ToJulianDateHMS","Returntype":"float64","Args":"year, month, day, hour, minute int, second float64"}],"Records":[{"Name":"const:util","Fields":["util.J2000"]},{"Name":"var:util","Fields":["util.monthDays"]}]} {"Filepath":"calendar/util/util_test.go","Functions":[{"Uniquefunname":"func Test_GetJulianCentury(t *testing.T)","Funname":"Test_GetJulianCentury","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetJulianThousandYears(t *testing.T)","Funname":"Test_GetJulianThousandYears","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetSolarMonthDays(t *testing.T)","Funname":"Test_GetSolarMonthDays","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetWeekday(t *testing.T)","Funname":"Test_GetWeekday","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_IsLeapYear(t *testing.T)","Funname":"Test_IsLeapYear","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_ToJulianDate(t *testing.T)","Funname":"Test_ToJulianDate","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_ToJulianDateHMS(t *testing.T)","Funname":"Test_ToJulianDateHMS","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetJulianCentury(t *testing.T)","Funname":"util.Test_GetJulianCentury","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetJulianThousandYears(t *testing.T)","Funname":"util.Test_GetJulianThousandYears","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetSolarMonthDays(t *testing.T)","Funname":"util.Test_GetSolarMonthDays","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_GetWeekday(t *testing.T)","Funname":"util.Test_GetWeekday","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_IsLeapYear(t *testing.T)","Funname":"util.Test_IsLeapYear","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_ToJulianDate(t *testing.T)","Funname":"util.Test_ToJulianDate","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_ToJulianDateHMS(t *testing.T)","Funname":"util.Test_ToJulianDateHMS","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"cgroup/cgroup.go","Functions":[{"Uniquefunname":"func (cg *Cgroup) AddController(name string) *Controller","Funname":"AddController","Returntype":"*Controller","Args":"name string"},{"Uniquefunname":"func (cg *Cgroup) AllExist() bool","Funname":"AllExist","Returntype":"bool","Args":""},{"Uniquefunname":"func (cg *Cgroup) AttachCurrentProcess() error","Funname":"AttachCurrentProcess","Returntype":"error","Args":""},{"Uniquefunname":"func (cg *Cgroup) AttachCurrentTask() error","Funname":"AttachCurrentTask","Returntype":"error","Args":""},{"Uniquefunname":"func (cg *Cgroup) AttachProcess(pid int) error","Funname":"AttachProcess","Returntype":"error","Args":"pid int"},{"Uniquefunname":"func (cg *Cgroup) AttachTask(tid int) error","Funname":"AttachTask","Returntype":"error","Args":"tid int"},{"Uniquefunname":"func (c *Controller) Cgroup() *Cgroup","Funname":"Cgroup","Returntype":"*Cgroup","Args":""},{"Uniquefunname":"func (cg *Cgroup) Create(ignoreOwnership bool) (err error)","Funname":"Create","Returntype":"(err error)","Args":"ignoreOwnership bool"},{"Uniquefunname":"func (cg *Cgroup) Delete(flags DeleteFlags) (err error)","Funname":"Delete","Returntype":"(err error)","Args":"flags DeleteFlags"},{"Uniquefunname":"func (cd *ControllerInfo) Enabled() bool","Funname":"Enabled","Returntype":"bool","Args":""},{"Uniquefunname":"func (c *Controller) Exists() bool","Funname":"Exists","Returntype":"bool","Args":""},{"Uniquefunname":"func GetAllControllers() ([]*ControllerInfo, error)","Funname":"GetAllControllers","Returntype":"([]*ControllerInfo, error)","Args":""},{"Uniquefunname":"func (cg *Cgroup) GetChildren(controller string) ([]string, error)","Funname":"GetChildren","Returntype":"([]string, error)","Args":"controller string"},{"Uniquefunname":"func (cg *Cgroup) GetController(name string) *Controller","Funname":"GetController","Returntype":"*Controller","Args":"name string"},{"Uniquefunname":"func GetControllers() []*MountTableItem","Funname":"GetControllers","Returntype":"[]*MountTableItem","Args":""},{"Uniquefunname":"func GetProcessControllerPath(pid int, controller string) (string, error)","Funname":"GetProcessControllerPath","Returntype":"(string, error)","Args":"pid int, controller string"},{"Uniquefunname":"func (cg *Cgroup) GetProcs(controller string) ([]int, error)","Funname":"GetProcs","Returntype":"([]int, error)","Args":"controller string"},{"Uniquefunname":"func GetProcs(name, controller string) ([]int, error)","Funname":"GetProcs","Returntype":"([]int, error)","Args":"name, controller string"},{"Uniquefunname":"func (c *Controller) GetStats(fields []string, args ...*uint64) (int, error)","Funname":"GetStats","Returntype":"(int, error)","Args":"fields []string, args ...*uint64"},{"Uniquefunname":"func (c *Controller) GetStatsAll() (map[string]uint64, error)","Funname":"GetStatsAll","Returntype":"(map[string]uint64, error)","Args":""},{"Uniquefunname":"func GetSubSysMountPoint(controller string) string","Funname":"GetSubSysMountPoint","Returntype":"string","Args":"controller string"},{"Uniquefunname":"func GetSubSysMountPoints(controller string) []string","Funname":"GetSubSysMountPoints","Returntype":"[]string","Args":"controller string"},{"Uniquefunname":"func (cg *Cgroup) GetTasks(controller string) ([]int, error)","Funname":"GetTasks","Returntype":"([]int, error)","Args":"controller string"},{"Uniquefunname":"func GetTasks(name, controller string) ([]int, error)","Funname":"GetTasks","Returntype":"([]int, error)","Args":"name, controller string"},{"Uniquefunname":"func (cg *Cgroup) GetUidGid() (int, int, int, int)","Funname":"GetUidGid","Returntype":"(int, int, int, int)","Args":""},{"Uniquefunname":"func (c *Controller) GetValueBool(name string) (bool, error)","Funname":"GetValueBool","Returntype":"(bool, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetValueInt64(name string) (int64, error)","Funname":"GetValueInt64","Returntype":"(int64, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetValueString(name string) (string, error)","Funname":"GetValueString","Returntype":"(string, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetValueUint64(name string) (uint64, error)","Funname":"GetValueUint64","Returntype":"(uint64, error)","Args":"name string"},{"Uniquefunname":"func (cd *ControllerInfo) Hierarchy() int","Funname":"Hierarchy","Returntype":"int","Args":""},{"Uniquefunname":"func Init() error","Funname":"Init","Returntype":"error","Args":""},{"Uniquefunname":"func (item *MountTableItem) MountPoints() []string","Funname":"MountPoints","Returntype":"[]string","Args":""},{"Uniquefunname":"func (c *Controller) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (cd *ControllerInfo) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (cg *Cgroup) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func (item *MountTableItem) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func NewCgroup(name string) *Cgroup","Funname":"NewCgroup","Returntype":"*Cgroup","Args":"name string"},{"Uniquefunname":"func (cg *Cgroup) NewChildGroup(name string) *Cgroup","Funname":"NewChildGroup","Returntype":"*Cgroup","Args":"name string"},{"Uniquefunname":"func (cg *Cgroup) NewChildrenGroups(controller string) ([]*Cgroup, error)","Funname":"NewChildrenGroups","Returntype":"([]*Cgroup, error)","Args":"controller string"},{"Uniquefunname":"func (cd *ControllerInfo) NumCgroups() int","Funname":"NumCgroups","Returntype":"int","Args":""},{"Uniquefunname":"func (cg *Cgroup) SetPermissions(controlDirPerm, controlFilePerm, tasksFilePerm os.FileMode)","Funname":"SetPermissions","Returntype":"","Args":"controlDirPerm, controlFilePerm, tasksFilePerm os.FileMode"},{"Uniquefunname":"func (cg *Cgroup) SetUidGid(tasksUid, tasksGid, controlUid, controlGid int)","Funname":"SetUidGid","Returntype":"","Args":"tasksUid, tasksGid, controlUid, controlGid int"},{"Uniquefunname":"func (c *Controller) SetValueBool(name string, value bool) error","Funname":"SetValueBool","Returntype":"error","Args":"name string, value bool"},{"Uniquefunname":"func (c *Controller) SetValueInt64(name string, value int64) error","Funname":"SetValueInt64","Returntype":"error","Args":"name string, value int64"},{"Uniquefunname":"func (c *Controller) SetValueString(name, value string) error","Funname":"SetValueString","Returntype":"error","Args":"name, value string"},{"Uniquefunname":"func (c *Controller) SetValueUint64(name string, value uint64) error","Funname":"SetValueUint64","Returntype":"error","Args":"name string, value uint64"},{"Uniquefunname":"func (item *MountTableItem) addDuplicateMount(path string)","Funname":"addDuplicateMount","Returntype":"","Args":"path string"},{"Uniquefunname":"func attachTaskProc(path string, tid int) error","Funname":"attachTaskProc","Returntype":"error","Args":"path string, tid int"},{"Uniquefunname":"func buildPath(name, controller string) string","Funname":"buildPath","Returntype":"string","Args":"name, controller string"},{"Uniquefunname":"func (cg *Cgroup) AddController(name string) *Controller","Funname":"cgroup.Cgroup.AddController","Returntype":"*Controller","Args":"name string"},{"Uniquefunname":"func (cg *Cgroup) AllExist() bool","Funname":"cgroup.Cgroup.AllExist","Returntype":"bool","Args":""},{"Uniquefunname":"func (cg *Cgroup) AttachCurrentProcess() error","Funname":"cgroup.Cgroup.AttachCurrentProcess","Returntype":"error","Args":""},{"Uniquefunname":"func (cg *Cgroup) AttachCurrentTask() error","Funname":"cgroup.Cgroup.AttachCurrentTask","Returntype":"error","Args":""},{"Uniquefunname":"func (cg *Cgroup) AttachProcess(pid int) error","Funname":"cgroup.Cgroup.AttachProcess","Returntype":"error","Args":"pid int"},{"Uniquefunname":"func (cg *Cgroup) AttachTask(tid int) error","Funname":"cgroup.Cgroup.AttachTask","Returntype":"error","Args":"tid int"},{"Uniquefunname":"func (cg *Cgroup) Create(ignoreOwnership bool) (err error)","Funname":"cgroup.Cgroup.Create","Returntype":"(err error)","Args":"ignoreOwnership bool"},{"Uniquefunname":"func (cg *Cgroup) Delete(flags DeleteFlags) (err error)","Funname":"cgroup.Cgroup.Delete","Returntype":"(err error)","Args":"flags DeleteFlags"},{"Uniquefunname":"func (cg *Cgroup) GetChildren(controller string) ([]string, error)","Funname":"cgroup.Cgroup.GetChildren","Returntype":"([]string, error)","Args":"controller string"},{"Uniquefunname":"func (cg *Cgroup) GetController(name string) *Controller","Funname":"cgroup.Cgroup.GetController","Returntype":"*Controller","Args":"name string"},{"Uniquefunname":"func (cg *Cgroup) GetProcs(controller string) ([]int, error)","Funname":"cgroup.Cgroup.GetProcs","Returntype":"([]int, error)","Args":"controller string"},{"Uniquefunname":"func (cg *Cgroup) GetTasks(controller string) ([]int, error)","Funname":"cgroup.Cgroup.GetTasks","Returntype":"([]int, error)","Args":"controller string"},{"Uniquefunname":"func (cg *Cgroup) GetUidGid() (int, int, int, int)","Funname":"cgroup.Cgroup.GetUidGid","Returntype":"(int, int, int, int)","Args":""},{"Uniquefunname":"func (cg *Cgroup) Name() string","Funname":"cgroup.Cgroup.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (cg *Cgroup) NewChildGroup(name string) *Cgroup","Funname":"cgroup.Cgroup.NewChildGroup","Returntype":"*Cgroup","Args":"name string"},{"Uniquefunname":"func (cg *Cgroup) NewChildrenGroups(controller string) ([]*Cgroup, error)","Funname":"cgroup.Cgroup.NewChildrenGroups","Returntype":"([]*Cgroup, error)","Args":"controller string"},{"Uniquefunname":"func (cg *Cgroup) SetPermissions(controlDirPerm, controlFilePerm, tasksFilePerm os.FileMode)","Funname":"cgroup.Cgroup.SetPermissions","Returntype":"","Args":"controlDirPerm, controlFilePerm, tasksFilePerm os.FileMode"},{"Uniquefunname":"func (cg *Cgroup) SetUidGid(tasksUid, tasksGid, controlUid, controlGid int)","Funname":"cgroup.Cgroup.SetUidGid","Returntype":"","Args":"tasksUid, tasksGid, controlUid, controlGid int"},{"Uniquefunname":"func (cg *Cgroup) findParent(controller string) (string, error)","Funname":"cgroup.Cgroup.findParent","Returntype":"(string, error)","Args":"controller string"},{"Uniquefunname":"func (cg *Cgroup) getFirstControllerName() string","Funname":"cgroup.Cgroup.getFirstControllerName","Returntype":"string","Args":""},{"Uniquefunname":"func (cg *Cgroup) getParentName() string","Funname":"cgroup.Cgroup.getParentName","Returntype":"string","Args":""},{"Uniquefunname":"func (cg *Cgroup) init()","Funname":"cgroup.Cgroup.init","Returntype":"","Args":""},{"Uniquefunname":"func (c *Controller) Cgroup() *Cgroup","Funname":"cgroup.Controller.Cgroup","Returntype":"*Cgroup","Args":""},{"Uniquefunname":"func (c *Controller) Exists() bool","Funname":"cgroup.Controller.Exists","Returntype":"bool","Args":""},{"Uniquefunname":"func (c *Controller) GetStats(fields []string, args ...*uint64) (int, error)","Funname":"cgroup.Controller.GetStats","Returntype":"(int, error)","Args":"fields []string, args ...*uint64"},{"Uniquefunname":"func (c *Controller) GetStatsAll() (map[string]uint64, error)","Funname":"cgroup.Controller.GetStatsAll","Returntype":"(map[string]uint64, error)","Args":""},{"Uniquefunname":"func (c *Controller) GetValueBool(name string) (bool, error)","Funname":"cgroup.Controller.GetValueBool","Returntype":"(bool, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetValueInt64(name string) (int64, error)","Funname":"cgroup.Controller.GetValueInt64","Returntype":"(int64, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetValueString(name string) (string, error)","Funname":"cgroup.Controller.GetValueString","Returntype":"(string, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) GetValueUint64(name string) (uint64, error)","Funname":"cgroup.Controller.GetValueUint64","Returntype":"(uint64, error)","Args":"name string"},{"Uniquefunname":"func (c *Controller) Name() string","Funname":"cgroup.Controller.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (c *Controller) SetValueBool(name string, value bool) error","Funname":"cgroup.Controller.SetValueBool","Returntype":"error","Args":"name string, value bool"},{"Uniquefunname":"func (c *Controller) SetValueInt64(name string, value int64) error","Funname":"cgroup.Controller.SetValueInt64","Returntype":"error","Args":"name string, value int64"},{"Uniquefunname":"func (c *Controller) SetValueString(name, value string) error","Funname":"cgroup.Controller.SetValueString","Returntype":"error","Args":"name, value string"},{"Uniquefunname":"func (c *Controller) SetValueUint64(name string, value uint64) error","Funname":"cgroup.Controller.SetValueUint64","Returntype":"error","Args":"name string, value uint64"},{"Uniquefunname":"func (c *Controller) exists() bool","Funname":"cgroup.Controller.exists","Returntype":"bool","Args":""},{"Uniquefunname":"func (c *Controller) getValueFile(name string) string","Funname":"cgroup.Controller.getValueFile","Returntype":"string","Args":"name string"},{"Uniquefunname":"func (cd *ControllerInfo) Enabled() bool","Funname":"cgroup.ControllerInfo.Enabled","Returntype":"bool","Args":""},{"Uniquefunname":"func (cd *ControllerInfo) Hierarchy() int","Funname":"cgroup.ControllerInfo.Hierarchy","Returntype":"int","Args":""},{"Uniquefunname":"func (cd *ControllerInfo) Name() string","Funname":"cgroup.ControllerInfo.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (cd *ControllerInfo) NumCgroups() int","Funname":"cgroup.ControllerInfo.NumCgroups","Returntype":"int","Args":""},{"Uniquefunname":"func GetAllControllers() ([]*ControllerInfo, error)","Funname":"cgroup.GetAllControllers","Returntype":"([]*ControllerInfo, error)","Args":""},{"Uniquefunname":"func GetControllers() []*MountTableItem","Funname":"cgroup.GetControllers","Returntype":"[]*MountTableItem","Args":""},{"Uniquefunname":"func GetProcessControllerPath(pid int, controller string) (string, error)","Funname":"cgroup.GetProcessControllerPath","Returntype":"(string, error)","Args":"pid int, controller string"},{"Uniquefunname":"func GetProcs(name, controller string) ([]int, error)","Funname":"cgroup.GetProcs","Returntype":"([]int, error)","Args":"name, controller string"},{"Uniquefunname":"func GetSubSysMountPoint(controller string) string","Funname":"cgroup.GetSubSysMountPoint","Returntype":"string","Args":"controller string"},{"Uniquefunname":"func GetSubSysMountPoints(controller string) []string","Funname":"cgroup.GetSubSysMountPoints","Returntype":"[]string","Args":"controller string"},{"Uniquefunname":"func GetTasks(name, controller string) ([]int, error)","Funname":"cgroup.GetTasks","Returntype":"([]int, error)","Args":"name, controller string"},{"Uniquefunname":"func Init() error","Funname":"cgroup.Init","Returntype":"error","Args":""},{"Uniquefunname":"func (me *MountEntry) hasOpt(opt string) string","Funname":"cgroup.MountEntry.hasOpt","Returntype":"string","Args":"opt string"},{"Uniquefunname":"func (item *MountTableItem) MountPoints() []string","Funname":"cgroup.MountTableItem.MountPoints","Returntype":"[]string","Args":""},{"Uniquefunname":"func (item *MountTableItem) Name() string","Funname":"cgroup.MountTableItem.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (item *MountTableItem) addDuplicateMount(path string)","Funname":"cgroup.MountTableItem.addDuplicateMount","Returntype":"","Args":"path string"},{"Uniquefunname":"func NewCgroup(name string) *Cgroup","Funname":"cgroup.NewCgroup","Returntype":"*Cgroup","Args":"name string"},{"Uniquefunname":"func attachTaskProc(path string, tid int) error","Funname":"cgroup.attachTaskProc","Returntype":"error","Args":"path string, tid int"},{"Uniquefunname":"func buildPath(name, controller string) string","Funname":"cgroup.buildPath","Returntype":"string","Args":"name, controller string"},{"Uniquefunname":"func cgroup.chmodFile(filename string, info os.FileInfo, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool)error","Funname":"cgroup.chmodFile","Returntype":"error","Args":"filename string, info os.FileInfo, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool"},{"Uniquefunname":"func chmodPath(path string, info os.FileInfo, mode os.FileMode, ownerIsUmask bool) error","Funname":"cgroup.chmodPath","Returntype":"error","Args":"path string, info os.FileInfo, mode os.FileMode, ownerIsUmask bool"},{"Uniquefunname":"func cgroup.chmodRecursiveController(path string, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool, ignoreList []string)error","Funname":"cgroup.chmodRecursiveController","Returntype":"error","Args":"path string, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool, ignoreList []string"},{"Uniquefunname":"func chown(filename string, owner, group int) error","Funname":"cgroup.chown","Returntype":"error","Args":"filename string, owner, group int"},{"Uniquefunname":"func chownRecursive(path string, owner, group int) error","Funname":"cgroup.chownRecursive","Returntype":"error","Args":"path string, owner, group int"},{"Uniquefunname":"func createControlGroup(path string) error","Funname":"cgroup.createControlGroup","Returntype":"error","Args":"path string"},{"Uniquefunname":"func cgroup.deleteCgroupController(cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags)(err error)","Funname":"cgroup.deleteCgroupController","Returntype":"(err error)","Args":"cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags"},{"Uniquefunname":"func cgroup.deleteCgroupControllerRecursive(cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags, deleteRoot bool)error","Funname":"cgroup.deleteCgroupControllerRecursive","Returntype":"error","Args":"cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags, deleteRoot bool"},{"Uniquefunname":"func getIntegers(name, controller, basename string) ([]int, error)","Funname":"cgroup.getIntegers","Returntype":"([]int, error)","Args":"name, controller, basename string"},{"Uniquefunname":"func getMountEntry(rd io.Reader) (*MountEntry, error)","Funname":"cgroup.getMountEntry","Returntype":"(*MountEntry, error)","Args":"rd io.Reader"},{"Uniquefunname":"func moveTaskFiles(inputTasksF, outputTasksF *os.File) error","Funname":"cgroup.moveTaskFiles","Returntype":"error","Args":"inputTasksF, outputTasksF *os.File"},{"Uniquefunname":"func panicIfNotInitialized()","Funname":"cgroup.panicIfNotInitialized","Returntype":"","Args":""},{"Uniquefunname":"func testMountedFs() bool","Funname":"cgroup.testMountedFs","Returntype":"bool","Args":""},{"Uniquefunname":"func testSubSysMounted(name string) bool","Funname":"cgroup.testSubSysMounted","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func chmodFile(filename string, info os.FileInfo, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool)error","Funname":"chmodFile","Returntype":"error","Args":"filename string, info os.FileInfo, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool"},{"Uniquefunname":"func chmodPath(path string, info os.FileInfo, mode os.FileMode, ownerIsUmask bool) error","Funname":"chmodPath","Returntype":"error","Args":"path string, info os.FileInfo, mode os.FileMode, ownerIsUmask bool"},{"Uniquefunname":"func chmodRecursiveController(path string, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool, ignoreList []string)error","Funname":"chmodRecursiveController","Returntype":"error","Args":"path string, dirMode os.FileMode, dirModeChange bool, fileMode os.FileMode, fileModeChange bool, ownerIsUmask bool, ignoreList []string"},{"Uniquefunname":"func chown(filename string, owner, group int) error","Funname":"chown","Returntype":"error","Args":"filename string, owner, group int"},{"Uniquefunname":"func chownRecursive(path string, owner, group int) error","Funname":"chownRecursive","Returntype":"error","Args":"path string, owner, group int"},{"Uniquefunname":"func createControlGroup(path string) error","Funname":"createControlGroup","Returntype":"error","Args":"path string"},{"Uniquefunname":"func deleteCgroupController(cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags)(err error)","Funname":"deleteCgroupController","Returntype":"(err error)","Args":"cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags"},{"Uniquefunname":"func deleteCgroupControllerRecursive(cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags, deleteRoot bool)error","Funname":"deleteCgroupControllerRecursive","Returntype":"error","Args":"cgroupName, controller string, targetTasksF *os.File, flags DeleteFlags, deleteRoot bool"},{"Uniquefunname":"func (c *Controller) exists() bool","Funname":"exists","Returntype":"bool","Args":""},{"Uniquefunname":"func (cg *Cgroup) findParent(controller string) (string, error)","Funname":"findParent","Returntype":"(string, error)","Args":"controller string"},{"Uniquefunname":"func (cg *Cgroup) getFirstControllerName() string","Funname":"getFirstControllerName","Returntype":"string","Args":""},{"Uniquefunname":"func getIntegers(name, controller, basename string) ([]int, error)","Funname":"getIntegers","Returntype":"([]int, error)","Args":"name, controller, basename string"},{"Uniquefunname":"func getMountEntry(rd io.Reader) (*MountEntry, error)","Funname":"getMountEntry","Returntype":"(*MountEntry, error)","Args":"rd io.Reader"},{"Uniquefunname":"func (cg *Cgroup) getParentName() string","Funname":"getParentName","Returntype":"string","Args":""},{"Uniquefunname":"func (c *Controller) getValueFile(name string) string","Funname":"getValueFile","Returntype":"string","Args":"name string"},{"Uniquefunname":"func (me *MountEntry) hasOpt(opt string) string","Funname":"hasOpt","Returntype":"string","Args":"opt string"},{"Uniquefunname":"func (cg *Cgroup) init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func moveTaskFiles(inputTasksF, outputTasksF *os.File) error","Funname":"moveTaskFiles","Returntype":"error","Args":"inputTasksF, outputTasksF *os.File"},{"Uniquefunname":"func panicIfNotInitialized()","Funname":"panicIfNotInitialized","Returntype":"","Args":""},{"Uniquefunname":"func testMountedFs() bool","Funname":"testMountedFs","Returntype":"bool","Args":""},{"Uniquefunname":"func testSubSysMounted(name string) bool","Funname":"testSubSysMounted","Returntype":"bool","Args":"name string"}],"Records":[{"Name":"const:cgroup","Fields":["cgroup.Blkio","cgroup.Cpu","cgroup.Cpuacct","cgroup.Cpuset","cgroup.DeleteFlagEmptyOnly","cgroup.DeleteFlagIgnoreMigration","cgroup.DeleteFlagRecursive","cgroup.Devices","cgroup.Freezer","cgroup.Memory","cgroup.NetCLS","cgroup.NetPrio","cgroup.PerfEvent","cgroup.Pids","cgroup.noPerms","cgroup.noUidGid"]},{"Name":"struct:cgroup.Cgroup","Fields":["cgroup.Cgroup.controlDirPerm os.FileMode","cgroup.Cgroup.controlFilePerm os.FileMode","cgroup.Cgroup.controlGid int","cgroup.Cgroup.controlUid int","cgroup.Cgroup.controllers []*Controller","cgroup.Cgroup.name string","cgroup.Cgroup.tasksFilePerm os.FileMode","cgroup.Cgroup.tasksGid int","cgroup.Cgroup.tasksUid int"]},{"Name":"struct:cgroup.Controller","Fields":["cgroup.Controller.cgroup *Cgroup","cgroup.Controller.name string"]},{"Name":"struct:cgroup.ControllerInfo","Fields":["cgroup.ControllerInfo.enabled bool","cgroup.ControllerInfo.hierarchy int","cgroup.ControllerInfo.name string","cgroup.ControllerInfo.numCgroups int"]},{"Name":"var:cgroup","Fields":["cgroup.ErrCgroupNotMounted","cgroup.ErrInvalid","cgroup.ErrNonEmpty","cgroup.ErrSubSysNotMounted","cgroup.initialized","cgroup.logger","cgroup.mountTable"]},{"Name":"struct:cgroup.MountEntry","Fields":["cgroup.MountEntry.dir string","cgroup.MountEntry.freq int","cgroup.MountEntry.fsname string","cgroup.MountEntry.opts string","cgroup.MountEntry.passno int","cgroup.MountEntry.type0 string"]},{"Name":"struct:cgroup.MountTableItem","Fields":["cgroup.MountTableItem.mountPoints []string","cgroup.MountTableItem.name string"]}]} {"Filepath":"dbusutil/dbusutil.go","Functions":[{"Uniquefunname":"func (pa *PropertyAccess) GetPID() (uint32, error)","Funname":"GetPID","Returntype":"(uint32, error)","Args":""},{"Uniquefunname":"func (pa *PropertyAccess) GetUID() (uint32, error)","Funname":"GetUID","Returntype":"(uint32, error)","Args":""},{"Uniquefunname":"func GetValueVariant(propRead *PropertyRead, signature dbus.Signature)(dbus.Variant, *dbus.Error)","Funname":"GetValueVariant","Returntype":"(dbus.Variant, *dbus.Error)","Args":"propRead *PropertyRead, signature dbus.Signature"},{"Uniquefunname":"func (p *fieldProp) SetValue(propWrite *PropertyWrite) (changed bool, err *dbus.Error)","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"propWrite *PropertyWrite"},{"Uniquefunname":"func (a accessType) String() string","Funname":"String","Returntype":"string","Args":""},{"Uniquefunname":"func (e emitType) String() string","Funname":"String","Returntype":"string","Args":""},{"Uniquefunname":"func (p *fieldProp) connectChanged(cb PropertyChangedCallback)","Funname":"connectChanged","Returntype":"","Args":"cb PropertyChangedCallback"},{"Uniquefunname":"func (pa *PropertyAccess) GetPID() (uint32, error)","Funname":"dbusutil.PropertyAccess.GetPID","Returntype":"(uint32, error)","Args":""},{"Uniquefunname":"func (pa *PropertyAccess) GetUID() (uint32, error)","Funname":"dbusutil.PropertyAccess.GetUID","Returntype":"(uint32, error)","Args":""},{"Uniquefunname":"func (a accessType) String() string","Funname":"dbusutil.accessType.String","Returntype":"string","Args":""},{"Uniquefunname":"func dbusutil.emitPropertiesChanged(conn *dbus.Conn, path dbus.ObjectPath, interfaceName string, propName string, value interface{}, emit emitType)(err error)","Funname":"dbusutil.emitPropertiesChanged","Returntype":"(err error)","Args":"conn *dbus.Conn, path dbus.ObjectPath, interfaceName string, propName string, value interface{}, emit emitType"},{"Uniquefunname":"func (e emitType) String() string","Funname":"dbusutil.emitType.String","Returntype":"string","Args":""},{"Uniquefunname":"func dbusutil.fieldProp.GetValueVariant(propRead *PropertyRead, signature dbus.Signature)(dbus.Variant, *dbus.Error)","Funname":"dbusutil.fieldProp.GetValueVariant","Returntype":"(dbus.Variant, *dbus.Error)","Args":"propRead *PropertyRead, signature dbus.Signature"},{"Uniquefunname":"func (p *fieldProp) SetValue(propWrite *PropertyWrite) (changed bool, err *dbus.Error)","Funname":"dbusutil.fieldProp.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"propWrite *PropertyWrite"},{"Uniquefunname":"func (p *fieldProp) connectChanged(cb PropertyChangedCallback)","Funname":"dbusutil.fieldProp.connectChanged","Returntype":"","Args":"cb PropertyChangedCallback"},{"Uniquefunname":"func (p *fieldProp) getReadCallback() PropertyReadCallback","Funname":"dbusutil.fieldProp.getReadCallback","Returntype":"PropertyReadCallback","Args":""},{"Uniquefunname":"func (p *fieldProp) getValue(propRead *PropertyRead) (value interface","Funname":"dbusutil.fieldProp.getValue","Returntype":"(value interface{}, err *dbus.Error)","Args":"propRead *PropertyRead"},{"Uniquefunname":"func (p *fieldProp) getWriteCallback() PropertyWriteCallback","Funname":"dbusutil.fieldProp.getWriteCallback","Returntype":"PropertyWriteCallback","Args":""},{"Uniquefunname":"func (p *fieldProp) notifyChanged(change *PropertyChanged)","Funname":"dbusutil.fieldProp.notifyChanged","Returntype":"","Args":"change *PropertyChanged"},{"Uniquefunname":"func (p *fieldProp) setReadCallback(cb PropertyReadCallback)","Funname":"dbusutil.fieldProp.setReadCallback","Returntype":"","Args":"cb PropertyReadCallback"},{"Uniquefunname":"func (p *fieldProp) setWriteCallback(cb PropertyWriteCallback)","Funname":"dbusutil.fieldProp.setWriteCallback","Returntype":"","Args":"cb PropertyWriteCallback"},{"Uniquefunname":"func getCorePropsMu(structValue reflect.Value) *sync.RWMutex","Funname":"dbusutil.getCorePropsMu","Returntype":"*sync.RWMutex","Args":"structValue reflect.Value"},{"Uniquefunname":"func dbusutil.getFieldPropMap(impl *implementer, implStatic *implementerStatic, structValue reflect.Value, s *Service, path dbus.ObjectPath)map[string]*fieldProp","Funname":"dbusutil.getFieldPropMap","Returntype":"map[string]*fieldProp","Args":"impl *implementer, implStatic *implementerStatic, structValue reflect.Value, s *Service, path dbus.ObjectPath"},{"Uniquefunname":"func dbusutil.getFieldPropStaticMap(structType reflect.Type, structValue reflect.Value)map[string]*fieldPropStatic","Funname":"dbusutil.getFieldPropStaticMap","Returntype":"map[string]*fieldPropStatic","Args":"structType reflect.Type, structValue reflect.Value"},{"Uniquefunname":"func getMethodDetailMap(structType reflect.Type) map[string]methodDetail","Funname":"dbusutil.getMethodDetailMap","Returntype":"map[string]methodDetail","Args":"structType reflect.Type"},{"Uniquefunname":"func getMethods(v interface","Funname":"dbusutil.getMethods","Returntype":"[]introspect.Method","Args":"v interface{}, methodDetailMap map[string]methodDetail"},{"Uniquefunname":"func getPropsIntrospection(props map[string]*fieldPropStatic) []introspect.Property","Funname":"dbusutil.getPropsIntrospection","Returntype":"[]introspect.Property","Args":"props map[string]*fieldPropStatic"},{"Uniquefunname":"func getSignals(structType reflect.Type) []introspect.Signal","Funname":"dbusutil.getSignals","Returntype":"[]introspect.Signal","Args":"structType reflect.Type"},{"Uniquefunname":"func getStructValue(m interface","Funname":"dbusutil.getStructValue","Returntype":"(reflect.Value, bool)","Args":"m interface{}"},{"Uniquefunname":"func init()","Funname":"dbusutil.init","Returntype":"","Args":""},{"Uniquefunname":"func (md methodDetail) getInArgName(index int, type0 reflect.Type, methodName string) string","Funname":"dbusutil.methodDetail.getInArgName","Returntype":"string","Args":"index int, type0 reflect.Type, methodName string"},{"Uniquefunname":"func (md methodDetail) getOutArgName(index int, type0 reflect.Type, methodName string) string","Funname":"dbusutil.methodDetail.getOutArgName","Returntype":"string","Args":"index int, type0 reflect.Type, methodName string"},{"Uniquefunname":"func dbusutil.newFieldPropStatic(field reflect.StructField, fieldValue reflect.Value, tag string)*fieldPropStatic","Funname":"dbusutil.newFieldPropStatic","Returntype":"*fieldPropStatic","Args":"field reflect.StructField, fieldValue reflect.Value, tag string"},{"Uniquefunname":"func dbusutil.newPropertyChanged(path dbus.ObjectPath, interfaceName, name string, value interface{})*PropertyChanged","Funname":"dbusutil.newPropertyChanged","Returntype":"*PropertyChanged","Args":"path dbus.ObjectPath, interfaceName, name string, value interface{}"},{"Uniquefunname":"func dbusutil.newPropertyRead(sender dbus.Sender, so *ServerObject, interfaceName, name string)*PropertyRead","Funname":"dbusutil.newPropertyRead","Returntype":"*PropertyRead","Args":"sender dbus.Sender, so *ServerObject, interfaceName, name string"},{"Uniquefunname":"func dbusutil.newPropertyWrite(sender dbus.Sender, so *ServerObject, interfaceName, name string, value interface{})*PropertyWrite","Funname":"dbusutil.newPropertyWrite","Returntype":"*PropertyWrite","Args":"sender dbus.Sender, so *ServerObject, interfaceName, name string, value interface{}"},{"Uniquefunname":"func parsePropTag(tag string) (accessType, emitType)","Funname":"dbusutil.parsePropTag","Returntype":"(accessType, emitType)","Args":"tag string"},{"Uniquefunname":"func splitArg(str string) (result []string)","Funname":"dbusutil.splitArg","Returntype":"(result []string)","Args":"str string"},{"Uniquefunname":"func toProperty(value reflect.Value) (Property, fieldPropValueType)","Funname":"dbusutil.toProperty","Returntype":"(Property, fieldPropValueType)","Args":"value reflect.Value"},{"Uniquefunname":"func valueFromBus(src interface","Funname":"dbusutil.valueFromBus","Returntype":"(reflect.Value, error)","Args":"src interface{}, valueRT reflect.Type"},{"Uniquefunname":"func emitPropertiesChanged(conn *dbus.Conn, path dbus.ObjectPath, interfaceName string, propName string, value interface{}, emit emitType)(err error)","Funname":"emitPropertiesChanged","Returntype":"(err error)","Args":"conn *dbus.Conn, path dbus.ObjectPath, interfaceName string, propName string, value interface{}, emit emitType"},{"Uniquefunname":"func getCorePropsMu(structValue reflect.Value) *sync.RWMutex","Funname":"getCorePropsMu","Returntype":"*sync.RWMutex","Args":"structValue reflect.Value"},{"Uniquefunname":"func getFieldPropMap(impl *implementer, implStatic *implementerStatic, structValue reflect.Value, s *Service, path dbus.ObjectPath)map[string]*fieldProp","Funname":"getFieldPropMap","Returntype":"map[string]*fieldProp","Args":"impl *implementer, implStatic *implementerStatic, structValue reflect.Value, s *Service, path dbus.ObjectPath"},{"Uniquefunname":"func getFieldPropStaticMap(structType reflect.Type, structValue reflect.Value)map[string]*fieldPropStatic","Funname":"getFieldPropStaticMap","Returntype":"map[string]*fieldPropStatic","Args":"structType reflect.Type, structValue reflect.Value"},{"Uniquefunname":"func (md methodDetail) getInArgName(index int, type0 reflect.Type, methodName string) string","Funname":"getInArgName","Returntype":"string","Args":"index int, type0 reflect.Type, methodName string"},{"Uniquefunname":"func getMethodDetailMap(structType reflect.Type) map[string]methodDetail","Funname":"getMethodDetailMap","Returntype":"map[string]methodDetail","Args":"structType reflect.Type"},{"Uniquefunname":"func getMethods(v interface","Funname":"getMethods","Returntype":"[]introspect.Method","Args":"v interface{}, methodDetailMap map[string]methodDetail"},{"Uniquefunname":"func (md methodDetail) getOutArgName(index int, type0 reflect.Type, methodName string) string","Funname":"getOutArgName","Returntype":"string","Args":"index int, type0 reflect.Type, methodName string"},{"Uniquefunname":"func getPropsIntrospection(props map[string]*fieldPropStatic) []introspect.Property","Funname":"getPropsIntrospection","Returntype":"[]introspect.Property","Args":"props map[string]*fieldPropStatic"},{"Uniquefunname":"func (p *fieldProp) getReadCallback() PropertyReadCallback","Funname":"getReadCallback","Returntype":"PropertyReadCallback","Args":""},{"Uniquefunname":"func getSignals(structType reflect.Type) []introspect.Signal","Funname":"getSignals","Returntype":"[]introspect.Signal","Args":"structType reflect.Type"},{"Uniquefunname":"func getStructValue(m interface","Funname":"getStructValue","Returntype":"(reflect.Value, bool)","Args":"m interface{}"},{"Uniquefunname":"func (p *fieldProp) getValue(propRead *PropertyRead) (value interface","Funname":"getValue","Returntype":"(value interface{}, err *dbus.Error)","Args":"propRead *PropertyRead"},{"Uniquefunname":"func (p *fieldProp) getWriteCallback() PropertyWriteCallback","Funname":"getWriteCallback","Returntype":"PropertyWriteCallback","Args":""},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func newFieldPropStatic(field reflect.StructField, fieldValue reflect.Value, tag string)*fieldPropStatic","Funname":"newFieldPropStatic","Returntype":"*fieldPropStatic","Args":"field reflect.StructField, fieldValue reflect.Value, tag string"},{"Uniquefunname":"func newPropertyChanged(path dbus.ObjectPath, interfaceName, name string, value interface{})*PropertyChanged","Funname":"newPropertyChanged","Returntype":"*PropertyChanged","Args":"path dbus.ObjectPath, interfaceName, name string, value interface{}"},{"Uniquefunname":"func newPropertyRead(sender dbus.Sender, so *ServerObject, interfaceName, name string)*PropertyRead","Funname":"newPropertyRead","Returntype":"*PropertyRead","Args":"sender dbus.Sender, so *ServerObject, interfaceName, name string"},{"Uniquefunname":"func newPropertyWrite(sender dbus.Sender, so *ServerObject, interfaceName, name string, value interface{})*PropertyWrite","Funname":"newPropertyWrite","Returntype":"*PropertyWrite","Args":"sender dbus.Sender, so *ServerObject, interfaceName, name string, value interface{}"},{"Uniquefunname":"func (p *fieldProp) notifyChanged(change *PropertyChanged)","Funname":"notifyChanged","Returntype":"","Args":"change *PropertyChanged"},{"Uniquefunname":"func parsePropTag(tag string) (accessType, emitType)","Funname":"parsePropTag","Returntype":"(accessType, emitType)","Args":"tag string"},{"Uniquefunname":"func (p *fieldProp) setReadCallback(cb PropertyReadCallback)","Funname":"setReadCallback","Returntype":"","Args":"cb PropertyReadCallback"},{"Uniquefunname":"func (p *fieldProp) setWriteCallback(cb PropertyWriteCallback)","Funname":"setWriteCallback","Returntype":"","Args":"cb PropertyWriteCallback"},{"Uniquefunname":"func splitArg(str string) (result []string)","Funname":"splitArg","Returntype":"(result []string)","Args":"str string"},{"Uniquefunname":"func toProperty(value reflect.Value) (Property, fieldPropValueType)","Funname":"toProperty","Returntype":"(Property, fieldPropValueType)","Args":"value reflect.Value"},{"Uniquefunname":"func valueFromBus(src interface","Funname":"valueFromBus","Returntype":"(reflect.Value, error)","Args":"src interface{}, valueRT reflect.Type"}],"Records":[{"Name":"interface","Fields":["dbusutil.Property"]},{"Name":"struct:dbusutil.PropertyAccess","Fields":["dbusutil.PropertyAccess.Sender dbus.Sender","dbusutil.PropertyAccess.service *Service"]},{"Name":"struct:dbusutil.PropertyChanged","Fields":["dbusutil.PropertyChanged.Value interface{}"]},{"Name":"struct:dbusutil.PropertyInfo","Fields":["dbusutil.PropertyInfo.Interface string","dbusutil.PropertyInfo.Name string","dbusutil.PropertyInfo.Path dbus.ObjectPath"]},{"Name":"struct:dbusutil.PropertyWrite","Fields":["dbusutil.PropertyWrite.Value interface{}"]},{"Name":"const:dbusutil","Fields":["dbusutil.accessRead","dbusutil.accessReadWrite","dbusutil.accessWrite","dbusutil.emitFalse","dbusutil.emitInvalidates","dbusutil.emitTrue","dbusutil.fieldPropValueImplProp","dbusutil.fieldPropValueNotProp","dbusutil.fieldPropValuePtrImplProp","dbusutil.orgFreedesktopDBus","dbusutil.propsMuField"]},{"Name":"struct:dbusutil.fieldProp","Fields":["dbusutil.fieldProp.cbMu sync.Mutex","dbusutil.fieldProp.changedCbs []PropertyChangedCallback","dbusutil.fieldProp.rValue reflect.Value","dbusutil.fieldProp.readCb PropertyReadCallback","dbusutil.fieldProp.valueMu *sync.RWMutex","dbusutil.fieldProp.writeCb PropertyWriteCallback"]},{"Name":"struct:dbusutil.fieldPropStatic","Fields":["dbusutil.fieldPropStatic.access accessType","dbusutil.fieldPropStatic.emit emitType","dbusutil.fieldPropStatic.hasStruct bool","dbusutil.fieldPropStatic.name string","dbusutil.fieldPropStatic.rType reflect.Type","dbusutil.fieldPropStatic.signature dbus.Signature","dbusutil.fieldPropStatic.valueType fieldPropValueType"]},{"Name":"var:dbusutil","Fields":["dbusutil.logger"]},{"Name":"struct:dbusutil.methodDetail","Fields":["dbusutil.methodDetail.In []string","dbusutil.methodDetail.Out []string"]}]} {"Filepath":"dbusutil/err.go","Functions":[{"Uniquefunname":"func MakeError(v Implementer, name string, args ...interface","Funname":"MakeError","Returntype":"*dbus.Error","Args":"v Implementer, name string, args ...interface{}"},{"Uniquefunname":"func MakeErrorJSON(v Implementer, name string, detail interface","Funname":"MakeErrorJSON","Returntype":"*dbus.Error","Args":"v Implementer, name string, detail interface{}"},{"Uniquefunname":"func MakeErrorf(v Implementer, name, format string, args ...interface","Funname":"MakeErrorf","Returntype":"*dbus.Error","Args":"v Implementer, name, format string, args ...interface{}"},{"Uniquefunname":"func ToError(err error) *dbus.Error","Funname":"ToError","Returntype":"*dbus.Error","Args":"err error"},{"Uniquefunname":"func MakeError(v Implementer, name string, args ...interface","Funname":"dbusutil.MakeError","Returntype":"*dbus.Error","Args":"v Implementer, name string, args ...interface{}"},{"Uniquefunname":"func MakeErrorJSON(v Implementer, name string, detail interface","Funname":"dbusutil.MakeErrorJSON","Returntype":"*dbus.Error","Args":"v Implementer, name string, detail interface{}"},{"Uniquefunname":"func MakeErrorf(v Implementer, name, format string, args ...interface","Funname":"dbusutil.MakeErrorf","Returntype":"*dbus.Error","Args":"v Implementer, name, format string, args ...interface{}"},{"Uniquefunname":"func ToError(err error) *dbus.Error","Funname":"dbusutil.ToError","Returntype":"*dbus.Error","Args":"err error"}],"Records":[{"Name":"interface","Fields":["dbusutil.DBusError"]}]} {"Filepath":"dbusutil/err_test.go","Functions":[{"Uniquefunname":"func (err namedError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err unnamedError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (*impl1) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (err namedError) Name() string","Funname":"Name","Returntype":"string","Args":""},{"Uniquefunname":"func TestMakeError(t *testing.T)","Funname":"TestMakeError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMakeErrorJSON(t *testing.T)","Funname":"TestMakeErrorJSON","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMakeErrorf(t *testing.T)","Funname":"TestMakeErrorf","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestToError(t *testing.T)","Funname":"TestToError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMakeError(t *testing.T)","Funname":"dbusutil.TestMakeError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMakeErrorJSON(t *testing.T)","Funname":"dbusutil.TestMakeErrorJSON","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMakeErrorf(t *testing.T)","Funname":"dbusutil.TestMakeErrorf","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestToError(t *testing.T)","Funname":"dbusutil.TestToError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*impl1) GetInterfaceName() string","Funname":"dbusutil.impl1.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (err namedError) Error() string","Funname":"dbusutil.namedError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err namedError) Name() string","Funname":"dbusutil.namedError.Name","Returntype":"string","Args":""},{"Uniquefunname":"func (err unnamedError) Error() string","Funname":"dbusutil.unnamedError.Error","Returntype":"string","Args":""}],"Records":null} {"Filepath":"dbusutil/implementer_static.go","Functions":[{"Uniquefunname":"func (is *implementerStatic) checkProperty(propName string) error","Funname":"checkProperty","Returntype":"error","Args":"propName string"},{"Uniquefunname":"func (is *implementerStatic) checkPropertyValue(propName string, value interface","Funname":"checkPropertyValue","Returntype":"error","Args":"propName string, value interface{}"},{"Uniquefunname":"func (is *implementerStatic) checkProperty(propName string) error","Funname":"dbusutil.implementerStatic.checkProperty","Returntype":"error","Args":"propName string"},{"Uniquefunname":"func (is *implementerStatic) checkPropertyValue(propName string, value interface","Funname":"dbusutil.implementerStatic.checkPropertyValue","Returntype":"error","Args":"propName string, value interface{}"},{"Uniquefunname":"func newImplementerStatic(impl Implementer, structValue reflect.Value) *implementerStatic","Funname":"dbusutil.newImplementerStatic","Returntype":"*implementerStatic","Args":"impl Implementer, structValue reflect.Value"},{"Uniquefunname":"func newImplementerStatic(impl Implementer, structValue reflect.Value) *implementerStatic","Funname":"newImplementerStatic","Returntype":"*implementerStatic","Args":"impl Implementer, structValue reflect.Value"}],"Records":[{"Name":"struct:dbusutil.implementerStatic","Fields":["dbusutil.implementerStatic.introspectInterface introspect.Interface","dbusutil.implementerStatic.props map[string]*fieldPropStatic"]}]} {"Filepath":"dbusutil/implementor.go","Functions":[{"Uniquefunname":"func (impl *implementer) connectChanged(propertyName string, cb PropertyChangedCallback) error","Funname":"connectChanged","Returntype":"error","Args":"propertyName string, cb PropertyChangedCallback"},{"Uniquefunname":"func getImplementerPointer(impl Implementer) unsafe.Pointer","Funname":"dbusutil.getImplementerPointer","Returntype":"unsafe.Pointer","Args":"impl Implementer"},{"Uniquefunname":"func (impl *implementer) connectChanged(propertyName string, cb PropertyChangedCallback) error","Funname":"dbusutil.implementer.connectChanged","Returntype":"error","Args":"propertyName string, cb PropertyChangedCallback"},{"Uniquefunname":"func (impl *implementer) delayEmitPropChanged()","Funname":"dbusutil.implementer.delayEmitPropChanged","Returntype":"","Args":""},{"Uniquefunname":"func dbusutil.implementer.emitPropChanged(s *Service, path dbus.ObjectPath, propName string, value interface{})(err error)","Funname":"dbusutil.implementer.emitPropChanged","Returntype":"(err error)","Args":"s *Service, path dbus.ObjectPath, propName string, value interface{}"},{"Uniquefunname":"func (impl *implementer) getInterfaceName() string","Funname":"dbusutil.implementer.getInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (impl *implementer) getStatic(s *Service) *implementerStatic","Funname":"dbusutil.implementer.getStatic","Returntype":"*implementerStatic","Args":"s *Service"},{"Uniquefunname":"func dbusutil.implementer.notifyChanged(s *Service, path dbus.ObjectPath, p *fieldProp, propStatic *fieldPropStatic, value interface{})","Funname":"dbusutil.implementer.notifyChanged","Returntype":"","Args":"s *Service, path dbus.ObjectPath, p *fieldProp, propStatic *fieldPropStatic, value interface{}"},{"Uniquefunname":"func (impl *implementer) setReadCallback(propertyName string, cb PropertyReadCallback) error","Funname":"dbusutil.implementer.setReadCallback","Returntype":"error","Args":"propertyName string, cb PropertyReadCallback"},{"Uniquefunname":"func (impl *implementer) setWriteCallback(propertyName string, cb PropertyWriteCallback) error","Funname":"dbusutil.implementer.setWriteCallback","Returntype":"error","Args":"propertyName string, cb PropertyWriteCallback"},{"Uniquefunname":"func dbusutil.implementer.stopDelayEmitPropChanged(s *Service, path dbus.ObjectPath)(err error)","Funname":"dbusutil.implementer.stopDelayEmitPropChanged","Returntype":"(err error)","Args":"s *Service, path dbus.ObjectPath"},{"Uniquefunname":"func dbusutil.newImplementer(core Implementer, service *Service, path dbus.ObjectPath)(*implementer, error)","Funname":"dbusutil.newImplementer","Returntype":"(*implementer, error)","Args":"core Implementer, service *Service, path dbus.ObjectPath"},{"Uniquefunname":"func (impl *implementer) delayEmitPropChanged()","Funname":"delayEmitPropChanged","Returntype":"","Args":""},{"Uniquefunname":"func emitPropChanged(s *Service, path dbus.ObjectPath, propName string, value interface{})(err error)","Funname":"emitPropChanged","Returntype":"(err error)","Args":"s *Service, path dbus.ObjectPath, propName string, value interface{}"},{"Uniquefunname":"func getImplementerPointer(impl Implementer) unsafe.Pointer","Funname":"getImplementerPointer","Returntype":"unsafe.Pointer","Args":"impl Implementer"},{"Uniquefunname":"func (impl *implementer) getInterfaceName() string","Funname":"getInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (impl *implementer) getStatic(s *Service) *implementerStatic","Funname":"getStatic","Returntype":"*implementerStatic","Args":"s *Service"},{"Uniquefunname":"func newImplementer(core Implementer, service *Service, path dbus.ObjectPath)(*implementer, error)","Funname":"newImplementer","Returntype":"(*implementer, error)","Args":"core Implementer, service *Service, path dbus.ObjectPath"},{"Uniquefunname":"func notifyChanged(s *Service, path dbus.ObjectPath, p *fieldProp, propStatic *fieldPropStatic, value interface{})","Funname":"notifyChanged","Returntype":"","Args":"s *Service, path dbus.ObjectPath, p *fieldProp, propStatic *fieldPropStatic, value interface{}"},{"Uniquefunname":"func (impl *implementer) setReadCallback(propertyName string, cb PropertyReadCallback) error","Funname":"setReadCallback","Returntype":"error","Args":"propertyName string, cb PropertyReadCallback"},{"Uniquefunname":"func (impl *implementer) setWriteCallback(propertyName string, cb PropertyWriteCallback) error","Funname":"setWriteCallback","Returntype":"error","Args":"propertyName string, cb PropertyWriteCallback"},{"Uniquefunname":"func stopDelayEmitPropChanged(s *Service, path dbus.ObjectPath)(err error)","Funname":"stopDelayEmitPropChanged","Returntype":"(err error)","Args":"s *Service, path dbus.ObjectPath"}],"Records":[{"Name":"interface","Fields":["dbusutil.Implementer"]},{"Name":"struct:dbusutil.implPropChanged","Fields":["dbusutil.implPropChanged.name string","dbusutil.implPropChanged.value interface{}"]},{"Name":"struct:dbusutil.implementer","Fields":["dbusutil.implementer.core Implementer","dbusutil.implementer.propChanges propChanges","dbusutil.implementer.props map[string]*fieldProp"]},{"Name":"struct:dbusutil.propChanges","Fields":["dbusutil.propChanges.delayMode bool","dbusutil.propChanges.items []implPropChanged","dbusutil.propChanges.modeMu sync.Mutex","dbusutil.propChanges.mu sync.Mutex"]}]} {"Filepath":"dbusutil/introspectable.go","Functions":[{"Uniquefunname":"func (so *ServerObject) getChildren() (children strv.Strv)","Funname":"dbusutil.ServerObject.getChildren","Returntype":"(children strv.Strv)","Args":""},{"Uniquefunname":"func (so *ServerObject) getInterfaces() []introspect.Interface","Funname":"dbusutil.ServerObject.getInterfaces","Returntype":"[]introspect.Interface","Args":""},{"Uniquefunname":"func (so *ServerObject) introspectableIntrospect() (string, *dbus.Error)","Funname":"dbusutil.ServerObject.introspectableIntrospect","Returntype":"(string, *dbus.Error)","Args":""},{"Uniquefunname":"func (so *ServerObject) getChildren() (children strv.Strv)","Funname":"getChildren","Returntype":"(children strv.Strv)","Args":""},{"Uniquefunname":"func (so *ServerObject) getInterfaces() []introspect.Interface","Funname":"getInterfaces","Returntype":"[]introspect.Interface","Args":""},{"Uniquefunname":"func (so *ServerObject) introspectableIntrospect() (string, *dbus.Error)","Funname":"introspectableIntrospect","Returntype":"(string, *dbus.Error)","Args":""}],"Records":[{"Name":"var:dbusutil","Fields":["dbusutil.peerIntrospectData"]}]} {"Filepath":"dbusutil/match_rule.go","Functions":[{"Uniquefunname":"func (mr MatchRule) AddTo(conn *dbus.Conn) error","Funname":"AddTo","Returntype":"error","Args":"conn *dbus.Conn"},{"Uniquefunname":"func (b *MatchRuleBuilder) Arg(idx int, value string) *MatchRuleBuilder","Funname":"Arg","Returntype":"*MatchRuleBuilder","Args":"idx int, value string"},{"Uniquefunname":"func (b *MatchRuleBuilder) ArgNamespace(idx int, namespace string) *MatchRuleBuilder","Funname":"ArgNamespace","Returntype":"*MatchRuleBuilder","Args":"idx int, namespace string"},{"Uniquefunname":"func (b *MatchRuleBuilder) ArgPath(idx int, path string) *MatchRuleBuilder","Funname":"ArgPath","Returntype":"*MatchRuleBuilder","Args":"idx int, path string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Build() MatchRule","Funname":"Build","Returntype":"MatchRule","Args":""},{"Uniquefunname":"func (b *MatchRuleBuilder) BuildStr() string","Funname":"BuildStr","Returntype":"string","Args":""},{"Uniquefunname":"func (b *MatchRuleBuilder) Destination(destination string) *MatchRuleBuilder","Funname":"Destination","Returntype":"*MatchRuleBuilder","Args":"destination string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Eavesdrop(eavesdrop bool) *MatchRuleBuilder","Funname":"Eavesdrop","Returntype":"*MatchRuleBuilder","Args":"eavesdrop bool"},{"Uniquefunname":"func (b *MatchRuleBuilder) ExtPropertiesChanged(path, interfaceName string) *MatchRuleBuilder","Funname":"ExtPropertiesChanged","Returntype":"*MatchRuleBuilder","Args":"path, interfaceName string"},{"Uniquefunname":"func (b *MatchRuleBuilder) ExtSignal(path, interfaceName, name string) *MatchRuleBuilder","Funname":"ExtSignal","Returntype":"*MatchRuleBuilder","Args":"path, interfaceName, name string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Interface(interface0 string) *MatchRuleBuilder","Funname":"Interface","Returntype":"*MatchRuleBuilder","Args":"interface0 string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Member(member string) *MatchRuleBuilder","Funname":"Member","Returntype":"*MatchRuleBuilder","Args":"member string"},{"Uniquefunname":"func NewMatchRuleBuilder() *MatchRuleBuilder","Funname":"NewMatchRuleBuilder","Returntype":"*MatchRuleBuilder","Args":""},{"Uniquefunname":"func (b *MatchRuleBuilder) Path(path string) *MatchRuleBuilder","Funname":"Path","Returntype":"*MatchRuleBuilder","Args":"path string"},{"Uniquefunname":"func (b *MatchRuleBuilder) PathNamespace(pathNamespace string) *MatchRuleBuilder","Funname":"PathNamespace","Returntype":"*MatchRuleBuilder","Args":"pathNamespace string"},{"Uniquefunname":"func (mr MatchRule) RemoveFrom(conn *dbus.Conn) error","Funname":"RemoveFrom","Returntype":"error","Args":"conn *dbus.Conn"},{"Uniquefunname":"func (b *MatchRuleBuilder) Sender(sender string) *MatchRuleBuilder","Funname":"Sender","Returntype":"*MatchRuleBuilder","Args":"sender string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Type(type0 string) *MatchRuleBuilder","Funname":"Type","Returntype":"*MatchRuleBuilder","Args":"type0 string"},{"Uniquefunname":"func (b *MatchRuleBuilder) addItem(k, v string)","Funname":"addItem","Returntype":"","Args":"k, v string"},{"Uniquefunname":"func (mr MatchRule) AddTo(conn *dbus.Conn) error","Funname":"dbusutil.MatchRule.AddTo","Returntype":"error","Args":"conn *dbus.Conn"},{"Uniquefunname":"func (mr MatchRule) RemoveFrom(conn *dbus.Conn) error","Funname":"dbusutil.MatchRule.RemoveFrom","Returntype":"error","Args":"conn *dbus.Conn"},{"Uniquefunname":"func (b *MatchRuleBuilder) Arg(idx int, value string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.Arg","Returntype":"*MatchRuleBuilder","Args":"idx int, value string"},{"Uniquefunname":"func (b *MatchRuleBuilder) ArgNamespace(idx int, namespace string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.ArgNamespace","Returntype":"*MatchRuleBuilder","Args":"idx int, namespace string"},{"Uniquefunname":"func (b *MatchRuleBuilder) ArgPath(idx int, path string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.ArgPath","Returntype":"*MatchRuleBuilder","Args":"idx int, path string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Build() MatchRule","Funname":"dbusutil.MatchRuleBuilder.Build","Returntype":"MatchRule","Args":""},{"Uniquefunname":"func (b *MatchRuleBuilder) BuildStr() string","Funname":"dbusutil.MatchRuleBuilder.BuildStr","Returntype":"string","Args":""},{"Uniquefunname":"func (b *MatchRuleBuilder) Destination(destination string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.Destination","Returntype":"*MatchRuleBuilder","Args":"destination string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Eavesdrop(eavesdrop bool) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.Eavesdrop","Returntype":"*MatchRuleBuilder","Args":"eavesdrop bool"},{"Uniquefunname":"func (b *MatchRuleBuilder) ExtPropertiesChanged(path, interfaceName string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.ExtPropertiesChanged","Returntype":"*MatchRuleBuilder","Args":"path, interfaceName string"},{"Uniquefunname":"func (b *MatchRuleBuilder) ExtSignal(path, interfaceName, name string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.ExtSignal","Returntype":"*MatchRuleBuilder","Args":"path, interfaceName, name string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Interface(interface0 string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.Interface","Returntype":"*MatchRuleBuilder","Args":"interface0 string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Member(member string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.Member","Returntype":"*MatchRuleBuilder","Args":"member string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Path(path string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.Path","Returntype":"*MatchRuleBuilder","Args":"path string"},{"Uniquefunname":"func (b *MatchRuleBuilder) PathNamespace(pathNamespace string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.PathNamespace","Returntype":"*MatchRuleBuilder","Args":"pathNamespace string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Sender(sender string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.Sender","Returntype":"*MatchRuleBuilder","Args":"sender string"},{"Uniquefunname":"func (b *MatchRuleBuilder) Type(type0 string) *MatchRuleBuilder","Funname":"dbusutil.MatchRuleBuilder.Type","Returntype":"*MatchRuleBuilder","Args":"type0 string"},{"Uniquefunname":"func (b *MatchRuleBuilder) addItem(k, v string)","Funname":"dbusutil.MatchRuleBuilder.addItem","Returntype":"","Args":"k, v string"},{"Uniquefunname":"func NewMatchRuleBuilder() *MatchRuleBuilder","Funname":"dbusutil.NewMatchRuleBuilder","Returntype":"*MatchRuleBuilder","Args":""}],"Records":[{"Name":"struct:dbusutil.MatchRule","Fields":["dbusutil.MatchRule.Str string"]},{"Name":"struct:dbusutil.MatchRuleBuilder","Fields":["dbusutil.MatchRuleBuilder.items []matchRuleItem"]},{"Name":"struct:dbusutil.matchRuleItem","Fields":["dbusutil.matchRuleItem.key string","dbusutil.matchRuleItem.value string"]}]} {"Filepath":"dbusutil/match_rule_test.go","Functions":[{"Uniquefunname":"func TestMatchRuleBuilder(t *testing.T)","Funname":"TestMatchRuleBuilder","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMatchRuleBuilder(t *testing.T)","Funname":"dbusutil.TestMatchRuleBuilder","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"dbusutil/object.go","Functions":[{"Uniquefunname":"func ConnectChanged(v Implementer, propertyName string, cb PropertyChangedCallback)error","Funname":"ConnectChanged","Returntype":"error","Args":"v Implementer, propertyName string, cb PropertyChangedCallback"},{"Uniquefunname":"func (so *ServerObject) Export() error","Funname":"Export","Returntype":"error","Args":""},{"Uniquefunname":"func (so *ServerObject) Path() dbus.ObjectPath","Funname":"Path","Returntype":"dbus.ObjectPath","Args":""},{"Uniquefunname":"func SetReadCallback(v Implementer, propertyName string, cb PropertyReadCallback)error","Funname":"SetReadCallback","Returntype":"error","Args":"v Implementer, propertyName string, cb PropertyReadCallback"},{"Uniquefunname":"func SetWriteCallback(v Implementer, propertyName string, cb PropertyWriteCallback)error","Funname":"SetWriteCallback","Returntype":"error","Args":"v Implementer, propertyName string, cb PropertyWriteCallback"},{"Uniquefunname":"func (so *ServerObject) StopExport() error","Funname":"StopExport","Returntype":"error","Args":""},{"Uniquefunname":"func dbusutil.ServerObject.ConnectChanged(v Implementer, propertyName string, cb PropertyChangedCallback)error","Funname":"dbusutil.ServerObject.ConnectChanged","Returntype":"error","Args":"v Implementer, propertyName string, cb PropertyChangedCallback"},{"Uniquefunname":"func (so *ServerObject) Export() error","Funname":"dbusutil.ServerObject.Export","Returntype":"error","Args":""},{"Uniquefunname":"func (so *ServerObject) Path() dbus.ObjectPath","Funname":"dbusutil.ServerObject.Path","Returntype":"dbus.ObjectPath","Args":""},{"Uniquefunname":"func dbusutil.ServerObject.SetReadCallback(v Implementer, propertyName string, cb PropertyReadCallback)error","Funname":"dbusutil.ServerObject.SetReadCallback","Returntype":"error","Args":"v Implementer, propertyName string, cb PropertyReadCallback"},{"Uniquefunname":"func dbusutil.ServerObject.SetWriteCallback(v Implementer, propertyName string, cb PropertyWriteCallback)error","Funname":"dbusutil.ServerObject.SetWriteCallback","Returntype":"error","Args":"v Implementer, propertyName string, cb PropertyWriteCallback"},{"Uniquefunname":"func (so *ServerObject) StopExport() error","Funname":"dbusutil.ServerObject.StopExport","Returntype":"error","Args":""},{"Uniquefunname":"func (so *ServerObject) getImplementer(interfaceName string) *implementer","Funname":"dbusutil.ServerObject.getImplementer","Returntype":"*implementer","Args":"interfaceName string"},{"Uniquefunname":"func (so *ServerObject) getImplementer(interfaceName string) *implementer","Funname":"getImplementer","Returntype":"*implementer","Args":"interfaceName string"}],"Records":[{"Name":"struct:dbusutil.ServerObject","Fields":["dbusutil.ServerObject.implementers []*implementer","dbusutil.ServerObject.path dbus.ObjectPath","dbusutil.ServerObject.service *Service"]}]} {"Filepath":"dbusutil/properties.go","Functions":[{"Uniquefunname":"func dbusutil.ServerObject.propertiesGet(sender dbus.Sender, interfaceName, propertyName string)(dbus.Variant, *dbus.Error)","Funname":"dbusutil.ServerObject.propertiesGet","Returntype":"(dbus.Variant, *dbus.Error)","Args":"sender dbus.Sender, interfaceName, propertyName string"},{"Uniquefunname":"func dbusutil.ServerObject.propertiesGetAll(sender dbus.Sender, interfaceName string)(map[string]dbus.Variant, *dbus.Error)","Funname":"dbusutil.ServerObject.propertiesGetAll","Returntype":"(map[string]dbus.Variant, *dbus.Error)","Args":"sender dbus.Sender, interfaceName string"},{"Uniquefunname":"func dbusutil.ServerObject.propertiesSet(sender dbus.Sender, interfaceName, propertyName string, newVar dbus.Variant)*dbus.Error","Funname":"dbusutil.ServerObject.propertiesSet","Returntype":"*dbus.Error","Args":"sender dbus.Sender, interfaceName, propertyName string, newVar dbus.Variant"},{"Uniquefunname":"func propertiesGet(sender dbus.Sender, interfaceName, propertyName string)(dbus.Variant, *dbus.Error)","Funname":"propertiesGet","Returntype":"(dbus.Variant, *dbus.Error)","Args":"sender dbus.Sender, interfaceName, propertyName string"},{"Uniquefunname":"func propertiesGetAll(sender dbus.Sender, interfaceName string)(map[string]dbus.Variant, *dbus.Error)","Funname":"propertiesGetAll","Returntype":"(map[string]dbus.Variant, *dbus.Error)","Args":"sender dbus.Sender, interfaceName string"},{"Uniquefunname":"func propertiesSet(sender dbus.Sender, interfaceName, propertyName string, newVar dbus.Variant)*dbus.Error","Funname":"propertiesSet","Returntype":"*dbus.Error","Args":"sender dbus.Sender, interfaceName, propertyName string, newVar dbus.Variant"}],"Records":null} {"Filepath":"dbusutil/service.go","Functions":[{"Uniquefunname":"func (s *Service) Conn() *dbus.Conn","Funname":"Conn","Returntype":"*dbus.Conn","Args":""},{"Uniquefunname":"func (s *Service) DelayAutoQuit()","Funname":"DelayAutoQuit","Returntype":"","Args":""},{"Uniquefunname":"func (s *Service) DelayEmitPropertyChanged(v Implementer) func() error","Funname":"DelayEmitPropertyChanged","Returntype":"func() error","Args":"v Implementer"},{"Uniquefunname":"func (s *Service) DumpProperties(v Implementer) (string, error)","Funname":"DumpProperties","Returntype":"(string, error)","Args":"v Implementer"},{"Uniquefunname":"func (s *Service) Emit(v Implementer, signalName string, values ...interface","Funname":"Emit","Returntype":"error","Args":"v Implementer, signalName string, values ...interface{}"},{"Uniquefunname":"func EmitPropertiesChanged(v Implementer, propValMap map[string]interface{}, invalidatedProps ...string)error","Funname":"EmitPropertiesChanged","Returntype":"error","Args":"v Implementer, propValMap map[string]interface{}, invalidatedProps ...string"},{"Uniquefunname":"func EmitPropertyChanged(v Implementer, propertyName string, value interface{})error","Funname":"EmitPropertyChanged","Returntype":"error","Args":"v Implementer, propertyName string, value interface{}"},{"Uniquefunname":"func (s *Service) Export(path dbus.ObjectPath, implements ...Implementer) error","Funname":"Export","Returntype":"error","Args":"path dbus.ObjectPath, implements ...Implementer"},{"Uniquefunname":"func (s *Service) GetConnPID(name string) (pid uint32, err error)","Funname":"GetConnPID","Returntype":"(pid uint32, err error)","Args":"name string"},{"Uniquefunname":"func (s *Service) GetConnUID(name string) (uid uint32, err error)","Funname":"GetConnUID","Returntype":"(uid uint32, err error)","Args":"name string"},{"Uniquefunname":"func (s *Service) GetNameOwner(name string) (owner string, err error)","Funname":"GetNameOwner","Returntype":"(owner string, err error)","Args":"name string"},{"Uniquefunname":"func (s *Service) GetServerObject(impl Implementer) *ServerObject","Funname":"GetServerObject","Returntype":"*ServerObject","Args":"impl Implementer"},{"Uniquefunname":"func (s *Service) GetServerObjectByPath(path dbus.ObjectPath) *ServerObject","Funname":"GetServerObjectByPath","Returntype":"*ServerObject","Args":"path dbus.ObjectPath"},{"Uniquefunname":"func (s *Service) IsExported(impl Implementer) bool","Funname":"IsExported","Returntype":"bool","Args":"impl Implementer"},{"Uniquefunname":"func (s *Service) NameHasOwner(name string) (hasOwner bool, err error)","Funname":"NameHasOwner","Returntype":"(hasOwner bool, err error)","Args":"name string"},{"Uniquefunname":"func NewServerObject(path dbus.ObjectPath, implementers ...Implementer)(*ServerObject, error)","Funname":"NewServerObject","Returntype":"(*ServerObject, error)","Args":"path dbus.ObjectPath, implementers ...Implementer"},{"Uniquefunname":"func NewService(conn *dbus.Conn) *Service","Funname":"NewService","Returntype":"*Service","Args":"conn *dbus.Conn"},{"Uniquefunname":"func NewSessionService() (*Service, error)","Funname":"NewSessionService","Returntype":"(*Service, error)","Args":""},{"Uniquefunname":"func NewSystemService() (*Service, error)","Funname":"NewSystemService","Returntype":"(*Service, error)","Args":""},{"Uniquefunname":"func (s *Service) Quit()","Funname":"Quit","Returntype":"","Args":""},{"Uniquefunname":"func (s *Service) ReleaseName(name string) error","Funname":"ReleaseName","Returntype":"error","Args":"name string"},{"Uniquefunname":"func (s *Service) RequestName(name string) error","Funname":"RequestName","Returntype":"error","Args":"name string"},{"Uniquefunname":"func (s *Service) SetAutoQuitHandler(interval time.Duration, canQuit func() bool)","Funname":"SetAutoQuitHandler","Returntype":"","Args":"interval time.Duration, canQuit func() bool"},{"Uniquefunname":"func (s *Service) StopExport(impl Implementer) error","Funname":"StopExport","Returntype":"error","Args":"impl Implementer"},{"Uniquefunname":"func (s *Service) StopExportByPath(path dbus.ObjectPath) error","Funname":"StopExportByPath","Returntype":"error","Args":"path dbus.ObjectPath"},{"Uniquefunname":"func (s *Service) Wait()","Funname":"Wait","Returntype":"","Args":""},{"Uniquefunname":"func NewService(conn *dbus.Conn) *Service","Funname":"dbusutil.NewService","Returntype":"*Service","Args":"conn *dbus.Conn"},{"Uniquefunname":"func NewSessionService() (*Service, error)","Funname":"dbusutil.NewSessionService","Returntype":"(*Service, error)","Args":""},{"Uniquefunname":"func NewSystemService() (*Service, error)","Funname":"dbusutil.NewSystemService","Returntype":"(*Service, error)","Args":""},{"Uniquefunname":"func (s *Service) Conn() *dbus.Conn","Funname":"dbusutil.Service.Conn","Returntype":"*dbus.Conn","Args":""},{"Uniquefunname":"func (s *Service) DelayAutoQuit()","Funname":"dbusutil.Service.DelayAutoQuit","Returntype":"","Args":""},{"Uniquefunname":"func (s *Service) DelayEmitPropertyChanged(v Implementer) func() error","Funname":"dbusutil.Service.DelayEmitPropertyChanged","Returntype":"func() error","Args":"v Implementer"},{"Uniquefunname":"func (s *Service) DumpProperties(v Implementer) (string, error)","Funname":"dbusutil.Service.DumpProperties","Returntype":"(string, error)","Args":"v Implementer"},{"Uniquefunname":"func (s *Service) Emit(v Implementer, signalName string, values ...interface","Funname":"dbusutil.Service.Emit","Returntype":"error","Args":"v Implementer, signalName string, values ...interface{}"},{"Uniquefunname":"func dbusutil.Service.EmitPropertiesChanged(v Implementer, propValMap map[string]interface{}, invalidatedProps ...string)error","Funname":"dbusutil.Service.EmitPropertiesChanged","Returntype":"error","Args":"v Implementer, propValMap map[string]interface{}, invalidatedProps ...string"},{"Uniquefunname":"func dbusutil.Service.EmitPropertyChanged(v Implementer, propertyName string, value interface{})error","Funname":"dbusutil.Service.EmitPropertyChanged","Returntype":"error","Args":"v Implementer, propertyName string, value interface{}"},{"Uniquefunname":"func (s *Service) Export(path dbus.ObjectPath, implements ...Implementer) error","Funname":"dbusutil.Service.Export","Returntype":"error","Args":"path dbus.ObjectPath, implements ...Implementer"},{"Uniquefunname":"func (s *Service) GetConnPID(name string) (pid uint32, err error)","Funname":"dbusutil.Service.GetConnPID","Returntype":"(pid uint32, err error)","Args":"name string"},{"Uniquefunname":"func (s *Service) GetConnUID(name string) (uid uint32, err error)","Funname":"dbusutil.Service.GetConnUID","Returntype":"(uid uint32, err error)","Args":"name string"},{"Uniquefunname":"func (s *Service) GetNameOwner(name string) (owner string, err error)","Funname":"dbusutil.Service.GetNameOwner","Returntype":"(owner string, err error)","Args":"name string"},{"Uniquefunname":"func (s *Service) GetServerObject(impl Implementer) *ServerObject","Funname":"dbusutil.Service.GetServerObject","Returntype":"*ServerObject","Args":"impl Implementer"},{"Uniquefunname":"func (s *Service) GetServerObjectByPath(path dbus.ObjectPath) *ServerObject","Funname":"dbusutil.Service.GetServerObjectByPath","Returntype":"*ServerObject","Args":"path dbus.ObjectPath"},{"Uniquefunname":"func (s *Service) IsExported(impl Implementer) bool","Funname":"dbusutil.Service.IsExported","Returntype":"bool","Args":"impl Implementer"},{"Uniquefunname":"func (s *Service) NameHasOwner(name string) (hasOwner bool, err error)","Funname":"dbusutil.Service.NameHasOwner","Returntype":"(hasOwner bool, err error)","Args":"name string"},{"Uniquefunname":"func dbusutil.Service.NewServerObject(path dbus.ObjectPath, implementers ...Implementer)(*ServerObject, error)","Funname":"dbusutil.Service.NewServerObject","Returntype":"(*ServerObject, error)","Args":"path dbus.ObjectPath, implementers ...Implementer"},{"Uniquefunname":"func (s *Service) Quit()","Funname":"dbusutil.Service.Quit","Returntype":"","Args":""},{"Uniquefunname":"func (s *Service) ReleaseName(name string) error","Funname":"dbusutil.Service.ReleaseName","Returntype":"error","Args":"name string"},{"Uniquefunname":"func (s *Service) RequestName(name string) error","Funname":"dbusutil.Service.RequestName","Returntype":"error","Args":"name string"},{"Uniquefunname":"func (s *Service) SetAutoQuitHandler(interval time.Duration, canQuit func() bool)","Funname":"dbusutil.Service.SetAutoQuitHandler","Returntype":"","Args":"interval time.Duration, canQuit func() bool"},{"Uniquefunname":"func (s *Service) StopExport(impl Implementer) error","Funname":"dbusutil.Service.StopExport","Returntype":"error","Args":"impl Implementer"},{"Uniquefunname":"func (s *Service) StopExportByPath(path dbus.ObjectPath) error","Funname":"dbusutil.Service.StopExportByPath","Returntype":"error","Args":"path dbus.ObjectPath"},{"Uniquefunname":"func (s *Service) Wait()","Funname":"dbusutil.Service.Wait","Returntype":"","Args":""},{"Uniquefunname":"func (s *Service) getImplementerStatic(impl Implementer) *implementerStatic","Funname":"dbusutil.Service.getImplementerStatic","Returntype":"*implementerStatic","Args":"impl Implementer"},{"Uniquefunname":"func (s *Service) getImplementerStatic(impl Implementer) *implementerStatic","Funname":"getImplementerStatic","Returntype":"*implementerStatic","Args":"impl Implementer"}],"Records":[{"Name":"struct:dbusutil.Service","Fields":["dbusutil.Service.canQuit func() bool","dbusutil.Service.conn *dbus.Conn","dbusutil.Service.hasCall bool","dbusutil.Service.implObjMap map[unsafe.Pointer]*ServerObject","dbusutil.Service.implStaticMap map[string]*implementerStatic","dbusutil.Service.mu sync.RWMutex","dbusutil.Service.objMap map[dbus.ObjectPath]*ServerObject","dbusutil.Service.quit chan struct{}","dbusutil.Service.quitCheckInterval time.Duration"]}]} {"Filepath":"dbusutil/service_test.go","Functions":[{"Uniquefunname":"func (*srvObject1) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject10) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject11) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject13) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject2) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject3) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject4) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject5) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject6) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject7) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject8) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject9) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (srvObject12) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (srvString) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (cp *customProperty) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (cp *customProperty) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (*srvObject1) Method1() (int, *dbus.Error)","Funname":"Method1","Returntype":"(int, *dbus.Error)","Args":""},{"Uniquefunname":"func (obj *srvObject5) Method1() *dbus.Error","Funname":"Method1","Returntype":"*dbus.Error","Args":""},{"Uniquefunname":"func (*customProperty) SetNotifyChangedFunc(func(val interface","Funname":"SetNotifyChangedFunc","Returntype":"","Args":"func(val interface{})"},{"Uniquefunname":"func (*customProperty) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func TestService_AutoQuit(t *testing.T)","Funname":"TestService_AutoQuit","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_ConnectChanged(t *testing.T)","Funname":"TestService_ConnectChanged","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_DumpProperties(t *testing.T)","Funname":"TestService_DumpProperties","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_Emit(t *testing.T)","Funname":"TestService_Emit","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_EmitPropertiesChanged(t *testing.T)","Funname":"TestService_EmitPropertiesChanged","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_EmitPropertyChanged(t *testing.T)","Funname":"TestService_EmitPropertyChanged","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_Export(t *testing.T)","Funname":"TestService_Export","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_GetConnPIDAndUID(t *testing.T)","Funname":"TestService_GetConnPIDAndUID","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_GetNameOwner(t *testing.T)","Funname":"TestService_GetNameOwner","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_IntUintProp(t *testing.T)","Funname":"TestService_IntUintProp","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_NameHasOwner(t *testing.T)","Funname":"TestService_NameHasOwner","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_PropTag(t *testing.T)","Funname":"TestService_PropTag","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_RequestName(t *testing.T)","Funname":"TestService_RequestName","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_SetReadCallback(t *testing.T)","Funname":"TestService_SetReadCallback","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_SetWriteCallback(t *testing.T)","Funname":"TestService_SetWriteCallback","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_StructProp(t *testing.T)","Funname":"TestService_StructProp","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_AutoQuit(t *testing.T)","Funname":"dbusutil.TestService_AutoQuit","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_ConnectChanged(t *testing.T)","Funname":"dbusutil.TestService_ConnectChanged","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_DumpProperties(t *testing.T)","Funname":"dbusutil.TestService_DumpProperties","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_Emit(t *testing.T)","Funname":"dbusutil.TestService_Emit","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_EmitPropertiesChanged(t *testing.T)","Funname":"dbusutil.TestService_EmitPropertiesChanged","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_EmitPropertyChanged(t *testing.T)","Funname":"dbusutil.TestService_EmitPropertyChanged","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_Export(t *testing.T)","Funname":"dbusutil.TestService_Export","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_GetConnPIDAndUID(t *testing.T)","Funname":"dbusutil.TestService_GetConnPIDAndUID","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_GetNameOwner(t *testing.T)","Funname":"dbusutil.TestService_GetNameOwner","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_IntUintProp(t *testing.T)","Funname":"dbusutil.TestService_IntUintProp","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_NameHasOwner(t *testing.T)","Funname":"dbusutil.TestService_NameHasOwner","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_PropTag(t *testing.T)","Funname":"dbusutil.TestService_PropTag","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_RequestName(t *testing.T)","Funname":"dbusutil.TestService_RequestName","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_SetReadCallback(t *testing.T)","Funname":"dbusutil.TestService_SetReadCallback","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_SetWriteCallback(t *testing.T)","Funname":"dbusutil.TestService_SetWriteCallback","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestService_StructProp(t *testing.T)","Funname":"dbusutil.TestService_StructProp","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (cp *customProperty) GetType() reflect.Type","Funname":"dbusutil.customProperty.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (cp *customProperty) GetValue() (val interface","Funname":"dbusutil.customProperty.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (*customProperty) SetNotifyChangedFunc(func(val interface","Funname":"dbusutil.customProperty.SetNotifyChangedFunc","Returntype":"","Args":"func(val interface{})"},{"Uniquefunname":"func (*customProperty) SetValue(val interface","Funname":"dbusutil.customProperty.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func processSignal(conn *dbus.Conn, fn func(signal *dbus.Signal) bool)","Funname":"dbusutil.processSignal","Returntype":"","Args":"conn *dbus.Conn, fn func(signal *dbus.Signal) bool"},{"Uniquefunname":"func (*srvObject1) GetInterfaceName() string","Funname":"dbusutil.srvObject1.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject1) Method1() (int, *dbus.Error)","Funname":"dbusutil.srvObject1.Method1","Returntype":"(int, *dbus.Error)","Args":""},{"Uniquefunname":"func (*srvObject10) GetInterfaceName() string","Funname":"dbusutil.srvObject10.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject11) GetInterfaceName() string","Funname":"dbusutil.srvObject11.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (srvObject12) GetInterfaceName() string","Funname":"dbusutil.srvObject12.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject13) GetInterfaceName() string","Funname":"dbusutil.srvObject13.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject2) GetInterfaceName() string","Funname":"dbusutil.srvObject2.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject3) GetInterfaceName() string","Funname":"dbusutil.srvObject3.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject4) GetInterfaceName() string","Funname":"dbusutil.srvObject4.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject5) GetInterfaceName() string","Funname":"dbusutil.srvObject5.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (obj *srvObject5) Method1() *dbus.Error","Funname":"dbusutil.srvObject5.Method1","Returntype":"*dbus.Error","Args":""},{"Uniquefunname":"func (*srvObject6) GetInterfaceName() string","Funname":"dbusutil.srvObject6.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject7) GetInterfaceName() string","Funname":"dbusutil.srvObject7.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject8) GetInterfaceName() string","Funname":"dbusutil.srvObject8.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (*srvObject9) GetInterfaceName() string","Funname":"dbusutil.srvObject9.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func (srvString) GetInterfaceName() string","Funname":"dbusutil.srvString.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func processSignal(conn *dbus.Conn, fn func(signal *dbus.Signal) bool)","Funname":"processSignal","Returntype":"","Args":"conn *dbus.Conn, fn func(signal *dbus.Signal) bool"}],"Records":[{"Name":"struct:dbusutil.customProperty","Fields":["dbusutil.customProperty.value int32"]},{"Name":"struct:dbusutil.integers","Fields":["dbusutil.integers.A int","dbusutil.integers.B uint"]},{"Name":"struct:dbusutil.rect","Fields":["dbusutil.rect.H int32","dbusutil.rect.W int32","dbusutil.rect.X uint32","dbusutil.rect.Y uint32"]},{"Name":"var:dbusutil","Fields":["dbusutil.serviceEmitPropertiesChangedTest","dbusutil.serviceEmitPropertyChangedTests"]},{"Name":"struct:dbusutil.srvObject1","Fields":["dbusutil.srvObject1.methods *struct { Method1 func() `out:\"num\"`; }"]},{"Name":"struct:dbusutil.srvObject10","Fields":["dbusutil.srvObject10.Prop1 rect","dbusutil.srvObject10.Prop2 []rect","dbusutil.srvObject10.Prop3 map[string]rect","dbusutil.srvObject10.Prop4 twoRect","dbusutil.srvObject10.prop1ChangedCount int","dbusutil.srvObject10.prop2ChangedCount int","dbusutil.srvObject10.prop3ChangedCount int","dbusutil.srvObject10.prop4ChangedCount int"]},{"Name":"struct:dbusutil.srvObject11","Fields":["dbusutil.srvObject11.Prop1 uint32","dbusutil.srvObject11.Prop2 uint64","dbusutil.srvObject11.Prop3 string","dbusutil.srvObject11.Prop4 map[string]uint32","dbusutil.srvObject11.Prop4Mu sync.RWMutex","dbusutil.srvObject11.Prop5 *customProperty","dbusutil.srvObject11.PropsMu sync.RWMutex"]},{"Name":"struct:dbusutil.srvObject13","Fields":["dbusutil.srvObject13.Prop1 int","dbusutil.srvObject13.Prop2 uint","dbusutil.srvObject13.Prop3 integers","dbusutil.srvObject13.prop1ChangedCount int","dbusutil.srvObject13.prop2ChangedCount int","dbusutil.srvObject13.prop3ChangedCount int"]},{"Name":"struct:dbusutil.srvObject2","Fields":["dbusutil.srvObject2.signals *struct { Signal1 struct{}; Signal2 struct { Arg1 string; Arg2 uint32; }; }"]},{"Name":"struct:dbusutil.srvObject3","Fields":["dbusutil.srvObject3.Prop1 string","dbusutil.srvObject3.Prop2 uint32","dbusutil.srvObject3.PropsMu sync.RWMutex"]},{"Name":"struct:dbusutil.srvObject4","Fields":["dbusutil.srvObject4.Prop1 string","dbusutil.srvObject4.Prop2 uint32","dbusutil.srvObject4.PropsMu sync.RWMutex"]},{"Name":"struct:dbusutil.srvObject5","Fields":["dbusutil.srvObject5.s *Service"]},{"Name":"struct:dbusutil.srvObject6","Fields":["dbusutil.srvObject6.Prop1 string","dbusutil.srvObject6.prop1ReadCount int"]},{"Name":"struct:dbusutil.srvObject7","Fields":["dbusutil.srvObject7.Prop1 string","dbusutil.srvObject7.prop1WriteCount int"]},{"Name":"struct:dbusutil.srvObject8","Fields":["dbusutil.srvObject8.Prop1 string","dbusutil.srvObject8.changedCountA int","dbusutil.srvObject8.changedCountB int"]},{"Name":"struct:dbusutil.srvObject9","Fields":["dbusutil.srvObject9.Prop0 int32","dbusutil.srvObject9.Prop1 int32","dbusutil.srvObject9.Prop2 int32","dbusutil.srvObject9.Prop3 int32","dbusutil.srvObject9.Prop4 int32","dbusutil.srvObject9.Prop5 int32","dbusutil.srvObject9.Prop6 int32"]},{"Name":"struct:dbusutil.twoRect","Fields":["dbusutil.twoRect.A rect","dbusutil.twoRect.B rect"]}]} {"Filepath":"dbusutil/signal.go","Functions":[{"Uniquefunname":"func (sl *SignalLoop) AddHandler(rule *SignalRule, cb SignalHandlerFunc) SignalHandlerId","Funname":"AddHandler","Returntype":"SignalHandlerId","Args":"rule *SignalRule, cb SignalHandlerFunc"},{"Uniquefunname":"func (sl *SignalLoop) Conn() *dbus.Conn","Funname":"Conn","Returntype":"*dbus.Conn","Args":""},{"Uniquefunname":"func NewSignalLoop(conn *dbus.Conn, bufSize int) *SignalLoop","Funname":"NewSignalLoop","Returntype":"*SignalLoop","Args":"conn *dbus.Conn, bufSize int"},{"Uniquefunname":"func (sl *SignalLoop) RemoveHandler(id SignalHandlerId)","Funname":"RemoveHandler","Returntype":"","Args":"id SignalHandlerId"},{"Uniquefunname":"func (sl *SignalLoop) Start()","Funname":"Start","Returntype":"","Args":""},{"Uniquefunname":"func (sl *SignalLoop) Stop()","Funname":"Stop","Returntype":"","Args":""},{"Uniquefunname":"func NewSignalLoop(conn *dbus.Conn, bufSize int) *SignalLoop","Funname":"dbusutil.NewSignalLoop","Returntype":"*SignalLoop","Args":"conn *dbus.Conn, bufSize int"},{"Uniquefunname":"func (sl *SignalLoop) AddHandler(rule *SignalRule, cb SignalHandlerFunc) SignalHandlerId","Funname":"dbusutil.SignalLoop.AddHandler","Returntype":"SignalHandlerId","Args":"rule *SignalRule, cb SignalHandlerFunc"},{"Uniquefunname":"func (sl *SignalLoop) Conn() *dbus.Conn","Funname":"dbusutil.SignalLoop.Conn","Returntype":"*dbus.Conn","Args":""},{"Uniquefunname":"func (sl *SignalLoop) RemoveHandler(id SignalHandlerId)","Funname":"dbusutil.SignalLoop.RemoveHandler","Returntype":"","Args":"id SignalHandlerId"},{"Uniquefunname":"func (sl *SignalLoop) Start()","Funname":"dbusutil.SignalLoop.Start","Returntype":"","Args":""},{"Uniquefunname":"func (sl *SignalLoop) Stop()","Funname":"dbusutil.SignalLoop.Stop","Returntype":"","Args":""},{"Uniquefunname":"func (sl *SignalLoop) process(signal *dbus.Signal)","Funname":"dbusutil.SignalLoop.process","Returntype":"","Args":"signal *dbus.Signal"},{"Uniquefunname":"func (m *SignalRule) match(sig *dbus.Signal) bool","Funname":"dbusutil.SignalRule.match","Returntype":"bool","Args":"sig *dbus.Signal"},{"Uniquefunname":"func (m *SignalRule) match(sig *dbus.Signal) bool","Funname":"match","Returntype":"bool","Args":"sig *dbus.Signal"},{"Uniquefunname":"func (sl *SignalLoop) process(signal *dbus.Signal)","Funname":"process","Returntype":"","Args":"signal *dbus.Signal"}],"Records":[{"Name":"struct:dbusutil.SignalHandler","Fields":["dbusutil.SignalHandler.cb SignalHandlerFunc","dbusutil.SignalHandler.rule *SignalRule"]},{"Name":"struct:dbusutil.SignalLoop","Fields":["dbusutil.SignalLoop.bufSize int","dbusutil.SignalLoop.ch chan *dbus.Signal","dbusutil.SignalLoop.conn *dbus.Conn","dbusutil.SignalLoop.handlers map[SignalHandlerId]SignalHandler","dbusutil.SignalLoop.mu sync.Mutex","dbusutil.SignalLoop.nextHandlerId SignalHandlerId"]},{"Name":"struct:dbusutil.SignalRule","Fields":["dbusutil.SignalRule.Name string","dbusutil.SignalRule.Path dbus.ObjectPath","dbusutil.SignalRule.Sender string"]}]} {"Filepath":"dbusutil/_tool/dbusutil-gen/main.go","Functions":[{"Uniquefunname":"func astNodeToStr(fset *token.FileSet, node interface","Funname":"astNodeToStr","Returntype":"(string, error)","Args":"fset *token.FileSet, node interface{}"},{"Uniquefunname":"func (g *Generator) format() []byte","Funname":"format","Returntype":"[]byte","Args":""},{"Uniquefunname":"func (g *Generator) generate()","Funname":"generate","Returntype":"","Args":""},{"Uniquefunname":"func getEqualFunc(option string) string","Funname":"getEqualFunc","Returntype":"string","Args":"option string"},{"Uniquefunname":"func getOptionFromComment(comment string) string","Funname":"getOptionFromComment","Returntype":"string","Args":"comment string"},{"Uniquefunname":"func getProps(fs *token.FileSet, structType *ast.StructType) []Property","Funname":"getProps","Returntype":"[]Property","Args":"fs *token.FileSet, structType *ast.StructType"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func isExportField(fieldName string) bool","Funname":"isExportField","Returntype":"bool","Args":"fieldName string"},{"Uniquefunname":"func main()","Funname":"main","Returntype":"","Args":""},{"Uniquefunname":"func (g *Generator) format() []byte","Funname":"main.Generator.format","Returntype":"[]byte","Args":""},{"Uniquefunname":"func (g *Generator) generate()","Funname":"main.Generator.generate","Returntype":"","Args":""},{"Uniquefunname":"func (g *Generator) parseFiles(names []string, types strv.Strv)","Funname":"main.Generator.parseFiles","Returntype":"","Args":"names []string, types strv.Strv"},{"Uniquefunname":"func (g *Generator) printf(format string, args ...interface","Funname":"main.Generator.printf","Returntype":"(int, error)","Args":"format string, args ...interface{}"},{"Uniquefunname":"func astNodeToStr(fset *token.FileSet, node interface","Funname":"main.astNodeToStr","Returntype":"(string, error)","Args":"fset *token.FileSet, node interface{}"},{"Uniquefunname":"func getEqualFunc(option string) string","Funname":"main.getEqualFunc","Returntype":"string","Args":"option string"},{"Uniquefunname":"func getOptionFromComment(comment string) string","Funname":"main.getOptionFromComment","Returntype":"string","Args":"comment string"},{"Uniquefunname":"func getProps(fs *token.FileSet, structType *ast.StructType) []Property","Funname":"main.getProps","Returntype":"[]Property","Args":"fs *token.FileSet, structType *ast.StructType"},{"Uniquefunname":"func init()","Funname":"main.init","Returntype":"","Args":""},{"Uniquefunname":"func isExportField(fieldName string) bool","Funname":"main.isExportField","Returntype":"bool","Args":"fieldName string"},{"Uniquefunname":"func main()","Funname":"main.main","Returntype":"","Args":""},{"Uniquefunname":"func (g *Generator) parseFiles(names []string, types strv.Strv)","Funname":"parseFiles","Returntype":"","Args":"names []string, types strv.Strv"},{"Uniquefunname":"func (g *Generator) printf(format string, args ...interface","Funname":"printf","Returntype":"(int, error)","Args":"format string, args ...interface{}"}],"Records":[{"Name":"struct:main.Generator","Fields":["main.Generator.buf bytes.Buffer","main.Generator.pkg Package"]},{"Name":"struct:main.Package","Fields":["main.Package.extraImports []string","main.Package.name string","main.Package.typePropMap map[string][]Property"]},{"Name":"struct:main.Property","Fields":["main.Property.Equal string","main.Property.Name string","main.Property.Type string"]},{"Name":"var:main","Fields":["main.extraImports","main.outputFile","main.typeNames"]},{"Name":"const:main","Fields":["main.propsMuField"]}]} {"Filepath":"dbusutil/gsprop/gsprop.go","Functions":[{"Uniquefunname":"func (b *Bool) Bind(gs *gio.Settings, key string)","Funname":"Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (d *Double) Bind(gs *gio.Settings, key string)","Funname":"Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (e *Enum) Bind(gs *gio.Settings, key string)","Funname":"Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (i *Int) Bind(gs *gio.Settings, key string)","Funname":"Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (s *String) Bind(gs *gio.Settings, key string)","Funname":"Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (s *Strv) Bind(gs *gio.Settings, key string)","Funname":"Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (u *Uint) Bind(gs *gio.Settings, key string)","Funname":"Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (u *Uint64) Bind(gs *gio.Settings, key string)","Funname":"Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (b *Bool) Get() bool","Funname":"Get","Returntype":"bool","Args":""},{"Uniquefunname":"func (d *Double) Get() float64","Funname":"Get","Returntype":"float64","Args":""},{"Uniquefunname":"func (e *Enum) Get() int32","Funname":"Get","Returntype":"int32","Args":""},{"Uniquefunname":"func (i *Int) Get() int32","Funname":"Get","Returntype":"int32","Args":""},{"Uniquefunname":"func (s *String) Get() string","Funname":"Get","Returntype":"string","Args":""},{"Uniquefunname":"func (s *Strv) Get() []string","Funname":"Get","Returntype":"[]string","Args":""},{"Uniquefunname":"func (u *Uint) Get() uint32","Funname":"Get","Returntype":"uint32","Args":""},{"Uniquefunname":"func (u *Uint64) Get() uint64","Funname":"Get","Returntype":"uint64","Args":""},{"Uniquefunname":"func (e *Enum) GetString() string","Funname":"GetString","Returntype":"string","Args":""},{"Uniquefunname":"func (*Bool) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (*Double) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (*Int) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (*String) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (*Strv) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (*Uint) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (*Uint64) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (e *Enum) GetType() reflect.Type","Funname":"GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (b *Bool) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (d *Double) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (e *Enum) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (i *Int) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (s *String) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (s *Strv) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (u *Uint) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (u *Uint64) GetValue() (val interface","Funname":"GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (b *Bool) Set(val bool) bool","Funname":"Set","Returntype":"bool","Args":"val bool"},{"Uniquefunname":"func (d *Double) Set(val float64) bool","Funname":"Set","Returntype":"bool","Args":"val float64"},{"Uniquefunname":"func (e *Enum) Set(val int32) bool","Funname":"Set","Returntype":"bool","Args":"val int32"},{"Uniquefunname":"func (i *Int) Set(val int32) bool","Funname":"Set","Returntype":"bool","Args":"val int32"},{"Uniquefunname":"func (s *String) Set(val string) bool","Funname":"Set","Returntype":"bool","Args":"val string"},{"Uniquefunname":"func (s *Strv) Set(val []string) bool","Funname":"Set","Returntype":"bool","Args":"val []string"},{"Uniquefunname":"func (u *Uint) Set(val uint32) bool","Funname":"Set","Returntype":"bool","Args":"val uint32"},{"Uniquefunname":"func (u *Uint64) Set(val uint64) bool","Funname":"Set","Returntype":"bool","Args":"val uint64"},{"Uniquefunname":"func (b *base) SetNotifyChangedFunc(fn func(val interface","Funname":"SetNotifyChangedFunc","Returntype":"","Args":"fn func(val interface{})"},{"Uniquefunname":"func (e *Enum) SetString(val string) bool","Funname":"SetString","Returntype":"bool","Args":"val string"},{"Uniquefunname":"func (b *Bool) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (d *Double) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (e *Enum) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (i *Int) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (s *String) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (s *Strv) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (u *Uint) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (u *Uint64) SetValue(val interface","Funname":"SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func bind(gs *gio.Settings, keyName string, getFn func() (interface{}, *dbus.Error))","Funname":"bind","Returntype":"","Args":"gs *gio.Settings, keyName string, getFn func() (interface{}, *dbus.Error)"},{"Uniquefunname":"func checkSet(setOk bool) *dbus.Error","Funname":"checkSet","Returntype":"*dbus.Error","Args":"setOk bool"},{"Uniquefunname":"func (b *Bool) Bind(gs *gio.Settings, key string)","Funname":"gsprop.Bool.Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (b *Bool) Get() bool","Funname":"gsprop.Bool.Get","Returntype":"bool","Args":""},{"Uniquefunname":"func (*Bool) GetType() reflect.Type","Funname":"gsprop.Bool.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (b *Bool) GetValue() (val interface","Funname":"gsprop.Bool.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (b *Bool) Set(val bool) bool","Funname":"gsprop.Bool.Set","Returntype":"bool","Args":"val bool"},{"Uniquefunname":"func (b *Bool) SetValue(val interface","Funname":"gsprop.Bool.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (d *Double) Bind(gs *gio.Settings, key string)","Funname":"gsprop.Double.Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (d *Double) Get() float64","Funname":"gsprop.Double.Get","Returntype":"float64","Args":""},{"Uniquefunname":"func (*Double) GetType() reflect.Type","Funname":"gsprop.Double.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (d *Double) GetValue() (val interface","Funname":"gsprop.Double.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (d *Double) Set(val float64) bool","Funname":"gsprop.Double.Set","Returntype":"bool","Args":"val float64"},{"Uniquefunname":"func (d *Double) SetValue(val interface","Funname":"gsprop.Double.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (e *Enum) Bind(gs *gio.Settings, key string)","Funname":"gsprop.Enum.Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (e *Enum) Get() int32","Funname":"gsprop.Enum.Get","Returntype":"int32","Args":""},{"Uniquefunname":"func (e *Enum) GetString() string","Funname":"gsprop.Enum.GetString","Returntype":"string","Args":""},{"Uniquefunname":"func (e *Enum) GetType() reflect.Type","Funname":"gsprop.Enum.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (e *Enum) GetValue() (val interface","Funname":"gsprop.Enum.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (e *Enum) Set(val int32) bool","Funname":"gsprop.Enum.Set","Returntype":"bool","Args":"val int32"},{"Uniquefunname":"func (e *Enum) SetString(val string) bool","Funname":"gsprop.Enum.SetString","Returntype":"bool","Args":"val string"},{"Uniquefunname":"func (e *Enum) SetValue(val interface","Funname":"gsprop.Enum.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (i *Int) Bind(gs *gio.Settings, key string)","Funname":"gsprop.Int.Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (i *Int) Get() int32","Funname":"gsprop.Int.Get","Returntype":"int32","Args":""},{"Uniquefunname":"func (*Int) GetType() reflect.Type","Funname":"gsprop.Int.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (i *Int) GetValue() (val interface","Funname":"gsprop.Int.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (i *Int) Set(val int32) bool","Funname":"gsprop.Int.Set","Returntype":"bool","Args":"val int32"},{"Uniquefunname":"func (i *Int) SetValue(val interface","Funname":"gsprop.Int.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (s *String) Bind(gs *gio.Settings, key string)","Funname":"gsprop.String.Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (s *String) Get() string","Funname":"gsprop.String.Get","Returntype":"string","Args":""},{"Uniquefunname":"func (*String) GetType() reflect.Type","Funname":"gsprop.String.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (s *String) GetValue() (val interface","Funname":"gsprop.String.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (s *String) Set(val string) bool","Funname":"gsprop.String.Set","Returntype":"bool","Args":"val string"},{"Uniquefunname":"func (s *String) SetValue(val interface","Funname":"gsprop.String.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (s *Strv) Bind(gs *gio.Settings, key string)","Funname":"gsprop.Strv.Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (s *Strv) Get() []string","Funname":"gsprop.Strv.Get","Returntype":"[]string","Args":""},{"Uniquefunname":"func (*Strv) GetType() reflect.Type","Funname":"gsprop.Strv.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (s *Strv) GetValue() (val interface","Funname":"gsprop.Strv.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (s *Strv) Set(val []string) bool","Funname":"gsprop.Strv.Set","Returntype":"bool","Args":"val []string"},{"Uniquefunname":"func (s *Strv) SetValue(val interface","Funname":"gsprop.Strv.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (u *Uint) Bind(gs *gio.Settings, key string)","Funname":"gsprop.Uint.Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (u *Uint) Get() uint32","Funname":"gsprop.Uint.Get","Returntype":"uint32","Args":""},{"Uniquefunname":"func (*Uint) GetType() reflect.Type","Funname":"gsprop.Uint.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (u *Uint) GetValue() (val interface","Funname":"gsprop.Uint.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (u *Uint) Set(val uint32) bool","Funname":"gsprop.Uint.Set","Returntype":"bool","Args":"val uint32"},{"Uniquefunname":"func (u *Uint) SetValue(val interface","Funname":"gsprop.Uint.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (u *Uint64) Bind(gs *gio.Settings, key string)","Funname":"gsprop.Uint64.Bind","Returntype":"","Args":"gs *gio.Settings, key string"},{"Uniquefunname":"func (u *Uint64) Get() uint64","Funname":"gsprop.Uint64.Get","Returntype":"uint64","Args":""},{"Uniquefunname":"func (*Uint64) GetType() reflect.Type","Funname":"gsprop.Uint64.GetType","Returntype":"reflect.Type","Args":""},{"Uniquefunname":"func (u *Uint64) GetValue() (val interface","Funname":"gsprop.Uint64.GetValue","Returntype":"(val interface{}, err *dbus.Error)","Args":""},{"Uniquefunname":"func (u *Uint64) Set(val uint64) bool","Funname":"gsprop.Uint64.Set","Returntype":"bool","Args":"val uint64"},{"Uniquefunname":"func (u *Uint64) SetValue(val interface","Funname":"gsprop.Uint64.SetValue","Returntype":"(changed bool, err *dbus.Error)","Args":"val interface{}"},{"Uniquefunname":"func (b *base) SetNotifyChangedFunc(fn func(val interface","Funname":"gsprop.base.SetNotifyChangedFunc","Returntype":"","Args":"fn func(val interface{})"},{"Uniquefunname":"func gsprop.base.bind(gs *gio.Settings, keyName string, getFn func() (interface{}, *dbus.Error))","Funname":"gsprop.base.bind","Returntype":"","Args":"gs *gio.Settings, keyName string, getFn func() (interface{}, *dbus.Error)"},{"Uniquefunname":"func checkSet(setOk bool) *dbus.Error","Funname":"gsprop.checkSet","Returntype":"*dbus.Error","Args":"setOk bool"},{"Uniquefunname":"func strvEqual(a []string, b []string) bool","Funname":"gsprop.strvEqual","Returntype":"bool","Args":"a []string, b []string"},{"Uniquefunname":"func strvEqual(a []string, b []string) bool","Funname":"strvEqual","Returntype":"bool","Args":"a []string, b []string"}],"Records":[{"Name":"struct:gsprop.base","Fields":["gsprop.base.gs *gio.Settings","gsprop.base.key string","gsprop.base.mu sync.Mutex","gsprop.base.notifyChanged func(val interface{})"]}]} {"Filepath":"dbusutil/gsprop/gsprop_test.go","Functions":[{"Uniquefunname":"func (*srvObject1) GetInterfaceName() string","Funname":"GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func TestAll(t *testing.T)","Funname":"TestAll","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAll(t *testing.T)","Funname":"gsprop.TestAll","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func processSignal(conn *dbus.Conn, fn func(signal *dbus.Signal) bool)","Funname":"gsprop.processSignal","Returntype":"","Args":"conn *dbus.Conn, fn func(signal *dbus.Signal) bool"},{"Uniquefunname":"func (*srvObject1) GetInterfaceName() string","Funname":"gsprop.srvObject1.GetInterfaceName","Returntype":"string","Args":""},{"Uniquefunname":"func processSignal(conn *dbus.Conn, fn func(signal *dbus.Signal) bool)","Funname":"processSignal","Returntype":"","Args":"conn *dbus.Conn, fn func(signal *dbus.Signal) bool"}],"Records":[{"Name":"const:gsprop","Fields":["gsprop.demoSchemaId","gsprop.srvObj1Interface"]},{"Name":"struct:gsprop.srvObject1","Fields":["gsprop.srvObject1.Bool Bool","gsprop.srvObject1.Double Double","gsprop.srvObject1.Enum Enum","gsprop.srvObject1.Int Int","gsprop.srvObject1.String String","gsprop.srvObject1.Strv Strv","gsprop.srvObject1.Uint Uint"]}]} {"Filepath":"dbusutil/proxy/object.go","Functions":[{"Uniquefunname":"func ConnectPropertiesChanged(cb func(interfaceName string, changedProperties map[string]dbus.Variant, invalidatedProperties []string))(dbusutil.SignalHandlerId, error)","Funname":"ConnectPropertiesChanged","Returntype":"(dbusutil.SignalHandlerId, error)","Args":"cb func(interfaceName string, changedProperties map[string]dbus.Variant, invalidatedProperties []string)"},{"Uniquefunname":"func ConnectPropertyChanged_(interfaceName, propName string, callback PropChangedCallback)error","Funname":"ConnectPropertyChanged_","Returntype":"error","Args":"interfaceName, propName string, callback PropChangedCallback"},{"Uniquefunname":"func ConnectSignal_(rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc)(dbusutil.SignalHandlerId, error)","Funname":"ConnectSignal_","Returntype":"(dbusutil.SignalHandlerId, error)","Args":"rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc"},{"Uniquefunname":"func (o *Object) GetExtra(key string) (interface","Funname":"GetExtra","Returntype":"(interface{}, bool)","Args":"key string"},{"Uniquefunname":"func GetProperty_(flags dbus.Flags, interfaceName, propName string, value interface{})error","Funname":"GetProperty_","Returntype":"error","Args":"flags dbus.Flags, interfaceName, propName string, value interface{}"},{"Uniquefunname":"func Go_(method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{})*dbus.Call","Funname":"Go_","Returntype":"*dbus.Call","Args":"method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{}"},{"Uniquefunname":"func (o *Object) InitSignalExt(sigLoop *dbusutil.SignalLoop, ruleAuto bool)","Funname":"InitSignalExt","Returntype":"","Args":"sigLoop *dbusutil.SignalLoop, ruleAuto bool"},{"Uniquefunname":"func Init_(conn *dbus.Conn, serviceName string, path dbus.ObjectPath)","Funname":"Init_","Returntype":"","Args":"conn *dbus.Conn, serviceName string, path dbus.ObjectPath"},{"Uniquefunname":"func (o *Object) Path_() dbus.ObjectPath","Funname":"Path_","Returntype":"dbus.ObjectPath","Args":""},{"Uniquefunname":"func (o *Object) RemoveAllHandlers()","Funname":"RemoveAllHandlers","Returntype":"","Args":""},{"Uniquefunname":"func (o *Object) RemoveHandler(handlerId dbusutil.SignalHandlerId)","Funname":"RemoveHandler","Returntype":"","Args":"handlerId dbusutil.SignalHandlerId"},{"Uniquefunname":"func (o *Object) ServiceName_() string","Funname":"ServiceName_","Returntype":"string","Args":""},{"Uniquefunname":"func (o *Object) SetExtra(key string, v interface","Funname":"SetExtra","Returntype":"","Args":"key string, v interface{}"},{"Uniquefunname":"func SetProperty_(flags dbus.Flags, interfaceName, propName string, value interface{})error","Funname":"SetProperty_","Returntype":"error","Args":"flags dbus.Flags, interfaceName, propName string, value interface{}"},{"Uniquefunname":"func (o *Object) addMatch(rule string) error","Funname":"addMatch","Returntype":"error","Args":"rule string"},{"Uniquefunname":"func (o *Object) addRuleHandlerId(rule string, handlerId dbusutil.SignalHandlerId)","Funname":"addRuleHandlerId","Returntype":"","Args":"rule string, handlerId dbusutil.SignalHandlerId"},{"Uniquefunname":"func (o *Object) checkSignalExt()","Funname":"checkSignalExt","Returntype":"","Args":""},{"Uniquefunname":"func connectSignal(rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc)(dbusutil.SignalHandlerId, error)","Funname":"connectSignal","Returntype":"(dbusutil.SignalHandlerId, error)","Args":"rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc"},{"Uniquefunname":"func (o *Object) getMatchRulePropertiesChanged() string","Funname":"getMatchRulePropertiesChanged","Returntype":"string","Args":""},{"Uniquefunname":"func handlerIdSliceDelete(slice []dbusutil.SignalHandlerId, index int)[]dbusutil.SignalHandlerId","Funname":"handlerIdSliceDelete","Returntype":"[]dbusutil.SignalHandlerId","Args":"slice []dbusutil.SignalHandlerId, index int"},{"Uniquefunname":"func handlerIdSliceIndex(slice []dbusutil.SignalHandlerId, hId dbusutil.SignalHandlerId) int","Funname":"handlerIdSliceIndex","Returntype":"int","Args":"slice []dbusutil.SignalHandlerId, hId dbusutil.SignalHandlerId"},{"Uniquefunname":"func (o *Object) initPropertiesChangedHandler() error","Funname":"initPropertiesChangedHandler","Returntype":"error","Args":""},{"Uniquefunname":"func (o *Object) propChangedHandler(sig *dbus.Signal)","Funname":"propChangedHandler","Returntype":"","Args":"sig *dbus.Signal"},{"Uniquefunname":"func proxy.Object.ConnectPropertiesChanged(cb func(interfaceName string, changedProperties map[string]dbus.Variant, invalidatedProperties []string))(dbusutil.SignalHandlerId, error)","Funname":"proxy.Object.ConnectPropertiesChanged","Returntype":"(dbusutil.SignalHandlerId, error)","Args":"cb func(interfaceName string, changedProperties map[string]dbus.Variant, invalidatedProperties []string)"},{"Uniquefunname":"func proxy.Object.ConnectPropertyChanged_(interfaceName, propName string, callback PropChangedCallback)error","Funname":"proxy.Object.ConnectPropertyChanged_","Returntype":"error","Args":"interfaceName, propName string, callback PropChangedCallback"},{"Uniquefunname":"func proxy.Object.ConnectSignal_(rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc)(dbusutil.SignalHandlerId, error)","Funname":"proxy.Object.ConnectSignal_","Returntype":"(dbusutil.SignalHandlerId, error)","Args":"rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc"},{"Uniquefunname":"func (o *Object) GetExtra(key string) (interface","Funname":"proxy.Object.GetExtra","Returntype":"(interface{}, bool)","Args":"key string"},{"Uniquefunname":"func proxy.Object.GetProperty_(flags dbus.Flags, interfaceName, propName string, value interface{})error","Funname":"proxy.Object.GetProperty_","Returntype":"error","Args":"flags dbus.Flags, interfaceName, propName string, value interface{}"},{"Uniquefunname":"func proxy.Object.Go_(method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{})*dbus.Call","Funname":"proxy.Object.Go_","Returntype":"*dbus.Call","Args":"method string, flags dbus.Flags, ch chan *dbus.Call, args ...interface{}"},{"Uniquefunname":"func (o *Object) InitSignalExt(sigLoop *dbusutil.SignalLoop, ruleAuto bool)","Funname":"proxy.Object.InitSignalExt","Returntype":"","Args":"sigLoop *dbusutil.SignalLoop, ruleAuto bool"},{"Uniquefunname":"func proxy.Object.Init_(conn *dbus.Conn, serviceName string, path dbus.ObjectPath)","Funname":"proxy.Object.Init_","Returntype":"","Args":"conn *dbus.Conn, serviceName string, path dbus.ObjectPath"},{"Uniquefunname":"func (o *Object) Path_() dbus.ObjectPath","Funname":"proxy.Object.Path_","Returntype":"dbus.ObjectPath","Args":""},{"Uniquefunname":"func (o *Object) RemoveAllHandlers()","Funname":"proxy.Object.RemoveAllHandlers","Returntype":"","Args":""},{"Uniquefunname":"func (o *Object) RemoveHandler(handlerId dbusutil.SignalHandlerId)","Funname":"proxy.Object.RemoveHandler","Returntype":"","Args":"handlerId dbusutil.SignalHandlerId"},{"Uniquefunname":"func (o *Object) ServiceName_() string","Funname":"proxy.Object.ServiceName_","Returntype":"string","Args":""},{"Uniquefunname":"func (o *Object) SetExtra(key string, v interface","Funname":"proxy.Object.SetExtra","Returntype":"","Args":"key string, v interface{}"},{"Uniquefunname":"func proxy.Object.SetProperty_(flags dbus.Flags, interfaceName, propName string, value interface{})error","Funname":"proxy.Object.SetProperty_","Returntype":"error","Args":"flags dbus.Flags, interfaceName, propName string, value interface{}"},{"Uniquefunname":"func (o *Object) addMatch(rule string) error","Funname":"proxy.Object.addMatch","Returntype":"error","Args":"rule string"},{"Uniquefunname":"func (o *Object) addRuleHandlerId(rule string, handlerId dbusutil.SignalHandlerId)","Funname":"proxy.Object.addRuleHandlerId","Returntype":"","Args":"rule string, handlerId dbusutil.SignalHandlerId"},{"Uniquefunname":"func (o *Object) checkSignalExt()","Funname":"proxy.Object.checkSignalExt","Returntype":"","Args":""},{"Uniquefunname":"func proxy.Object.connectSignal(rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc)(dbusutil.SignalHandlerId, error)","Funname":"proxy.Object.connectSignal","Returntype":"(dbusutil.SignalHandlerId, error)","Args":"rule string, sigRule *dbusutil.SignalRule, cb dbusutil.SignalHandlerFunc"},{"Uniquefunname":"func (o *Object) getMatchRulePropertiesChanged() string","Funname":"proxy.Object.getMatchRulePropertiesChanged","Returntype":"string","Args":""},{"Uniquefunname":"func (o *Object) initPropertiesChangedHandler() error","Funname":"proxy.Object.initPropertiesChangedHandler","Returntype":"error","Args":""},{"Uniquefunname":"func (o *Object) propChangedHandler(sig *dbus.Signal)","Funname":"proxy.Object.propChangedHandler","Returntype":"","Args":"sig *dbus.Signal"},{"Uniquefunname":"func (o *Object) removeAllHandlers()","Funname":"proxy.Object.removeAllHandlers","Returntype":"","Args":""},{"Uniquefunname":"func (o *Object) removeHandler(handlerId dbusutil.SignalHandlerId)","Funname":"proxy.Object.removeHandler","Returntype":"","Args":"handlerId dbusutil.SignalHandlerId"},{"Uniquefunname":"func (o *Object) removePropertiesChangedHandler()","Funname":"proxy.Object.removePropertiesChangedHandler","Returntype":"","Args":""},{"Uniquefunname":"func proxy.handlerIdSliceDelete(slice []dbusutil.SignalHandlerId, index int)[]dbusutil.SignalHandlerId","Funname":"proxy.handlerIdSliceDelete","Returntype":"[]dbusutil.SignalHandlerId","Args":"slice []dbusutil.SignalHandlerId, index int"},{"Uniquefunname":"func handlerIdSliceIndex(slice []dbusutil.SignalHandlerId, hId dbusutil.SignalHandlerId) int","Funname":"proxy.handlerIdSliceIndex","Returntype":"int","Args":"slice []dbusutil.SignalHandlerId, hId dbusutil.SignalHandlerId"},{"Uniquefunname":"func storeGetProperty(call *dbus.Call, value interface","Funname":"proxy.storeGetProperty","Returntype":"error","Args":"call *dbus.Call, value interface{}"},{"Uniquefunname":"func (o *Object) removeAllHandlers()","Funname":"removeAllHandlers","Returntype":"","Args":""},{"Uniquefunname":"func (o *Object) removeHandler(handlerId dbusutil.SignalHandlerId)","Funname":"removeHandler","Returntype":"","Args":"handlerId dbusutil.SignalHandlerId"},{"Uniquefunname":"func (o *Object) removePropertiesChangedHandler()","Funname":"removePropertiesChangedHandler","Returntype":"","Args":""},{"Uniquefunname":"func storeGetProperty(call *dbus.Call, value interface","Funname":"storeGetProperty","Returntype":"error","Args":"call *dbus.Call, value interface{}"}],"Records":[{"Name":"interface","Fields":["proxy.Implementer"]},{"Name":"struct:proxy.Object","Fields":["proxy.Object.conn *dbus.Conn","proxy.Object.extraMap map[string]interface{}","proxy.Object.mu sync.Mutex","proxy.Object.obj dbus.BusObject"]},{"Name":"const:proxy","Fields":["proxy.RemoveAllHandlers","proxy.RemovePropertiesChangedHandler"]},{"Name":"struct:proxy.objectSignalExt","Fields":["proxy.objectSignalExt.handleIds []dbusutil.SignalHandlerId","proxy.objectSignalExt.propChangedCallbacks map[propChangedKey][]PropChangedCallback","proxy.objectSignalExt.propChangedHandlerId dbusutil.SignalHandlerId","proxy.objectSignalExt.ruleAuto bool","proxy.objectSignalExt.ruleHandlersMap map[string][]dbusutil.SignalHandlerId","proxy.objectSignalExt.sigLoop *dbusutil.SignalLoop"]},{"Name":"struct:proxy.propChangedKey","Fields":["proxy.propChangedKey.interfaceName string","proxy.propChangedKey.propName string"]}]} {"Filepath":"dbusutil/proxy/prop.go","Functions":[{"Uniquefunname":"func (p PropBool) ConnectChanged(cb func(hasValue bool, value bool)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value bool)"},{"Uniquefunname":"func (p PropBoolArray) ConnectChanged(cb func(hasValue bool, value []bool)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []bool)"},{"Uniquefunname":"func (p PropByte) ConnectChanged(cb func(hasValue bool, value byte)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value byte)"},{"Uniquefunname":"func (p PropByteArray) ConnectChanged(cb func(hasValue bool, value []byte)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []byte)"},{"Uniquefunname":"func (p PropDouble) ConnectChanged(cb func(hasValue bool, value float64)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value float64)"},{"Uniquefunname":"func (p PropDoubleArray) ConnectChanged(cb func(hasValue bool, value []float64)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []float64)"},{"Uniquefunname":"func (p PropInt16) ConnectChanged(cb func(hasValue bool, value int16)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value int16)"},{"Uniquefunname":"func (p PropInt16Array) ConnectChanged(cb func(hasValue bool, value []int16)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []int16)"},{"Uniquefunname":"func (p PropInt32) ConnectChanged(cb func(hasValue bool, value int32)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value int32)"},{"Uniquefunname":"func (p PropInt32Array) ConnectChanged(cb func(hasValue bool, value []int32)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []int32)"},{"Uniquefunname":"func (p PropInt64) ConnectChanged(cb func(hasValue bool, value int64)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value int64)"},{"Uniquefunname":"func (p PropInt64Array) ConnectChanged(cb func(hasValue bool, value []int64)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []int64)"},{"Uniquefunname":"func (p PropObjectPath) ConnectChanged(cb func(hasValue bool, value dbus.ObjectPath)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value dbus.ObjectPath)"},{"Uniquefunname":"func ConnectChanged(cb func(hasValue bool, value []dbus.ObjectPath))error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []dbus.ObjectPath)"},{"Uniquefunname":"func (p PropString) ConnectChanged(cb func(hasValue bool, value string)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value string)"},{"Uniquefunname":"func (p PropStringArray) ConnectChanged(cb func(hasValue bool, value []string)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []string)"},{"Uniquefunname":"func (p PropUint16) ConnectChanged(cb func(hasValue bool, value uint16)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value uint16)"},{"Uniquefunname":"func (p PropUint16Array) ConnectChanged(cb func(hasValue bool, value []uint16)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []uint16)"},{"Uniquefunname":"func (p PropUint32) ConnectChanged(cb func(hasValue bool, value uint32)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value uint32)"},{"Uniquefunname":"func (p PropUint32Array) ConnectChanged(cb func(hasValue bool, value []uint32)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []uint32)"},{"Uniquefunname":"func (p PropUint64) ConnectChanged(cb func(hasValue bool, value uint64)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value uint64)"},{"Uniquefunname":"func (p PropUint64Array) ConnectChanged(cb func(hasValue bool, value []uint64)) error","Funname":"ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []uint64)"},{"Uniquefunname":"func (p PropBool) Get(flags dbus.Flags) (value bool, err error)","Funname":"Get","Returntype":"(value bool, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropBoolArray) Get(flags dbus.Flags) (value []bool, err error)","Funname":"Get","Returntype":"(value []bool, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropByte) Get(flags dbus.Flags) (value byte, err error)","Funname":"Get","Returntype":"(value byte, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropByteArray) Get(flags dbus.Flags) (value []byte, err error)","Funname":"Get","Returntype":"(value []byte, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropDouble) Get(flags dbus.Flags) (value float64, err error)","Funname":"Get","Returntype":"(value float64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropDoubleArray) Get(flags dbus.Flags) (value []float64, err error)","Funname":"Get","Returntype":"(value []float64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt16) Get(flags dbus.Flags) (value int16, err error)","Funname":"Get","Returntype":"(value int16, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt16Array) Get(flags dbus.Flags) (value []int16, err error)","Funname":"Get","Returntype":"(value []int16, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt32) Get(flags dbus.Flags) (value int32, err error)","Funname":"Get","Returntype":"(value int32, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt32Array) Get(flags dbus.Flags) (value []int32, err error)","Funname":"Get","Returntype":"(value []int32, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt64) Get(flags dbus.Flags) (value int64, err error)","Funname":"Get","Returntype":"(value int64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt64Array) Get(flags dbus.Flags) (value []int64, err error)","Funname":"Get","Returntype":"(value []int64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropObjectPath) Get(flags dbus.Flags) (value dbus.ObjectPath, err error)","Funname":"Get","Returntype":"(value dbus.ObjectPath, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropObjectPathArray) Get(flags dbus.Flags) (value []dbus.ObjectPath, err error)","Funname":"Get","Returntype":"(value []dbus.ObjectPath, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropString) Get(flags dbus.Flags) (value string, err error)","Funname":"Get","Returntype":"(value string, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropStringArray) Get(flags dbus.Flags) (value []string, err error)","Funname":"Get","Returntype":"(value []string, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint16) Get(flags dbus.Flags) (value uint16, err error)","Funname":"Get","Returntype":"(value uint16, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint16Array) Get(flags dbus.Flags) (value []uint16, err error)","Funname":"Get","Returntype":"(value []uint16, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint32) Get(flags dbus.Flags) (value uint32, err error)","Funname":"Get","Returntype":"(value uint32, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint32Array) Get(flags dbus.Flags) (value []uint32, err error)","Funname":"Get","Returntype":"(value []uint32, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint64) Get(flags dbus.Flags) (value uint64, err error)","Funname":"Get","Returntype":"(value uint64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint64Array) Get(flags dbus.Flags) (value []uint64, err error)","Funname":"Get","Returntype":"(value []uint64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropBool) Set(flags dbus.Flags, value bool) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value bool"},{"Uniquefunname":"func (p PropBoolArray) Set(flags dbus.Flags, value []bool) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []bool"},{"Uniquefunname":"func (p PropByte) Set(flags dbus.Flags, value byte) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value byte"},{"Uniquefunname":"func (p PropByteArray) Set(flags dbus.Flags, value []byte) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []byte"},{"Uniquefunname":"func (p PropDouble) Set(flags dbus.Flags, value float64) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value float64"},{"Uniquefunname":"func (p PropDoubleArray) Set(flags dbus.Flags, value []float64) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []float64"},{"Uniquefunname":"func (p PropInt16) Set(flags dbus.Flags, value int16) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value int16"},{"Uniquefunname":"func (p PropInt16Array) Set(flags dbus.Flags, value []int16) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []int16"},{"Uniquefunname":"func (p PropInt32) Set(flags dbus.Flags, value int32) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value int32"},{"Uniquefunname":"func (p PropInt32Array) Set(flags dbus.Flags, value []int32) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []int32"},{"Uniquefunname":"func (p PropInt64) Set(flags dbus.Flags, value int64) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value int64"},{"Uniquefunname":"func (p PropInt64Array) Set(flags dbus.Flags, value []int64) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []int64"},{"Uniquefunname":"func (p PropObjectPath) Set(flags dbus.Flags, value dbus.ObjectPath) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value dbus.ObjectPath"},{"Uniquefunname":"func (p PropObjectPathArray) Set(flags dbus.Flags, value []dbus.ObjectPath) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []dbus.ObjectPath"},{"Uniquefunname":"func (p PropString) Set(flags dbus.Flags, value string) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value string"},{"Uniquefunname":"func (p PropStringArray) Set(flags dbus.Flags, value []string) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []string"},{"Uniquefunname":"func (p PropUint16) Set(flags dbus.Flags, value uint16) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value uint16"},{"Uniquefunname":"func (p PropUint16Array) Set(flags dbus.Flags, value []uint16) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []uint16"},{"Uniquefunname":"func (p PropUint32) Set(flags dbus.Flags, value uint32) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value uint32"},{"Uniquefunname":"func (p PropUint32Array) Set(flags dbus.Flags, value []uint32) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []uint32"},{"Uniquefunname":"func (p PropUint64) Set(flags dbus.Flags, value uint64) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value uint64"},{"Uniquefunname":"func (p PropUint64Array) Set(flags dbus.Flags, value []uint64) error","Funname":"Set","Returntype":"error","Args":"flags dbus.Flags, value []uint64"},{"Uniquefunname":"func (p PropBool) ConnectChanged(cb func(hasValue bool, value bool)) error","Funname":"proxy.PropBool.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value bool)"},{"Uniquefunname":"func (p PropBool) Get(flags dbus.Flags) (value bool, err error)","Funname":"proxy.PropBool.Get","Returntype":"(value bool, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropBool) Set(flags dbus.Flags, value bool) error","Funname":"proxy.PropBool.Set","Returntype":"error","Args":"flags dbus.Flags, value bool"},{"Uniquefunname":"func (p PropBoolArray) ConnectChanged(cb func(hasValue bool, value []bool)) error","Funname":"proxy.PropBoolArray.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []bool)"},{"Uniquefunname":"func (p PropBoolArray) Get(flags dbus.Flags) (value []bool, err error)","Funname":"proxy.PropBoolArray.Get","Returntype":"(value []bool, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropBoolArray) Set(flags dbus.Flags, value []bool) error","Funname":"proxy.PropBoolArray.Set","Returntype":"error","Args":"flags dbus.Flags, value []bool"},{"Uniquefunname":"func (p PropByte) ConnectChanged(cb func(hasValue bool, value byte)) error","Funname":"proxy.PropByte.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value byte)"},{"Uniquefunname":"func (p PropByte) Get(flags dbus.Flags) (value byte, err error)","Funname":"proxy.PropByte.Get","Returntype":"(value byte, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropByte) Set(flags dbus.Flags, value byte) error","Funname":"proxy.PropByte.Set","Returntype":"error","Args":"flags dbus.Flags, value byte"},{"Uniquefunname":"func (p PropByteArray) ConnectChanged(cb func(hasValue bool, value []byte)) error","Funname":"proxy.PropByteArray.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []byte)"},{"Uniquefunname":"func (p PropByteArray) Get(flags dbus.Flags) (value []byte, err error)","Funname":"proxy.PropByteArray.Get","Returntype":"(value []byte, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropByteArray) Set(flags dbus.Flags, value []byte) error","Funname":"proxy.PropByteArray.Set","Returntype":"error","Args":"flags dbus.Flags, value []byte"},{"Uniquefunname":"func (p PropDouble) ConnectChanged(cb func(hasValue bool, value float64)) error","Funname":"proxy.PropDouble.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value float64)"},{"Uniquefunname":"func (p PropDouble) Get(flags dbus.Flags) (value float64, err error)","Funname":"proxy.PropDouble.Get","Returntype":"(value float64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropDouble) Set(flags dbus.Flags, value float64) error","Funname":"proxy.PropDouble.Set","Returntype":"error","Args":"flags dbus.Flags, value float64"},{"Uniquefunname":"func (p PropDoubleArray) ConnectChanged(cb func(hasValue bool, value []float64)) error","Funname":"proxy.PropDoubleArray.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []float64)"},{"Uniquefunname":"func (p PropDoubleArray) Get(flags dbus.Flags) (value []float64, err error)","Funname":"proxy.PropDoubleArray.Get","Returntype":"(value []float64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropDoubleArray) Set(flags dbus.Flags, value []float64) error","Funname":"proxy.PropDoubleArray.Set","Returntype":"error","Args":"flags dbus.Flags, value []float64"},{"Uniquefunname":"func (p PropInt16) ConnectChanged(cb func(hasValue bool, value int16)) error","Funname":"proxy.PropInt16.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value int16)"},{"Uniquefunname":"func (p PropInt16) Get(flags dbus.Flags) (value int16, err error)","Funname":"proxy.PropInt16.Get","Returntype":"(value int16, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt16) Set(flags dbus.Flags, value int16) error","Funname":"proxy.PropInt16.Set","Returntype":"error","Args":"flags dbus.Flags, value int16"},{"Uniquefunname":"func (p PropInt16Array) ConnectChanged(cb func(hasValue bool, value []int16)) error","Funname":"proxy.PropInt16Array.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []int16)"},{"Uniquefunname":"func (p PropInt16Array) Get(flags dbus.Flags) (value []int16, err error)","Funname":"proxy.PropInt16Array.Get","Returntype":"(value []int16, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt16Array) Set(flags dbus.Flags, value []int16) error","Funname":"proxy.PropInt16Array.Set","Returntype":"error","Args":"flags dbus.Flags, value []int16"},{"Uniquefunname":"func (p PropInt32) ConnectChanged(cb func(hasValue bool, value int32)) error","Funname":"proxy.PropInt32.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value int32)"},{"Uniquefunname":"func (p PropInt32) Get(flags dbus.Flags) (value int32, err error)","Funname":"proxy.PropInt32.Get","Returntype":"(value int32, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt32) Set(flags dbus.Flags, value int32) error","Funname":"proxy.PropInt32.Set","Returntype":"error","Args":"flags dbus.Flags, value int32"},{"Uniquefunname":"func (p PropInt32Array) ConnectChanged(cb func(hasValue bool, value []int32)) error","Funname":"proxy.PropInt32Array.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []int32)"},{"Uniquefunname":"func (p PropInt32Array) Get(flags dbus.Flags) (value []int32, err error)","Funname":"proxy.PropInt32Array.Get","Returntype":"(value []int32, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt32Array) Set(flags dbus.Flags, value []int32) error","Funname":"proxy.PropInt32Array.Set","Returntype":"error","Args":"flags dbus.Flags, value []int32"},{"Uniquefunname":"func (p PropInt64) ConnectChanged(cb func(hasValue bool, value int64)) error","Funname":"proxy.PropInt64.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value int64)"},{"Uniquefunname":"func (p PropInt64) Get(flags dbus.Flags) (value int64, err error)","Funname":"proxy.PropInt64.Get","Returntype":"(value int64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt64) Set(flags dbus.Flags, value int64) error","Funname":"proxy.PropInt64.Set","Returntype":"error","Args":"flags dbus.Flags, value int64"},{"Uniquefunname":"func (p PropInt64Array) ConnectChanged(cb func(hasValue bool, value []int64)) error","Funname":"proxy.PropInt64Array.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []int64)"},{"Uniquefunname":"func (p PropInt64Array) Get(flags dbus.Flags) (value []int64, err error)","Funname":"proxy.PropInt64Array.Get","Returntype":"(value []int64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropInt64Array) Set(flags dbus.Flags, value []int64) error","Funname":"proxy.PropInt64Array.Set","Returntype":"error","Args":"flags dbus.Flags, value []int64"},{"Uniquefunname":"func (p PropObjectPath) ConnectChanged(cb func(hasValue bool, value dbus.ObjectPath)) error","Funname":"proxy.PropObjectPath.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value dbus.ObjectPath)"},{"Uniquefunname":"func (p PropObjectPath) Get(flags dbus.Flags) (value dbus.ObjectPath, err error)","Funname":"proxy.PropObjectPath.Get","Returntype":"(value dbus.ObjectPath, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropObjectPath) Set(flags dbus.Flags, value dbus.ObjectPath) error","Funname":"proxy.PropObjectPath.Set","Returntype":"error","Args":"flags dbus.Flags, value dbus.ObjectPath"},{"Uniquefunname":"func proxy.PropObjectPathArray.ConnectChanged(cb func(hasValue bool, value []dbus.ObjectPath))error","Funname":"proxy.PropObjectPathArray.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []dbus.ObjectPath)"},{"Uniquefunname":"func (p PropObjectPathArray) Get(flags dbus.Flags) (value []dbus.ObjectPath, err error)","Funname":"proxy.PropObjectPathArray.Get","Returntype":"(value []dbus.ObjectPath, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropObjectPathArray) Set(flags dbus.Flags, value []dbus.ObjectPath) error","Funname":"proxy.PropObjectPathArray.Set","Returntype":"error","Args":"flags dbus.Flags, value []dbus.ObjectPath"},{"Uniquefunname":"func (p PropString) ConnectChanged(cb func(hasValue bool, value string)) error","Funname":"proxy.PropString.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value string)"},{"Uniquefunname":"func (p PropString) Get(flags dbus.Flags) (value string, err error)","Funname":"proxy.PropString.Get","Returntype":"(value string, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropString) Set(flags dbus.Flags, value string) error","Funname":"proxy.PropString.Set","Returntype":"error","Args":"flags dbus.Flags, value string"},{"Uniquefunname":"func (p PropStringArray) ConnectChanged(cb func(hasValue bool, value []string)) error","Funname":"proxy.PropStringArray.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []string)"},{"Uniquefunname":"func (p PropStringArray) Get(flags dbus.Flags) (value []string, err error)","Funname":"proxy.PropStringArray.Get","Returntype":"(value []string, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropStringArray) Set(flags dbus.Flags, value []string) error","Funname":"proxy.PropStringArray.Set","Returntype":"error","Args":"flags dbus.Flags, value []string"},{"Uniquefunname":"func (p PropUint16) ConnectChanged(cb func(hasValue bool, value uint16)) error","Funname":"proxy.PropUint16.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value uint16)"},{"Uniquefunname":"func (p PropUint16) Get(flags dbus.Flags) (value uint16, err error)","Funname":"proxy.PropUint16.Get","Returntype":"(value uint16, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint16) Set(flags dbus.Flags, value uint16) error","Funname":"proxy.PropUint16.Set","Returntype":"error","Args":"flags dbus.Flags, value uint16"},{"Uniquefunname":"func (p PropUint16Array) ConnectChanged(cb func(hasValue bool, value []uint16)) error","Funname":"proxy.PropUint16Array.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []uint16)"},{"Uniquefunname":"func (p PropUint16Array) Get(flags dbus.Flags) (value []uint16, err error)","Funname":"proxy.PropUint16Array.Get","Returntype":"(value []uint16, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint16Array) Set(flags dbus.Flags, value []uint16) error","Funname":"proxy.PropUint16Array.Set","Returntype":"error","Args":"flags dbus.Flags, value []uint16"},{"Uniquefunname":"func (p PropUint32) ConnectChanged(cb func(hasValue bool, value uint32)) error","Funname":"proxy.PropUint32.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value uint32)"},{"Uniquefunname":"func (p PropUint32) Get(flags dbus.Flags) (value uint32, err error)","Funname":"proxy.PropUint32.Get","Returntype":"(value uint32, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint32) Set(flags dbus.Flags, value uint32) error","Funname":"proxy.PropUint32.Set","Returntype":"error","Args":"flags dbus.Flags, value uint32"},{"Uniquefunname":"func (p PropUint32Array) ConnectChanged(cb func(hasValue bool, value []uint32)) error","Funname":"proxy.PropUint32Array.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []uint32)"},{"Uniquefunname":"func (p PropUint32Array) Get(flags dbus.Flags) (value []uint32, err error)","Funname":"proxy.PropUint32Array.Get","Returntype":"(value []uint32, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint32Array) Set(flags dbus.Flags, value []uint32) error","Funname":"proxy.PropUint32Array.Set","Returntype":"error","Args":"flags dbus.Flags, value []uint32"},{"Uniquefunname":"func (p PropUint64) ConnectChanged(cb func(hasValue bool, value uint64)) error","Funname":"proxy.PropUint64.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value uint64)"},{"Uniquefunname":"func (p PropUint64) Get(flags dbus.Flags) (value uint64, err error)","Funname":"proxy.PropUint64.Get","Returntype":"(value uint64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint64) Set(flags dbus.Flags, value uint64) error","Funname":"proxy.PropUint64.Set","Returntype":"error","Args":"flags dbus.Flags, value uint64"},{"Uniquefunname":"func (p PropUint64Array) ConnectChanged(cb func(hasValue bool, value []uint64)) error","Funname":"proxy.PropUint64Array.ConnectChanged","Returntype":"error","Args":"cb func(hasValue bool, value []uint64)"},{"Uniquefunname":"func (p PropUint64Array) Get(flags dbus.Flags) (value []uint64, err error)","Funname":"proxy.PropUint64Array.Get","Returntype":"(value []uint64, err error)","Args":"flags dbus.Flags"},{"Uniquefunname":"func (p PropUint64Array) Set(flags dbus.Flags, value []uint64) error","Funname":"proxy.PropUint64Array.Set","Returntype":"error","Args":"flags dbus.Flags, value []uint64"}],"Records":[{"Name":"struct:proxy.PropBool","Fields":["proxy.PropBool.Impl Implementer","proxy.PropBool.Name string"]},{"Name":"struct:proxy.PropBoolArray","Fields":["proxy.PropBoolArray.Impl Implementer","proxy.PropBoolArray.Name string"]},{"Name":"struct:proxy.PropByte","Fields":["proxy.PropByte.Impl Implementer","proxy.PropByte.Name string"]},{"Name":"struct:proxy.PropByteArray","Fields":["proxy.PropByteArray.Impl Implementer","proxy.PropByteArray.Name string"]},{"Name":"struct:proxy.PropDouble","Fields":["proxy.PropDouble.Impl Implementer","proxy.PropDouble.Name string"]},{"Name":"struct:proxy.PropDoubleArray","Fields":["proxy.PropDoubleArray.Impl Implementer","proxy.PropDoubleArray.Name string"]},{"Name":"struct:proxy.PropInt16","Fields":["proxy.PropInt16.Impl Implementer","proxy.PropInt16.Name string"]},{"Name":"struct:proxy.PropInt16Array","Fields":["proxy.PropInt16Array.Impl Implementer","proxy.PropInt16Array.Name string"]},{"Name":"struct:proxy.PropInt32","Fields":["proxy.PropInt32.Impl Implementer","proxy.PropInt32.Name string"]},{"Name":"struct:proxy.PropInt32Array","Fields":["proxy.PropInt32Array.Impl Implementer","proxy.PropInt32Array.Name string"]},{"Name":"struct:proxy.PropInt64","Fields":["proxy.PropInt64.Impl Implementer","proxy.PropInt64.Name string"]},{"Name":"struct:proxy.PropInt64Array","Fields":["proxy.PropInt64Array.Impl Implementer","proxy.PropInt64Array.Name string"]},{"Name":"struct:proxy.PropObjectPath","Fields":["proxy.PropObjectPath.Impl Implementer","proxy.PropObjectPath.Name string"]},{"Name":"struct:proxy.PropObjectPathArray","Fields":["proxy.PropObjectPathArray.Impl Implementer","proxy.PropObjectPathArray.Name string"]},{"Name":"struct:proxy.PropString","Fields":["proxy.PropString.Impl Implementer","proxy.PropString.Name string"]},{"Name":"struct:proxy.PropStringArray","Fields":["proxy.PropStringArray.Impl Implementer","proxy.PropStringArray.Name string"]},{"Name":"struct:proxy.PropUint16","Fields":["proxy.PropUint16.Impl Implementer","proxy.PropUint16.Name string"]},{"Name":"struct:proxy.PropUint16Array","Fields":["proxy.PropUint16Array.Impl Implementer","proxy.PropUint16Array.Name string"]},{"Name":"struct:proxy.PropUint32","Fields":["proxy.PropUint32.Impl Implementer","proxy.PropUint32.Name string"]},{"Name":"struct:proxy.PropUint32Array","Fields":["proxy.PropUint32Array.Impl Implementer","proxy.PropUint32Array.Name string"]},{"Name":"struct:proxy.PropUint64","Fields":["proxy.PropUint64.Impl Implementer","proxy.PropUint64.Name string"]},{"Name":"struct:proxy.PropUint64Array","Fields":["proxy.PropUint64Array.Impl Implementer","proxy.PropUint64Array.Name string"]},{"Name":"var:proxy","Fields":["proxy.errNilCallback"]}]} {"Filepath":"dbusutil/proxy/rule_counter.go","Functions":[{"Uniquefunname":"func DeleteConn(conn *dbus.Conn)","Funname":"DeleteConn","Returntype":"","Args":"conn *dbus.Conn"},{"Uniquefunname":"func (rc *ruleCounter) addMatch(conn *dbus.Conn, rule string) error","Funname":"addMatch","Returntype":"error","Args":"conn *dbus.Conn, rule string"},{"Uniquefunname":"func (rc *ruleCounter) deleteConn(conn *dbus.Conn)","Funname":"deleteConn","Returntype":"","Args":"conn *dbus.Conn"},{"Uniquefunname":"func getConnName(conn *dbus.Conn) string","Funname":"getConnName","Returntype":"string","Args":"conn *dbus.Conn"},{"Uniquefunname":"func DeleteConn(conn *dbus.Conn)","Funname":"proxy.DeleteConn","Returntype":"","Args":"conn *dbus.Conn"},{"Uniquefunname":"func getConnName(conn *dbus.Conn) string","Funname":"proxy.getConnName","Returntype":"string","Args":"conn *dbus.Conn"},{"Uniquefunname":"func (rc *ruleCounter) addMatch(conn *dbus.Conn, rule string) error","Funname":"proxy.ruleCounter.addMatch","Returntype":"error","Args":"conn *dbus.Conn, rule string"},{"Uniquefunname":"func (rc *ruleCounter) deleteConn(conn *dbus.Conn)","Funname":"proxy.ruleCounter.deleteConn","Returntype":"","Args":"conn *dbus.Conn"},{"Uniquefunname":"func (rc *ruleCounter) removeMatch(conn *dbus.Conn, rule string) error","Funname":"proxy.ruleCounter.removeMatch","Returntype":"error","Args":"conn *dbus.Conn, rule string"},{"Uniquefunname":"func (rc *ruleCounter) removeMatch(conn *dbus.Conn, rule string) error","Funname":"removeMatch","Returntype":"error","Args":"conn *dbus.Conn, rule string"}],"Records":[{"Name":"var:proxy","Fields":["proxy.globalRuleCounter"]},{"Name":"struct:proxy.ruleCounter","Fields":["proxy.ruleCounter.connRuleCount map[string]map[string]uint","proxy.ruleCounter.mu sync.Mutex"]}]} {"Filepath":"encoding/kv/reader.go","Functions":[{"Uniquefunname":"func NewReader(r io.Reader) *Reader","Funname":"NewReader","Returntype":"*Reader","Args":"r io.Reader"},{"Uniquefunname":"func (r *Reader) Read() (pair *Pair, err error)","Funname":"Read","Returntype":"(pair *Pair, err error)","Args":""},{"Uniquefunname":"func (r *Reader) ReadAll() (pairs []*Pair, err error)","Funname":"ReadAll","Returntype":"(pairs []*Pair, err error)","Args":""},{"Uniquefunname":"func NewReader(r io.Reader) *Reader","Funname":"kv.NewReader","Returntype":"*Reader","Args":"r io.Reader"},{"Uniquefunname":"func (r *Reader) Read() (pair *Pair, err error)","Funname":"kv.Reader.Read","Returntype":"(pair *Pair, err error)","Args":""},{"Uniquefunname":"func (r *Reader) ReadAll() (pairs []*Pair, err error)","Funname":"kv.Reader.ReadAll","Returntype":"(pairs []*Pair, err error)","Args":""},{"Uniquefunname":"func (r *Reader) parseLine() (*Pair, error)","Funname":"kv.Reader.parseLine","Returntype":"(*Pair, error)","Args":""},{"Uniquefunname":"func (r *Reader) parseLine() (*Pair, error)","Funname":"parseLine","Returntype":"(*Pair, error)","Args":""}],"Records":[{"Name":"var:kv","Fields":["kv.ErrBadLine"]},{"Name":"struct:kv.Pair","Fields":["kv.Pair.Key string","kv.Pair.Value string"]},{"Name":"struct:kv.Reader","Fields":["kv.Reader.Comment byte","kv.Reader.Delim byte","kv.Reader.TrimSpace TrimSpaceFlag","kv.Reader.r *bufio.Reader"]},{"Name":"const:kv","Fields":["kv.TrimAllSpace","kv.TrimDelimLeftSpace","kv.TrimDelimLeftSpace","kv.TrimDelimRightSpace","kv.TrimLeadingSpace","kv.TrimLeadingTailingSpace","kv.TrimTailingSpace"]}]} {"Filepath":"encoding/kv/reader_test.go","Functions":[{"Uniquefunname":"func TestReader(t *testing.T)","Funname":"TestReader","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestReader(t *testing.T)","Funname":"kv.TestReader","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"event/event.go","Functions":[{"Uniquefunname":"func New(f interface","Funname":"New","Returntype":"*Event","Args":"f interface{}"},{"Uniquefunname":"func (e *Event) Off(f interface","Funname":"Off","Returntype":"error","Args":"f interface{}"},{"Uniquefunname":"func (e *Event) On(f interface","Funname":"On","Returntype":"error","Args":"f interface{}"},{"Uniquefunname":"func (e *Event) Trigger(args ...interface","Funname":"Trigger","Returntype":"error","Args":"args ...interface{}"},{"Uniquefunname":"func (e *Event) checkFuncSignature(f interface","Funname":"checkFuncSignature","Returntype":"(*reflect.Value, error)","Args":"f interface{}"},{"Uniquefunname":"func (e *Event) Off(f interface","Funname":"event.Event.Off","Returntype":"error","Args":"f interface{}"},{"Uniquefunname":"func (e *Event) On(f interface","Funname":"event.Event.On","Returntype":"error","Args":"f interface{}"},{"Uniquefunname":"func (e *Event) Trigger(args ...interface","Funname":"event.Event.Trigger","Returntype":"error","Args":"args ...interface{}"},{"Uniquefunname":"func (e *Event) checkFuncSignature(f interface","Funname":"event.Event.checkFuncSignature","Returntype":"(*reflect.Value, error)","Args":"f interface{}"},{"Uniquefunname":"func New(f interface","Funname":"event.New","Returntype":"*Event","Args":"f interface{}"}],"Records":[{"Name":"struct:event.Event","Fields":["event.Event.argTypes []reflect.Type","event.Event.listeners []reflect.Value","event.Event.lmu sync.RWMutex"]}]} {"Filepath":"gdkpixbuf/blur.go","Functions":[{"Uniquefunname":"func Blur(pixbuf *C.GdkPixbuf, sigma, numSteps float64) (err error)","Funname":"Blur","Returntype":"(err error)","Args":"pixbuf *C.GdkPixbuf, sigma, numSteps float64"},{"Uniquefunname":"func BlurImage(srcFile, dstFile string, sigma, numSteps float64, f Format) (err error)","Funname":"BlurImage","Returntype":"(err error)","Args":"srcFile, dstFile string, sigma, numSteps float64, f Format"},{"Uniquefunname":"func BlurImageCache(srcFile string, sigma, numSteps float64, f Format)(dstFile string, useCache bool, err error)","Funname":"BlurImageCache","Returntype":"(dstFile string, useCache bool, err error)","Args":"srcFile string, sigma, numSteps float64, f Format"},{"Uniquefunname":"func Blur(pixbuf *C.GdkPixbuf, sigma, numSteps float64) (err error)","Funname":"gdkpixbuf.Blur","Returntype":"(err error)","Args":"pixbuf *C.GdkPixbuf, sigma, numSteps float64"},{"Uniquefunname":"func BlurImage(srcFile, dstFile string, sigma, numSteps float64, f Format) (err error)","Funname":"gdkpixbuf.BlurImage","Returntype":"(err error)","Args":"srcFile, dstFile string, sigma, numSteps float64, f Format"},{"Uniquefunname":"func gdkpixbuf.BlurImageCache(srcFile string, sigma, numSteps float64, f Format)(dstFile string, useCache bool, err error)","Funname":"gdkpixbuf.BlurImageCache","Returntype":"(dstFile string, useCache bool, err error)","Args":"srcFile string, sigma, numSteps float64, f Format"}],"Records":null} {"Filepath":"gdkpixbuf/constants.go","Functions":null,"Records":[{"Name":"const:gdkpixbuf","Fields":["gdkpixbuf.GDK_COLORSPACE_RGB","gdkpixbuf.GDK_INTERP_BILINEAR","gdkpixbuf.GDK_INTERP_HYPER","gdkpixbuf.GDK_INTERP_NEAREST","gdkpixbuf.GDK_INTERP_TILES","gdkpixbuf.GDK_PIXBUF_ALPHA_BILEVEL","gdkpixbuf.GDK_PIXBUF_ALPHA_FULL","gdkpixbuf.GDK_PIXBUF_ERROR_BAD_OPTION","gdkpixbuf.GDK_PIXBUF_ERROR_CORRUPT_IMAGE","gdkpixbuf.GDK_PIXBUF_ERROR_FAILED","gdkpixbuf.GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY","gdkpixbuf.GDK_PIXBUF_ERROR_UNKNOWN_TYPE","gdkpixbuf.GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION","gdkpixbuf.GDK_PIXBUF_ROTATE_CLOCKWISE","gdkpixbuf.GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE","gdkpixbuf.GDK_PIXBUF_ROTATE_NONE","gdkpixbuf.GDK_PIXBUF_ROTATE_UPSIDEDOWN","gdkpixbuf.GDK_PIXDATA_COLOR_TYPE_MASK","gdkpixbuf.GDK_PIXDATA_COLOR_TYPE_RGB","gdkpixbuf.GDK_PIXDATA_COLOR_TYPE_RGBA","gdkpixbuf.GDK_PIXDATA_DUMP_CONST","gdkpixbuf.GDK_PIXDATA_DUMP_CTYPES","gdkpixbuf.GDK_PIXDATA_DUMP_GTYPES","gdkpixbuf.GDK_PIXDATA_DUMP_MACROS","gdkpixbuf.GDK_PIXDATA_DUMP_PIXDATA_STREAM","gdkpixbuf.GDK_PIXDATA_DUMP_PIXDATA_STRUCT","gdkpixbuf.GDK_PIXDATA_DUMP_RLE_DECODER","gdkpixbuf.GDK_PIXDATA_DUMP_STATIC","gdkpixbuf.GDK_PIXDATA_ENCODING_MASK","gdkpixbuf.GDK_PIXDATA_ENCODING_RAW","gdkpixbuf.GDK_PIXDATA_ENCODING_RLE","gdkpixbuf.GDK_PIXDATA_SAMPLE_WIDTH_8","gdkpixbuf.GDK_PIXDATA_SAMPLE_WIDTH_MASK"]}]} {"Filepath":"gdkpixbuf/gdkpixbuf.go","Functions":[{"Uniquefunname":"func ClipImage(srcFile, destFile string, srcX, srcY, width, height int, f Format) (err error)","Funname":"ClipImage","Returntype":"(err error)","Args":"srcFile, destFile string, srcX, srcY, width, height int, f Format"},{"Uniquefunname":"func ConvertImage(srcFile, destFile string, f Format) (err error)","Funname":"ConvertImage","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func ConvertImageToXpixmap(imgFile string) (xpixmap x.Pixmap, err error)","Funname":"ConvertImageToXpixmap","Returntype":"(xpixmap x.Pixmap, err error)","Args":"imgFile string"},{"Uniquefunname":"func ConvertPixbufToXpixmap(pixbuf *C.GdkPixbuf) (xpixmap x.Pixmap, err error)","Funname":"ConvertPixbufToXpixmap","Returntype":"(xpixmap x.Pixmap, err error)","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func ConvertXpixmapToPixbuf(xpixmap x.Pixmap, width, height int)(pixbuf *C.GdkPixbuf, err error)","Funname":"ConvertXpixmapToPixbuf","Returntype":"(pixbuf *C.GdkPixbuf, err error)","Args":"xpixmap x.Pixmap, width, height int"},{"Uniquefunname":"func CopyArea(srcPixbuf, destPixbuf *C.GdkPixbuf, srcX, srcY, width, height, destX, destY int)(err error)","Funname":"CopyArea","Returntype":"(err error)","Args":"srcPixbuf, destPixbuf *C.GdkPixbuf, srcX, srcY, width, height, destX, destY int"},{"Uniquefunname":"func CopyAreaSimple(srcPixbuf *C.GdkPixbuf, srcX, srcY, width, height int)(destPixbuf *C.GdkPixbuf, err error)","Funname":"CopyAreaSimple","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, srcX, srcY, width, height int"},{"Uniquefunname":"func Flip(srcPixbuf *C.GdkPixbuf, horizontal bool) (destPixbuf *C.GdkPixbuf, err error)","Funname":"Flip","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, horizontal bool"},{"Uniquefunname":"func FlipImageHorizontal(srcFile, destFile string, f Format) (err error)","Funname":"FlipImageHorizontal","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func FlipImageVertical(srcFile, destFile string, f Format) (err error)","Funname":"FlipImageVertical","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func FreePixbuf(pixbuf *C.GdkPixbuf)","Funname":"FreePixbuf","Returntype":"","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func GetDominantColor(pixbuf *C.GdkPixbuf) (h, s, v float64, err error)","Funname":"GetDominantColor","Returntype":"(h, s, v float64, err error)","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func GetDominantColorOfImage(imgFile string) (h, s, v float64, err error)","Funname":"GetDominantColorOfImage","Returntype":"(h, s, v float64, err error)","Args":"imgFile string"},{"Uniquefunname":"func GetImageFormat(imgFile string) (f Format, err error)","Funname":"GetImageFormat","Returntype":"(f Format, err error)","Args":"imgFile string"},{"Uniquefunname":"func GetImageSize(imgFile string) (w, h int, err error)","Funname":"GetImageSize","Returntype":"(w, h int, err error)","Args":"imgFile string"},{"Uniquefunname":"func GetPixels(pixbuf *C.GdkPixbuf) []byte","Funname":"GetPixels","Returntype":"[]byte","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func GetSize(pixbuf *C.GdkPixbuf) (w, h int, err error)","Funname":"GetSize","Returntype":"(w, h int, err error)","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func InitGdk() (err error)","Funname":"InitGdk","Returntype":"(err error)","Args":""},{"Uniquefunname":"func InitGdkXlib() (err error)","Funname":"InitGdkXlib","Returntype":"(err error)","Args":""},{"Uniquefunname":"func IsSupportedImage(imgFile string) bool","Funname":"IsSupportedImage","Returntype":"bool","Args":"imgFile string"},{"Uniquefunname":"func NewPixbufFromFile(imgFile string) (pixbuf *C.GdkPixbuf, err error)","Funname":"NewPixbufFromFile","Returntype":"(pixbuf *C.GdkPixbuf, err error)","Args":"imgFile string"},{"Uniquefunname":"func RotateImageLeft(srcFile, destFile string, f Format) (err error)","Funname":"RotateImageLeft","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func RotateImageRight(srcFile, destFile string, f Format) (err error)","Funname":"RotateImageRight","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func RotateImageUpsizedown(srcFile, destFile string, f Format) (err error)","Funname":"RotateImageUpsizedown","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func RotateSimple(srcPixbuf *C.GdkPixbuf, angle GdkPixbufRotation)(destPixbuf *C.GdkPixbuf, err error)","Funname":"RotateSimple","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, angle GdkPixbufRotation"},{"Uniquefunname":"func Save(pixbuf *C.GdkPixbuf, destFile string, f Format) (err error)","Funname":"Save","Returntype":"(err error)","Args":"pixbuf *C.GdkPixbuf, destFile string, f Format"},{"Uniquefunname":"func ScaleImage(srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format)(err error)","Funname":"ScaleImage","Returntype":"(err error)","Args":"srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func ScaleImageCache(srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format)(destFile string, useCache bool, err error)","Funname":"ScaleImageCache","Returntype":"(destFile string, useCache bool, err error)","Args":"srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func ScaleImagePrefer(srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format)(err error)","Funname":"ScaleImagePrefer","Returntype":"(err error)","Args":"srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func ScaleImagePreferCache(srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format)(destFile string, useCache bool, err error)","Funname":"ScaleImagePreferCache","Returntype":"(destFile string, useCache bool, err error)","Args":"srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func ScalePrefer(srcPixbuf *C.GdkPixbuf, newWidth, newHeight int, interpType GdkInterpType)(destPixbuf *C.GdkPixbuf, err error)","Funname":"ScalePrefer","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, newWidth, newHeight int, interpType GdkInterpType"},{"Uniquefunname":"func ScaleSimple(srcPixbuf *C.GdkPixbuf, newWidth, newHeght int, interpType GdkInterpType)(destPixbuf *C.GdkPixbuf, err error)","Funname":"ScaleSimple","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, newWidth, newHeght int, interpType GdkInterpType"},{"Uniquefunname":"func Screenshot() (pixbuf *C.GdkPixbuf, err error)","Funname":"Screenshot","Returntype":"(pixbuf *C.GdkPixbuf, err error)","Args":""},{"Uniquefunname":"func ScreenshotImage(file string, f Format) (err error)","Funname":"ScreenshotImage","Returntype":"(err error)","Args":"file string, f Format"},{"Uniquefunname":"func Thumbnail(srcPixbuf *C.GdkPixbuf, maxWidth, maxHeight int, interpType GdkInterpType)(destPixbuf *C.GdkPixbuf, err error)","Funname":"Thumbnail","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, maxWidth, maxHeight int, interpType GdkInterpType"},{"Uniquefunname":"func ThumbnailImage(srcFile, destFile string, maxWidth, maxHeight int, interpType GdkInterpType, f Format)(err error)","Funname":"ThumbnailImage","Returntype":"(err error)","Args":"srcFile, destFile string, maxWidth, maxHeight int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func ToImage(pixbuf *C.GdkPixbuf) (image.Image, error)","Funname":"ToImage","Returntype":"(image.Image, error)","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func doFlipImage(srcFile, destFile string, horizontal bool, f Format) (err error)","Funname":"doFlipImage","Returntype":"(err error)","Args":"srcFile, destFile string, horizontal bool, f Format"},{"Uniquefunname":"func doRotateImage(srcFile, destFile string, angle GdkPixbufRotation, f Format) (err error)","Funname":"doRotateImage","Returntype":"(err error)","Args":"srcFile, destFile string, angle GdkPixbufRotation, f Format"},{"Uniquefunname":"func ClipImage(srcFile, destFile string, srcX, srcY, width, height int, f Format) (err error)","Funname":"gdkpixbuf.ClipImage","Returntype":"(err error)","Args":"srcFile, destFile string, srcX, srcY, width, height int, f Format"},{"Uniquefunname":"func ConvertImage(srcFile, destFile string, f Format) (err error)","Funname":"gdkpixbuf.ConvertImage","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func ConvertImageToXpixmap(imgFile string) (xpixmap x.Pixmap, err error)","Funname":"gdkpixbuf.ConvertImageToXpixmap","Returntype":"(xpixmap x.Pixmap, err error)","Args":"imgFile string"},{"Uniquefunname":"func ConvertPixbufToXpixmap(pixbuf *C.GdkPixbuf) (xpixmap x.Pixmap, err error)","Funname":"gdkpixbuf.ConvertPixbufToXpixmap","Returntype":"(xpixmap x.Pixmap, err error)","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func gdkpixbuf.ConvertXpixmapToPixbuf(xpixmap x.Pixmap, width, height int)(pixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.ConvertXpixmapToPixbuf","Returntype":"(pixbuf *C.GdkPixbuf, err error)","Args":"xpixmap x.Pixmap, width, height int"},{"Uniquefunname":"func gdkpixbuf.CopyArea(srcPixbuf, destPixbuf *C.GdkPixbuf, srcX, srcY, width, height, destX, destY int)(err error)","Funname":"gdkpixbuf.CopyArea","Returntype":"(err error)","Args":"srcPixbuf, destPixbuf *C.GdkPixbuf, srcX, srcY, width, height, destX, destY int"},{"Uniquefunname":"func gdkpixbuf.CopyAreaSimple(srcPixbuf *C.GdkPixbuf, srcX, srcY, width, height int)(destPixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.CopyAreaSimple","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, srcX, srcY, width, height int"},{"Uniquefunname":"func Flip(srcPixbuf *C.GdkPixbuf, horizontal bool) (destPixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.Flip","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, horizontal bool"},{"Uniquefunname":"func FlipImageHorizontal(srcFile, destFile string, f Format) (err error)","Funname":"gdkpixbuf.FlipImageHorizontal","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func FlipImageVertical(srcFile, destFile string, f Format) (err error)","Funname":"gdkpixbuf.FlipImageVertical","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func FreePixbuf(pixbuf *C.GdkPixbuf)","Funname":"gdkpixbuf.FreePixbuf","Returntype":"","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func GetDominantColor(pixbuf *C.GdkPixbuf) (h, s, v float64, err error)","Funname":"gdkpixbuf.GetDominantColor","Returntype":"(h, s, v float64, err error)","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func GetDominantColorOfImage(imgFile string) (h, s, v float64, err error)","Funname":"gdkpixbuf.GetDominantColorOfImage","Returntype":"(h, s, v float64, err error)","Args":"imgFile string"},{"Uniquefunname":"func GetImageFormat(imgFile string) (f Format, err error)","Funname":"gdkpixbuf.GetImageFormat","Returntype":"(f Format, err error)","Args":"imgFile string"},{"Uniquefunname":"func GetImageSize(imgFile string) (w, h int, err error)","Funname":"gdkpixbuf.GetImageSize","Returntype":"(w, h int, err error)","Args":"imgFile string"},{"Uniquefunname":"func GetPixels(pixbuf *C.GdkPixbuf) []byte","Funname":"gdkpixbuf.GetPixels","Returntype":"[]byte","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func GetSize(pixbuf *C.GdkPixbuf) (w, h int, err error)","Funname":"gdkpixbuf.GetSize","Returntype":"(w, h int, err error)","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func InitGdk() (err error)","Funname":"gdkpixbuf.InitGdk","Returntype":"(err error)","Args":""},{"Uniquefunname":"func InitGdkXlib() (err error)","Funname":"gdkpixbuf.InitGdkXlib","Returntype":"(err error)","Args":""},{"Uniquefunname":"func IsSupportedImage(imgFile string) bool","Funname":"gdkpixbuf.IsSupportedImage","Returntype":"bool","Args":"imgFile string"},{"Uniquefunname":"func NewPixbufFromFile(imgFile string) (pixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.NewPixbufFromFile","Returntype":"(pixbuf *C.GdkPixbuf, err error)","Args":"imgFile string"},{"Uniquefunname":"func RotateImageLeft(srcFile, destFile string, f Format) (err error)","Funname":"gdkpixbuf.RotateImageLeft","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func RotateImageRight(srcFile, destFile string, f Format) (err error)","Funname":"gdkpixbuf.RotateImageRight","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func RotateImageUpsizedown(srcFile, destFile string, f Format) (err error)","Funname":"gdkpixbuf.RotateImageUpsizedown","Returntype":"(err error)","Args":"srcFile, destFile string, f Format"},{"Uniquefunname":"func gdkpixbuf.RotateSimple(srcPixbuf *C.GdkPixbuf, angle GdkPixbufRotation)(destPixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.RotateSimple","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, angle GdkPixbufRotation"},{"Uniquefunname":"func Save(pixbuf *C.GdkPixbuf, destFile string, f Format) (err error)","Funname":"gdkpixbuf.Save","Returntype":"(err error)","Args":"pixbuf *C.GdkPixbuf, destFile string, f Format"},{"Uniquefunname":"func gdkpixbuf.ScaleImage(srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format)(err error)","Funname":"gdkpixbuf.ScaleImage","Returntype":"(err error)","Args":"srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func gdkpixbuf.ScaleImageCache(srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format)(destFile string, useCache bool, err error)","Funname":"gdkpixbuf.ScaleImageCache","Returntype":"(destFile string, useCache bool, err error)","Args":"srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func gdkpixbuf.ScaleImagePrefer(srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format)(err error)","Funname":"gdkpixbuf.ScaleImagePrefer","Returntype":"(err error)","Args":"srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func gdkpixbuf.ScaleImagePreferCache(srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format)(destFile string, useCache bool, err error)","Funname":"gdkpixbuf.ScaleImagePreferCache","Returntype":"(destFile string, useCache bool, err error)","Args":"srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func gdkpixbuf.ScalePrefer(srcPixbuf *C.GdkPixbuf, newWidth, newHeight int, interpType GdkInterpType)(destPixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.ScalePrefer","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, newWidth, newHeight int, interpType GdkInterpType"},{"Uniquefunname":"func gdkpixbuf.ScaleSimple(srcPixbuf *C.GdkPixbuf, newWidth, newHeght int, interpType GdkInterpType)(destPixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.ScaleSimple","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, newWidth, newHeght int, interpType GdkInterpType"},{"Uniquefunname":"func Screenshot() (pixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.Screenshot","Returntype":"(pixbuf *C.GdkPixbuf, err error)","Args":""},{"Uniquefunname":"func ScreenshotImage(file string, f Format) (err error)","Funname":"gdkpixbuf.ScreenshotImage","Returntype":"(err error)","Args":"file string, f Format"},{"Uniquefunname":"func gdkpixbuf.Thumbnail(srcPixbuf *C.GdkPixbuf, maxWidth, maxHeight int, interpType GdkInterpType)(destPixbuf *C.GdkPixbuf, err error)","Funname":"gdkpixbuf.Thumbnail","Returntype":"(destPixbuf *C.GdkPixbuf, err error)","Args":"srcPixbuf *C.GdkPixbuf, maxWidth, maxHeight int, interpType GdkInterpType"},{"Uniquefunname":"func gdkpixbuf.ThumbnailImage(srcFile, destFile string, maxWidth, maxHeight int, interpType GdkInterpType, f Format)(err error)","Funname":"gdkpixbuf.ThumbnailImage","Returntype":"(err error)","Args":"srcFile, destFile string, maxWidth, maxHeight int, interpType GdkInterpType, f Format"},{"Uniquefunname":"func ToImage(pixbuf *C.GdkPixbuf) (image.Image, error)","Funname":"gdkpixbuf.ToImage","Returntype":"(image.Image, error)","Args":"pixbuf *C.GdkPixbuf"},{"Uniquefunname":"func doFlipImage(srcFile, destFile string, horizontal bool, f Format) (err error)","Funname":"gdkpixbuf.doFlipImage","Returntype":"(err error)","Args":"srcFile, destFile string, horizontal bool, f Format"},{"Uniquefunname":"func doRotateImage(srcFile, destFile string, angle GdkPixbufRotation, f Format) (err error)","Funname":"gdkpixbuf.doRotateImage","Returntype":"(err error)","Args":"srcFile, destFile string, angle GdkPixbufRotation, f Format"}],"Records":[{"Name":"const:gdkpixbuf","Fields":["gdkpixbuf.FormatBmp","gdkpixbuf.FormatIco","gdkpixbuf.FormatJpeg","gdkpixbuf.FormatPng","gdkpixbuf.FormatTiff"]}]} {"Filepath":"gdkpixbuf/gdkpixbuf_test.go","Functions":[{"Uniquefunname":"func (*testWrapper) BenchmarkBlurImage(c *C.C)","Funname":"BenchmarkBlurImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) ManualTestScreenshotImage(c *C.C)","Funname":"ManualTestScreenshotImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestBlurImage(c *C.C)","Funname":"TestBlurImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestBlurImageCache(c *C.C)","Funname":"TestBlurImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestClipImage(c *C.C)","Funname":"TestClipImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestConvertImage(c *C.C)","Funname":"TestConvertImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestFlipImageHorizontal(c *C.C)","Funname":"TestFlipImageHorizontal","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestFlipImageVertical(c *C.C)","Funname":"TestFlipImageVertical","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetDominantColor(c *C.C)","Funname":"TestGetDominantColor","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetImageFormat(c *C.C)","Funname":"TestGetImageFormat","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetImageSize(c *C.C)","Funname":"TestGetImageSize","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsSupportedImage(c *C.C)","Funname":"TestIsSupportedImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestRotateImageLeft(c *C.C)","Funname":"TestRotateImageLeft","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestRotateImageRight(c *C.C)","Funname":"TestRotateImageRight","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestRotateImageUpsizedown(c *C.C)","Funname":"TestRotateImageUpsizedown","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestScaleImage(c *C.C)","Funname":"TestScaleImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestScaleImageCache(c *C.C)","Funname":"TestScaleImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestScaleImagePrefer(c *C.C)","Funname":"TestScaleImagePrefer","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestScaleImagePreferCache(c *C.C)","Funname":"TestScaleImagePreferCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestThumbnailImage(c *C.C)","Funname":"TestThumbnailImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func delta(x, y float64) float64","Funname":"delta","Returntype":"float64","Args":"x, y float64"},{"Uniquefunname":"func gdkpixbuf.Test(t *testing.T)","Funname":"gdkpixbuf.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func delta(x, y float64) float64","Funname":"gdkpixbuf.delta","Returntype":"float64","Args":"x, y float64"},{"Uniquefunname":"func (*testWrapper) BenchmarkBlurImage(c *C.C)","Funname":"gdkpixbuf.testWrapper.BenchmarkBlurImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) ManualTestScreenshotImage(c *C.C)","Funname":"gdkpixbuf.testWrapper.ManualTestScreenshotImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestBlurImage(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestBlurImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestBlurImageCache(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestBlurImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestClipImage(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestClipImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestConvertImage(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestConvertImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestFlipImageHorizontal(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestFlipImageHorizontal","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestFlipImageVertical(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestFlipImageVertical","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetDominantColor(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestGetDominantColor","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetImageFormat(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestGetImageFormat","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetImageSize(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestGetImageSize","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsSupportedImage(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestIsSupportedImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestRotateImageLeft(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestRotateImageLeft","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestRotateImageRight(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestRotateImageRight","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestRotateImageUpsizedown(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestRotateImageUpsizedown","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestScaleImage(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestScaleImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestScaleImageCache(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestScaleImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestScaleImagePrefer(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestScaleImagePrefer","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestScaleImagePreferCache(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestScaleImagePreferCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestThumbnailImage(c *C.C)","Funname":"gdkpixbuf.testWrapper.TestThumbnailImage","Returntype":"","Args":"c *C.C"}],"Records":[{"Name":"var:gdkpixbuf","Fields":["gdkpixbuf._"]},{"Name":"const:gdkpixbuf","Fields":["gdkpixbuf.originImg","gdkpixbuf.originImgDominantColorH","gdkpixbuf.originImgDominantColorS","gdkpixbuf.originImgDominantColorV","gdkpixbuf.originImgHeight","gdkpixbuf.originImgIconBmp","gdkpixbuf.originImgIconGif","gdkpixbuf.originImgIconPng1","gdkpixbuf.originImgIconTxt","gdkpixbuf.originImgNotImage","gdkpixbuf.originImgPngSmall","gdkpixbuf.originImgWidth"]}]} {"Filepath":"gdkpixbuf/utils.go","Functions":[{"Uniquefunname":"func GetPreferScaleClipRect(refWidth, refHeight, imgWidth, imgHeight int)(x, y, w, h int, err error)","Funname":"GetPreferScaleClipRect","Returntype":"(x, y, w, h int, err error)","Args":"refWidth, refHeight, imgWidth, imgHeight int"},{"Uniquefunname":"func Hsv2Rgb(h, s, v float64) (r, g, b uint8)","Funname":"Hsv2Rgb","Returntype":"(r, g, b uint8)","Args":"h, s, v float64"},{"Uniquefunname":"func Rgb2Hsv(r, g, b uint8) (h, s, v float64)","Funname":"Rgb2Hsv","Returntype":"(h, s, v float64)","Args":"r, g, b uint8"},{"Uniquefunname":"func gdkpixbuf.GetPreferScaleClipRect(refWidth, refHeight, imgWidth, imgHeight int)(x, y, w, h int, err error)","Funname":"gdkpixbuf.GetPreferScaleClipRect","Returntype":"(x, y, w, h int, err error)","Args":"refWidth, refHeight, imgWidth, imgHeight int"},{"Uniquefunname":"func Hsv2Rgb(h, s, v float64) (r, g, b uint8)","Funname":"gdkpixbuf.Hsv2Rgb","Returntype":"(r, g, b uint8)","Args":"h, s, v float64"},{"Uniquefunname":"func Rgb2Hsv(r, g, b uint8) (h, s, v float64)","Funname":"gdkpixbuf.Rgb2Hsv","Returntype":"(h, s, v float64)","Args":"r, g, b uint8"},{"Uniquefunname":"func generateCacheFilePath(keyword string) string","Funname":"gdkpixbuf.generateCacheFilePath","Returntype":"string","Args":"keyword string"},{"Uniquefunname":"func generateCacheFilePath(keyword string) string","Funname":"generateCacheFilePath","Returntype":"string","Args":"keyword string"}],"Records":null} {"Filepath":"gettext/gettext.go","Functions":[{"Uniquefunname":"func Bindtextdomain(domain, dirname string) string","Funname":"Bindtextdomain","Returntype":"string","Args":"domain, dirname string"},{"Uniquefunname":"func DGettext(domain, id string) string","Funname":"DGettext","Returntype":"string","Args":"domain, id string"},{"Uniquefunname":"func DNGettext(domain, msgid, plural string, n int) string","Funname":"DNGettext","Returntype":"string","Args":"domain, msgid, plural string, n int"},{"Uniquefunname":"func InitI18n()","Funname":"InitI18n","Returntype":"","Args":""},{"Uniquefunname":"func NTr(msgid, plural string, n int) string","Funname":"NTr","Returntype":"string","Args":"msgid, plural string, n int"},{"Uniquefunname":"func QueryLang() string","Funname":"QueryLang","Returntype":"string","Args":""},{"Uniquefunname":"func QueryLangs() []string","Funname":"QueryLangs","Returntype":"[]string","Args":""},{"Uniquefunname":"func SetLocale(category int, locale string) string","Funname":"SetLocale","Returntype":"string","Args":"category int, locale string"},{"Uniquefunname":"func Textdomain(domain string)","Funname":"Textdomain","Returntype":"","Args":"domain string"},{"Uniquefunname":"func Tr(id string) string","Funname":"Tr","Returntype":"string","Args":"id string"},{"Uniquefunname":"func Bindtextdomain(domain, dirname string) string","Funname":"gettext.Bindtextdomain","Returntype":"string","Args":"domain, dirname string"},{"Uniquefunname":"func DGettext(domain, id string) string","Funname":"gettext.DGettext","Returntype":"string","Args":"domain, id string"},{"Uniquefunname":"func DNGettext(domain, msgid, plural string, n int) string","Funname":"gettext.DNGettext","Returntype":"string","Args":"domain, msgid, plural string, n int"},{"Uniquefunname":"func InitI18n()","Funname":"gettext.InitI18n","Returntype":"","Args":""},{"Uniquefunname":"func NTr(msgid, plural string, n int) string","Funname":"gettext.NTr","Returntype":"string","Args":"msgid, plural string, n int"},{"Uniquefunname":"func QueryLang() string","Funname":"gettext.QueryLang","Returntype":"string","Args":""},{"Uniquefunname":"func QueryLangs() []string","Funname":"gettext.QueryLangs","Returntype":"[]string","Args":""},{"Uniquefunname":"func SetLocale(category int, locale string) string","Funname":"gettext.SetLocale","Returntype":"string","Args":"category int, locale string"},{"Uniquefunname":"func Textdomain(domain string)","Funname":"gettext.Textdomain","Returntype":"","Args":"domain string"},{"Uniquefunname":"func Tr(id string) string","Funname":"gettext.Tr","Returntype":"string","Args":"id string"}],"Records":[{"Name":"var:gettext","Fields":["gettext.LcAll","gettext.LcCollate","gettext.LcCtype","gettext.LcMessages","gettext.LcMonetary","gettext.LcNumeric","gettext.LcTime"]}]} {"Filepath":"gettext/gettext_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*gettext) TestDGettext(c *C.C)","Funname":"TestDGettext","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestDNGettext(c *C.C)","Funname":"TestDNGettext","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestFailed(c *C.C)","Funname":"TestFailed","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestNTr(c *C.C)","Funname":"TestNTr","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestQueryLang(c *C.C)","Funname":"TestQueryLang","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestTr(c *C.C)","Funname":"TestTr","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func gettext.Test(t *testing.T)","Funname":"gettext.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*gettext) TestDGettext(c *C.C)","Funname":"gettext.gettext.TestDGettext","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestDNGettext(c *C.C)","Funname":"gettext.gettext.TestDNGettext","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestFailed(c *C.C)","Funname":"gettext.gettext.TestFailed","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestNTr(c *C.C)","Funname":"gettext.gettext.TestNTr","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestQueryLang(c *C.C)","Funname":"gettext.gettext.TestQueryLang","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*gettext) TestTr(c *C.C)","Funname":"gettext.gettext.TestTr","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"gettext.init","Returntype":"","Args":""},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""}],"Records":null} {"Filepath":"gettext/testdata/plural/t.go","Functions":[{"Uniquefunname":"func main()","Funname":"main","Returntype":"","Args":""},{"Uniquefunname":"func main()","Funname":"main.main","Returntype":"","Args":""}],"Records":null} {"Filepath":"graphic/clip.go","Functions":[{"Uniquefunname":"func Clip(srcimg image.Image, x, y, w, h int) (dstimg *image.RGBA)","Funname":"Clip","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, x, y, w, h int"},{"Uniquefunname":"func ClipImage(srcfile, dstfile string, x, y, w, h int, f Format) (err error)","Funname":"ClipImage","Returntype":"(err error)","Args":"srcfile, dstfile string, x, y, w, h int, f Format"},{"Uniquefunname":"func ClipImageCache(srcfile string, x, y, w, h int, f Format)(dstfile string, useCache bool, err error)","Funname":"ClipImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, x, y, w, h int, f Format"},{"Uniquefunname":"func Clip(srcimg image.Image, x, y, w, h int) (dstimg *image.RGBA)","Funname":"graphic.Clip","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, x, y, w, h int"},{"Uniquefunname":"func ClipImage(srcfile, dstfile string, x, y, w, h int, f Format) (err error)","Funname":"graphic.ClipImage","Returntype":"(err error)","Args":"srcfile, dstfile string, x, y, w, h int, f Format"},{"Uniquefunname":"func graphic.ClipImageCache(srcfile string, x, y, w, h int, f Format)(dstfile string, useCache bool, err error)","Funname":"graphic.ClipImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, x, y, w, h int, f Format"}],"Records":null} {"Filepath":"graphic/composite.go","Functions":[{"Uniquefunname":"func Composite(dstimg draw.Image, compimg image.Image, x, y int)","Funname":"Composite","Returntype":"","Args":"dstimg draw.Image, compimg image.Image, x, y int"},{"Uniquefunname":"func CompositeImage(srcfile, compfile, dstfile string, x, y int, f Format) (err error)","Funname":"CompositeImage","Returntype":"(err error)","Args":"srcfile, compfile, dstfile string, x, y int, f Format"},{"Uniquefunname":"func CompositeImageSet(srcfile string, compinfos []CompositeInfo, dstfile string, f Format)(err error)","Funname":"CompositeImageSet","Returntype":"(err error)","Args":"srcfile string, compinfos []CompositeInfo, dstfile string, f Format"},{"Uniquefunname":"func CompositeImageUri(srcDatauri, compDataUri string, x, y int, f Format)(dstDataUri string, err error)","Funname":"CompositeImageUri","Returntype":"(dstDataUri string, err error)","Args":"srcDatauri, compDataUri string, x, y int, f Format"},{"Uniquefunname":"func Len()int","Funname":"Len","Returntype":"int","Args":""},{"Uniquefunname":"func Less(i, j int)bool","Funname":"Less","Returntype":"bool","Args":"i, j int"},{"Uniquefunname":"func Swap(i, j int)","Funname":"Swap","Returntype":"","Args":"i, j int"},{"Uniquefunname":"func Composite(dstimg draw.Image, compimg image.Image, x, y int)","Funname":"graphic.Composite","Returntype":"","Args":"dstimg draw.Image, compimg image.Image, x, y int"},{"Uniquefunname":"func CompositeImage(srcfile, compfile, dstfile string, x, y int, f Format) (err error)","Funname":"graphic.CompositeImage","Returntype":"(err error)","Args":"srcfile, compfile, dstfile string, x, y int, f Format"},{"Uniquefunname":"func graphic.CompositeImageSet(srcfile string, compinfos []CompositeInfo, dstfile string, f Format)(err error)","Funname":"graphic.CompositeImageSet","Returntype":"(err error)","Args":"srcfile string, compinfos []CompositeInfo, dstfile string, f Format"},{"Uniquefunname":"func graphic.CompositeImageUri(srcDatauri, compDataUri string, x, y int, f Format)(dstDataUri string, err error)","Funname":"graphic.CompositeImageUri","Returntype":"(dstDataUri string, err error)","Args":"srcDatauri, compDataUri string, x, y int, f Format"},{"Uniquefunname":"func graphic.compositeInfoSorter.Len()int","Funname":"graphic.compositeInfoSorter.Len","Returntype":"int","Args":""},{"Uniquefunname":"func graphic.compositeInfoSorter.Less(i, j int)bool","Funname":"graphic.compositeInfoSorter.Less","Returntype":"bool","Args":"i, j int"},{"Uniquefunname":"func graphic.compositeInfoSorter.Swap(i, j int)","Funname":"graphic.compositeInfoSorter.Swap","Returntype":"","Args":"i, j int"}],"Records":[{"Name":"struct:graphic.CompositeInfo","Fields":["graphic.CompositeInfo.File string","graphic.CompositeInfo.X int","graphic.CompositeInfo.Y int","graphic.CompositeInfo.Z int"]}]} {"Filepath":"graphic/convert.go","Functions":[{"Uniquefunname":"func ConvertImage(srcfile, dstfile string, f Format) (err error)","Funname":"ConvertImage","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func ConvertImageCache(srcfile string, f Format) (dstfile string, useCache bool, err error)","Funname":"ConvertImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, f Format"},{"Uniquefunname":"func ConvertImage(srcfile, dstfile string, f Format) (err error)","Funname":"graphic.ConvertImage","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func ConvertImageCache(srcfile string, f Format) (dstfile string, useCache bool, err error)","Funname":"graphic.ConvertImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, f Format"}],"Records":null} {"Filepath":"graphic/data_uri.go","Functions":[{"Uniquefunname":"func ConvertDataUriToImage(dataUri string, dstfile string, f Format) (err error)","Funname":"ConvertDataUriToImage","Returntype":"(err error)","Args":"dataUri string, dstfile string, f Format"},{"Uniquefunname":"func ConvertImageObjectToDataUri(img image.Image, f Format) (dataUri string, err error)","Funname":"ConvertImageObjectToDataUri","Returntype":"(dataUri string, err error)","Args":"img image.Image, f Format"},{"Uniquefunname":"func ConvertImageToDataUri(imgfile string) (dataUri string, err error)","Funname":"ConvertImageToDataUri","Returntype":"(dataUri string, err error)","Args":"imgfile string"},{"Uniquefunname":"func LoadImageFromDataUri(dataUri string) (img image.Image, err error)","Funname":"LoadImageFromDataUri","Returntype":"(img image.Image, err error)","Args":"dataUri string"},{"Uniquefunname":"func ConvertDataUriToImage(dataUri string, dstfile string, f Format) (err error)","Funname":"graphic.ConvertDataUriToImage","Returntype":"(err error)","Args":"dataUri string, dstfile string, f Format"},{"Uniquefunname":"func ConvertImageObjectToDataUri(img image.Image, f Format) (dataUri string, err error)","Funname":"graphic.ConvertImageObjectToDataUri","Returntype":"(dataUri string, err error)","Args":"img image.Image, f Format"},{"Uniquefunname":"func ConvertImageToDataUri(imgfile string) (dataUri string, err error)","Funname":"graphic.ConvertImageToDataUri","Returntype":"(dataUri string, err error)","Args":"imgfile string"},{"Uniquefunname":"func LoadImageFromDataUri(dataUri string) (img image.Image, err error)","Funname":"graphic.LoadImageFromDataUri","Returntype":"(img image.Image, err error)","Args":"dataUri string"},{"Uniquefunname":"func imageFormatToDataUriContentType(f Format) (contentType string)","Funname":"graphic.imageFormatToDataUriContentType","Returntype":"(contentType string)","Args":"f Format"},{"Uniquefunname":"func imageFormatToDataUriContentType(f Format) (contentType string)","Funname":"imageFormatToDataUriContentType","Returntype":"(contentType string)","Args":"f Format"}],"Records":null} {"Filepath":"graphic/dominant_color.go","Functions":[{"Uniquefunname":"func GetDominantColorOfImage(imgfile string) (h, s, v float64, err error)","Funname":"GetDominantColorOfImage","Returntype":"(h, s, v float64, err error)","Args":"imgfile string"},{"Uniquefunname":"func doGetDominantColorOfImage(img image.Image) (h, s, v float64, err error)","Funname":"doGetDominantColorOfImage","Returntype":"(h, s, v float64, err error)","Args":"img image.Image"},{"Uniquefunname":"func GetDominantColorOfImage(imgfile string) (h, s, v float64, err error)","Funname":"graphic.GetDominantColorOfImage","Returntype":"(h, s, v float64, err error)","Args":"imgfile string"},{"Uniquefunname":"func doGetDominantColorOfImage(img image.Image) (h, s, v float64, err error)","Funname":"graphic.doGetDominantColorOfImage","Returntype":"(h, s, v float64, err error)","Args":"img image.Image"}],"Records":null} {"Filepath":"graphic/fill.go","Functions":[{"Uniquefunname":"func Fill(srcimg image.Image, width, height int, style FillStyle)(dstimg *image.RGBA, err error)","Funname":"Fill","Returntype":"(dstimg *image.RGBA, err error)","Args":"srcimg image.Image, width, height int, style FillStyle"},{"Uniquefunname":"func FillImage(srcfile, dstfile string, width, height int, style FillStyle, f Format)(err error)","Funname":"FillImage","Returntype":"(err error)","Args":"srcfile, dstfile string, width, height int, style FillStyle, f Format"},{"Uniquefunname":"func FillImageCache(srcfile string, width, height int, style FillStyle, f Format)(dstfile string, useCache bool, err error)","Funname":"FillImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, width, height int, style FillStyle, f Format"},{"Uniquefunname":"func doFillImageInCenterStyle(srcimg image.Image, width, height int) (dstimg *image.RGBA)","Funname":"doFillImageInCenterStyle","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, width, height int"},{"Uniquefunname":"func doFillImageInTileStyle(srcimg image.Image, width, height int) (dstimg *image.RGBA)","Funname":"doFillImageInTileStyle","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, width, height int"},{"Uniquefunname":"func graphic.Fill(srcimg image.Image, width, height int, style FillStyle)(dstimg *image.RGBA, err error)","Funname":"graphic.Fill","Returntype":"(dstimg *image.RGBA, err error)","Args":"srcimg image.Image, width, height int, style FillStyle"},{"Uniquefunname":"func graphic.FillImage(srcfile, dstfile string, width, height int, style FillStyle, f Format)(err error)","Funname":"graphic.FillImage","Returntype":"(err error)","Args":"srcfile, dstfile string, width, height int, style FillStyle, f Format"},{"Uniquefunname":"func graphic.FillImageCache(srcfile string, width, height int, style FillStyle, f Format)(dstfile string, useCache bool, err error)","Funname":"graphic.FillImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, width, height int, style FillStyle, f Format"},{"Uniquefunname":"func doFillImageInCenterStyle(srcimg image.Image, width, height int) (dstimg *image.RGBA)","Funname":"graphic.doFillImageInCenterStyle","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, width, height int"},{"Uniquefunname":"func doFillImageInTileStyle(srcimg image.Image, width, height int) (dstimg *image.RGBA)","Funname":"graphic.doFillImageInTileStyle","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, width, height int"}],"Records":[{"Name":"const:graphic","Fields":["graphic.FillCenter","graphic.FillTile"]}]} {"Filepath":"graphic/flip.go","Functions":[{"Uniquefunname":"func FlipImageHorizontal(srcfile, dstfile string, f Format) (err error)","Funname":"FlipImageHorizontal","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func FlipImageVertical(srcfile, dstfile string, f Format) (err error)","Funname":"FlipImageVertical","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func doFlipImageHorizontal(srcimg image.Image) (dstimg *image.RGBA)","Funname":"doFlipImageHorizontal","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image"},{"Uniquefunname":"func doFlipImageVertical(srcimg image.Image) (dstimg *image.RGBA)","Funname":"doFlipImageVertical","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image"},{"Uniquefunname":"func FlipImageHorizontal(srcfile, dstfile string, f Format) (err error)","Funname":"graphic.FlipImageHorizontal","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func FlipImageVertical(srcfile, dstfile string, f Format) (err error)","Funname":"graphic.FlipImageVertical","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func doFlipImageHorizontal(srcimg image.Image) (dstimg *image.RGBA)","Funname":"graphic.doFlipImageHorizontal","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image"},{"Uniquefunname":"func doFlipImageVertical(srcimg image.Image) (dstimg *image.RGBA)","Funname":"graphic.doFlipImageVertical","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image"}],"Records":null} {"Filepath":"graphic/format_sniff.go","Functions":[{"Uniquefunname":"func SniffImageFormat(file string) (string, error)","Funname":"SniffImageFormat","Returntype":"(string, error)","Args":"file string"},{"Uniquefunname":"func SniffImageFormat(file string) (string, error)","Funname":"graphic.SniffImageFormat","Returntype":"(string, error)","Args":"file string"},{"Uniquefunname":"func match(magic string, b []byte) bool","Funname":"graphic.match","Returntype":"bool","Args":"magic string, b []byte"},{"Uniquefunname":"func sniff(r *bufio.Reader) format","Funname":"graphic.sniff","Returntype":"format","Args":"r *bufio.Reader"},{"Uniquefunname":"func match(magic string, b []byte) bool","Funname":"match","Returntype":"bool","Args":"magic string, b []byte"},{"Uniquefunname":"func sniff(r *bufio.Reader) format","Funname":"sniff","Returntype":"format","Args":"r *bufio.Reader"}],"Records":[{"Name":"struct:graphic.format","Fields":["graphic.format.magic string","graphic.format.name string"]},{"Name":"var:graphic","Fields":["graphic.formats"]}]} {"Filepath":"graphic/graphic.go","Functions":null,"Records":[{"Name":"const:graphic","Fields":["graphic.FormatBmp","graphic.FormatJpeg","graphic.FormatPng","graphic.FormatTiff"]}]} {"Filepath":"graphic/graphic_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (g *testWrapper) TestClipImage(c *C.C)","Funname":"TestClipImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestCompositeImage(c *C.C)","Funname":"TestCompositeImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestCompositeImageSet(c *C.C)","Funname":"TestCompositeImageSet","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestCompositeImageUri(c *C.C)","Funname":"TestCompositeImageUri","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestConvertDataUriToImage(c *C.C)","Funname":"TestConvertDataUriToImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestConvertImage(c *C.C)","Funname":"TestConvertImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestConvertImageToDataUri(c *C.C)","Funname":"TestConvertImageToDataUri","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestFillImage(c *C.C)","Funname":"TestFillImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestFillImageCache(c *C.C)","Funname":"TestFillImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestFlipImageHorizontal(c *C.C)","Funname":"TestFlipImageHorizontal","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestFlipImageVertical(c *C.C)","Funname":"TestFlipImageVertical","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestGetDominantColor(c *C.C)","Funname":"TestGetDominantColor","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetIcons(c *C.C)","Funname":"TestGetIcons","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestGetImageFormat(c *C.C)","Funname":"TestGetImageFormat","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestGetImageSize(c *C.C)","Funname":"TestGetImageSize","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetPreferScaleClipRect(c *C.C)","Funname":"TestGetPreferScaleClipRect","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestHsv(c *C.C)","Funname":"TestHsv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestIsSupportedImage(c *C.C)","Funname":"TestIsSupportedImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestLoadImage(c *C.C)","Funname":"TestLoadImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestLoadImageFromDataUri(c *C.C)","Funname":"TestLoadImageFromDataUri","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestNewImageWithColor(c *C.C)","Funname":"TestNewImageWithColor","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestRotateImageLeft(c *C.C)","Funname":"TestRotateImageLeft","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestRotateImageRight(c *C.C)","Funname":"TestRotateImageRight","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestScaleImage(c *C.C)","Funname":"TestScaleImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestScaleImageCache(c *C.C)","Funname":"TestScaleImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestScaleImagePrefer(c *C.C)","Funname":"TestScaleImagePrefer","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestSniffImageFormat(c *C.C)","Funname":"TestSniffImageFormat","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestThumbnailImage(c *C.C)","Funname":"TestThumbnailImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestThumbnailImageCache(c *C.C)","Funname":"TestThumbnailImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func delta(x, y float64) float64","Funname":"delta","Returntype":"float64","Args":"x, y float64"},{"Uniquefunname":"func graphic.Test(t *testing.T)","Funname":"graphic.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func delta(x, y float64) float64","Funname":"graphic.delta","Returntype":"float64","Args":"x, y float64"},{"Uniquefunname":"func (g *testWrapper) TestClipImage(c *C.C)","Funname":"graphic.testWrapper.TestClipImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestCompositeImage(c *C.C)","Funname":"graphic.testWrapper.TestCompositeImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestCompositeImageSet(c *C.C)","Funname":"graphic.testWrapper.TestCompositeImageSet","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestCompositeImageUri(c *C.C)","Funname":"graphic.testWrapper.TestCompositeImageUri","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestConvertDataUriToImage(c *C.C)","Funname":"graphic.testWrapper.TestConvertDataUriToImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestConvertImage(c *C.C)","Funname":"graphic.testWrapper.TestConvertImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestConvertImageToDataUri(c *C.C)","Funname":"graphic.testWrapper.TestConvertImageToDataUri","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestFillImage(c *C.C)","Funname":"graphic.testWrapper.TestFillImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestFillImageCache(c *C.C)","Funname":"graphic.testWrapper.TestFillImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestFlipImageHorizontal(c *C.C)","Funname":"graphic.testWrapper.TestFlipImageHorizontal","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestFlipImageVertical(c *C.C)","Funname":"graphic.testWrapper.TestFlipImageVertical","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestGetDominantColor(c *C.C)","Funname":"graphic.testWrapper.TestGetDominantColor","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetIcons(c *C.C)","Funname":"graphic.testWrapper.TestGetIcons","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestGetImageFormat(c *C.C)","Funname":"graphic.testWrapper.TestGetImageFormat","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestGetImageSize(c *C.C)","Funname":"graphic.testWrapper.TestGetImageSize","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetPreferScaleClipRect(c *C.C)","Funname":"graphic.testWrapper.TestGetPreferScaleClipRect","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestHsv(c *C.C)","Funname":"graphic.testWrapper.TestHsv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestIsSupportedImage(c *C.C)","Funname":"graphic.testWrapper.TestIsSupportedImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestLoadImage(c *C.C)","Funname":"graphic.testWrapper.TestLoadImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestLoadImageFromDataUri(c *C.C)","Funname":"graphic.testWrapper.TestLoadImageFromDataUri","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestNewImageWithColor(c *C.C)","Funname":"graphic.testWrapper.TestNewImageWithColor","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestRotateImageLeft(c *C.C)","Funname":"graphic.testWrapper.TestRotateImageLeft","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestRotateImageRight(c *C.C)","Funname":"graphic.testWrapper.TestRotateImageRight","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestScaleImage(c *C.C)","Funname":"graphic.testWrapper.TestScaleImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestScaleImageCache(c *C.C)","Funname":"graphic.testWrapper.TestScaleImageCache","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestScaleImagePrefer(c *C.C)","Funname":"graphic.testWrapper.TestScaleImagePrefer","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestSniffImageFormat(c *C.C)","Funname":"graphic.testWrapper.TestSniffImageFormat","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestThumbnailImage(c *C.C)","Funname":"graphic.testWrapper.TestThumbnailImage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (g *testWrapper) TestThumbnailImageCache(c *C.C)","Funname":"graphic.testWrapper.TestThumbnailImageCache","Returntype":"","Args":"c *C.C"}],"Records":[{"Name":"var:graphic","Fields":["graphic._"]},{"Name":"const:graphic","Fields":["graphic.originIconHeight","graphic.originIconWidth","graphic.originImg","graphic.originImgDominantColorH","graphic.originImgDominantColorS","graphic.originImgDominantColorV","graphic.originImgHeight","graphic.originImgNotImage","graphic.originImgPngIcon1","graphic.originImgPngIcon2","graphic.originImgPngSmall","graphic.originImgWidth","graphic.testDataUri"]}]} {"Filepath":"graphic/hsv.go","Functions":[{"Uniquefunname":"func Hsv2Rgb(h, s, v float64) (r, g, b uint8)","Funname":"Hsv2Rgb","Returntype":"(r, g, b uint8)","Args":"h, s, v float64"},{"Uniquefunname":"func Rgb2Hsv(r, g, b uint8) (h, s, v float64)","Funname":"Rgb2Hsv","Returntype":"(h, s, v float64)","Args":"r, g, b uint8"},{"Uniquefunname":"func Hsv2Rgb(h, s, v float64) (r, g, b uint8)","Funname":"graphic.Hsv2Rgb","Returntype":"(r, g, b uint8)","Args":"h, s, v float64"},{"Uniquefunname":"func Rgb2Hsv(r, g, b uint8) (h, s, v float64)","Funname":"graphic.Rgb2Hsv","Returntype":"(h, s, v float64)","Args":"r, g, b uint8"}],"Records":null} {"Filepath":"graphic/info.go","Functions":[{"Uniquefunname":"func GetImageFormat(imgfile string) (format Format, err error)","Funname":"GetImageFormat","Returntype":"(format Format, err error)","Args":"imgfile string"},{"Uniquefunname":"func GetImageSize(imgfile string) (w, h int, err error)","Funname":"GetImageSize","Returntype":"(w, h int, err error)","Args":"imgfile string"},{"Uniquefunname":"func GetImagesInDir(dir string) ([]string, error)","Funname":"GetImagesInDir","Returntype":"([]string, error)","Args":"dir string"},{"Uniquefunname":"func GetSize(img image.Image) (w, h int)","Funname":"GetSize","Returntype":"(w, h int)","Args":"img image.Image"},{"Uniquefunname":"func IsSupportedImage(imgfile string) bool","Funname":"IsSupportedImage","Returntype":"bool","Args":"imgfile string"},{"Uniquefunname":"func GetImageFormat(imgfile string) (format Format, err error)","Funname":"graphic.GetImageFormat","Returntype":"(format Format, err error)","Args":"imgfile string"},{"Uniquefunname":"func GetImageSize(imgfile string) (w, h int, err error)","Funname":"graphic.GetImageSize","Returntype":"(w, h int, err error)","Args":"imgfile string"},{"Uniquefunname":"func GetImagesInDir(dir string) ([]string, error)","Funname":"graphic.GetImagesInDir","Returntype":"([]string, error)","Args":"dir string"},{"Uniquefunname":"func GetSize(img image.Image) (w, h int)","Funname":"graphic.GetSize","Returntype":"(w, h int)","Args":"img image.Image"},{"Uniquefunname":"func IsSupportedImage(imgfile string) bool","Funname":"graphic.IsSupportedImage","Returntype":"bool","Args":"imgfile string"}],"Records":null} {"Filepath":"graphic/new.go","Functions":[{"Uniquefunname":"func NewImageWithColor(dstfile string, width, height int, r, g, b, a uint8, f Format)(err error)","Funname":"NewImageWithColor","Returntype":"(err error)","Args":"dstfile string, width, height int, r, g, b, a uint8, f Format"},{"Uniquefunname":"func NewWithColor(width, height int, r, g, b, a uint8) (dstimg *image.RGBA, err error)","Funname":"NewWithColor","Returntype":"(dstimg *image.RGBA, err error)","Args":"width, height int, r, g, b, a uint8"},{"Uniquefunname":"func graphic.NewImageWithColor(dstfile string, width, height int, r, g, b, a uint8, f Format)(err error)","Funname":"graphic.NewImageWithColor","Returntype":"(err error)","Args":"dstfile string, width, height int, r, g, b, a uint8, f Format"},{"Uniquefunname":"func NewWithColor(width, height int, r, g, b, a uint8) (dstimg *image.RGBA, err error)","Funname":"graphic.NewWithColor","Returntype":"(dstimg *image.RGBA, err error)","Args":"width, height int, r, g, b, a uint8"}],"Records":null} {"Filepath":"graphic/rotate.go","Functions":[{"Uniquefunname":"func RotateImageLeft(srcfile, dstfile string, f Format) (err error)","Funname":"RotateImageLeft","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func RotateImageRight(srcfile, dstfile string, f Format) (err error)","Funname":"RotateImageRight","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func doRotateImageLeft(srcimg image.Image) (dstimg *image.RGBA)","Funname":"doRotateImageLeft","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image"},{"Uniquefunname":"func doRotateImageRight(srcimg image.Image) (dstimg *image.RGBA)","Funname":"doRotateImageRight","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image"},{"Uniquefunname":"func RotateImageLeft(srcfile, dstfile string, f Format) (err error)","Funname":"graphic.RotateImageLeft","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func RotateImageRight(srcfile, dstfile string, f Format) (err error)","Funname":"graphic.RotateImageRight","Returntype":"(err error)","Args":"srcfile, dstfile string, f Format"},{"Uniquefunname":"func doRotateImageLeft(srcimg image.Image) (dstimg *image.RGBA)","Funname":"graphic.doRotateImageLeft","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image"},{"Uniquefunname":"func doRotateImageRight(srcimg image.Image) (dstimg *image.RGBA)","Funname":"graphic.doRotateImageRight","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image"}],"Records":null} {"Filepath":"graphic/save_load.go","Functions":[{"Uniquefunname":"func LoadImage(imgfile string) (img image.Image, err error)","Funname":"LoadImage","Returntype":"(img image.Image, err error)","Args":"imgfile string"},{"Uniquefunname":"func SaveImage(dstfile string, m image.Image, f Format) (err error)","Funname":"SaveImage","Returntype":"(err error)","Args":"dstfile string, m image.Image, f Format"},{"Uniquefunname":"func doSaveImage(w io.Writer, m image.Image, f Format) (err error)","Funname":"doSaveImage","Returntype":"(err error)","Args":"w io.Writer, m image.Image, f Format"},{"Uniquefunname":"func LoadImage(imgfile string) (img image.Image, err error)","Funname":"graphic.LoadImage","Returntype":"(img image.Image, err error)","Args":"imgfile string"},{"Uniquefunname":"func SaveImage(dstfile string, m image.Image, f Format) (err error)","Funname":"graphic.SaveImage","Returntype":"(err error)","Args":"dstfile string, m image.Image, f Format"},{"Uniquefunname":"func doSaveImage(w io.Writer, m image.Image, f Format) (err error)","Funname":"graphic.doSaveImage","Returntype":"(err error)","Args":"w io.Writer, m image.Image, f Format"}],"Records":null} {"Filepath":"graphic/scale.go","Functions":[{"Uniquefunname":"func GetPreferScaleClipRect(refWidth, refHeight, imgWidth, imgHeight int)(x, y, w, h int, err error)","Funname":"GetPreferScaleClipRect","Returntype":"(x, y, w, h int, err error)","Args":"refWidth, refHeight, imgWidth, imgHeight int"},{"Uniquefunname":"func Scale(srcimg image.Image, newWidth, newHeight int) (dstimg *image.RGBA)","Funname":"Scale","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, newWidth, newHeight int"},{"Uniquefunname":"func ScaleImage(srcfile, dstfile string, newWidth, newHeight int, f Format) (err error)","Funname":"ScaleImage","Returntype":"(err error)","Args":"srcfile, dstfile string, newWidth, newHeight int, f Format"},{"Uniquefunname":"func ScaleImageCache(srcfile string, newWidth, newHeight int, f Format)(dstfile string, useCache bool, err error)","Funname":"ScaleImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, newWidth, newHeight int, f Format"},{"Uniquefunname":"func ScaleImagePrefer(srcfile, dstfile string, newWidth, newHeight int, f Format) (err error)","Funname":"ScaleImagePrefer","Returntype":"(err error)","Args":"srcfile, dstfile string, newWidth, newHeight int, f Format"},{"Uniquefunname":"func ScalePrefer(srcimg image.Image, newWidth, newHeight int) (dstimg *image.RGBA, err error)","Funname":"ScalePrefer","Returntype":"(dstimg *image.RGBA, err error)","Args":"srcimg image.Image, newWidth, newHeight int"},{"Uniquefunname":"func Thumbnail(srcimg image.Image, maxWidth, maxHeight int) (dstimg *image.RGBA)","Funname":"Thumbnail","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, maxWidth, maxHeight int"},{"Uniquefunname":"func ThumbnailImage(srcfile, dstfile string, maxWidth, maxHeight int, f Format) (err error)","Funname":"ThumbnailImage","Returntype":"(err error)","Args":"srcfile, dstfile string, maxWidth, maxHeight int, f Format"},{"Uniquefunname":"func ThumbnailImageCache(srcfile string, maxWidth, maxHeight int, f Format)(dstfile string, useCache bool, err error)","Funname":"ThumbnailImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, maxWidth, maxHeight int, f Format"},{"Uniquefunname":"func doScaleNearestNeighbor(img image.Image, newWidth, newHeight int) (newimg *image.RGBA)","Funname":"doScaleNearestNeighbor","Returntype":"(newimg *image.RGBA)","Args":"img image.Image, newWidth, newHeight int"},{"Uniquefunname":"func graphic.GetPreferScaleClipRect(refWidth, refHeight, imgWidth, imgHeight int)(x, y, w, h int, err error)","Funname":"graphic.GetPreferScaleClipRect","Returntype":"(x, y, w, h int, err error)","Args":"refWidth, refHeight, imgWidth, imgHeight int"},{"Uniquefunname":"func Scale(srcimg image.Image, newWidth, newHeight int) (dstimg *image.RGBA)","Funname":"graphic.Scale","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, newWidth, newHeight int"},{"Uniquefunname":"func ScaleImage(srcfile, dstfile string, newWidth, newHeight int, f Format) (err error)","Funname":"graphic.ScaleImage","Returntype":"(err error)","Args":"srcfile, dstfile string, newWidth, newHeight int, f Format"},{"Uniquefunname":"func graphic.ScaleImageCache(srcfile string, newWidth, newHeight int, f Format)(dstfile string, useCache bool, err error)","Funname":"graphic.ScaleImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, newWidth, newHeight int, f Format"},{"Uniquefunname":"func ScaleImagePrefer(srcfile, dstfile string, newWidth, newHeight int, f Format) (err error)","Funname":"graphic.ScaleImagePrefer","Returntype":"(err error)","Args":"srcfile, dstfile string, newWidth, newHeight int, f Format"},{"Uniquefunname":"func ScalePrefer(srcimg image.Image, newWidth, newHeight int) (dstimg *image.RGBA, err error)","Funname":"graphic.ScalePrefer","Returntype":"(dstimg *image.RGBA, err error)","Args":"srcimg image.Image, newWidth, newHeight int"},{"Uniquefunname":"func Thumbnail(srcimg image.Image, maxWidth, maxHeight int) (dstimg *image.RGBA)","Funname":"graphic.Thumbnail","Returntype":"(dstimg *image.RGBA)","Args":"srcimg image.Image, maxWidth, maxHeight int"},{"Uniquefunname":"func ThumbnailImage(srcfile, dstfile string, maxWidth, maxHeight int, f Format) (err error)","Funname":"graphic.ThumbnailImage","Returntype":"(err error)","Args":"srcfile, dstfile string, maxWidth, maxHeight int, f Format"},{"Uniquefunname":"func graphic.ThumbnailImageCache(srcfile string, maxWidth, maxHeight int, f Format)(dstfile string, useCache bool, err error)","Funname":"graphic.ThumbnailImageCache","Returntype":"(dstfile string, useCache bool, err error)","Args":"srcfile string, maxWidth, maxHeight int, f Format"},{"Uniquefunname":"func doScaleNearestNeighbor(img image.Image, newWidth, newHeight int) (newimg *image.RGBA)","Funname":"graphic.doScaleNearestNeighbor","Returntype":"(newimg *image.RGBA)","Args":"img image.Image, newWidth, newHeight int"}],"Records":null} {"Filepath":"graphic/utils.go","Functions":[{"Uniquefunname":"func convertToRGBA(img image.Image) (rgba *image.RGBA)","Funname":"convertToRGBA","Returntype":"(rgba *image.RGBA)","Args":"img image.Image"},{"Uniquefunname":"func generateCacheFilePath(keyword string) (dstfile string)","Funname":"generateCacheFilePath","Returntype":"(dstfile string)","Args":"keyword string"},{"Uniquefunname":"func convertToRGBA(img image.Image) (rgba *image.RGBA)","Funname":"graphic.convertToRGBA","Returntype":"(rgba *image.RGBA)","Args":"img image.Image"},{"Uniquefunname":"func generateCacheFilePath(keyword string) (dstfile string)","Funname":"graphic.generateCacheFilePath","Returntype":"(dstfile string)","Args":"keyword string"},{"Uniquefunname":"func isFileExists(file string) bool","Funname":"graphic.isFileExists","Returntype":"bool","Args":"file string"},{"Uniquefunname":"func openFileOrCreate(file string) (*os.File, error)","Funname":"graphic.openFileOrCreate","Returntype":"(*os.File, error)","Args":"file string"},{"Uniquefunname":"func isFileExists(file string) bool","Funname":"isFileExists","Returntype":"bool","Args":"file string"},{"Uniquefunname":"func openFileOrCreate(file string) (*os.File, error)","Funname":"openFileOrCreate","Returntype":"(*os.File, error)","Args":"file string"}],"Records":null} {"Filepath":"gsettings/monitor.go","Functions":[{"Uniquefunname":"func ConnectChanged(schemaOrPath, key string, fn ChangedCallbackFunc)","Funname":"ConnectChanged","Returntype":"","Args":"schemaOrPath, key string, fn ChangedCallbackFunc"},{"Uniquefunname":"func StartMonitor() error","Funname":"StartMonitor","Returntype":"error","Args":""},{"Uniquefunname":"func addMatch(bus *dbus.Conn, rule string) error","Funname":"addMatch","Returntype":"error","Args":"bus *dbus.Conn, rule string"},{"Uniquefunname":"func ConnectChanged(schemaOrPath, key string, fn ChangedCallbackFunc)","Funname":"gsettings.ConnectChanged","Returntype":"","Args":"schemaOrPath, key string, fn ChangedCallbackFunc"},{"Uniquefunname":"func StartMonitor() error","Funname":"gsettings.StartMonitor","Returntype":"error","Args":""},{"Uniquefunname":"func addMatch(bus *dbus.Conn, rule string) error","Funname":"gsettings.addMatch","Returntype":"error","Args":"bus *dbus.Conn, rule string"},{"Uniquefunname":"func handleSignal(keyPath string)","Funname":"gsettings.handleSignal","Returntype":"","Args":"keyPath string"},{"Uniquefunname":"func initBus() (*dbus.Conn, error)","Funname":"gsettings.initBus","Returntype":"(*dbus.Conn, error)","Args":""},{"Uniquefunname":"func toPath(schemaOrPath string) string","Funname":"gsettings.toPath","Returntype":"string","Args":"schemaOrPath string"},{"Uniquefunname":"func handleSignal(keyPath string)","Funname":"handleSignal","Returntype":"","Args":"keyPath string"},{"Uniquefunname":"func initBus() (*dbus.Conn, error)","Funname":"initBus","Returntype":"(*dbus.Conn, error)","Args":""},{"Uniquefunname":"func toPath(schemaOrPath string) string","Funname":"toPath","Returntype":"string","Args":"schemaOrPath string"}],"Records":[{"Name":"struct:gsettings.changedCallback","Fields":["gsettings.changedCallback.all bool","gsettings.changedCallback.fns []ChangedCallbackFunc"]},{"Name":"var:gsettings","Fields":["gsettings.changedCallbackMap","gsettings.changedCallbackMapMu","gsettings.started","gsettings.startedMu"]}]} {"Filepath":"imgutil/format_sniff.go","Functions":[{"Uniquefunname":"func SniffFormat(file string) (string, error)","Funname":"SniffFormat","Returntype":"(string, error)","Args":"file string"},{"Uniquefunname":"func SniffFormat(file string) (string, error)","Funname":"imgutil.SniffFormat","Returntype":"(string, error)","Args":"file string"},{"Uniquefunname":"func match(magic string, b []byte) bool","Funname":"imgutil.match","Returntype":"bool","Args":"magic string, b []byte"},{"Uniquefunname":"func sniff(r *bufio.Reader) format","Funname":"imgutil.sniff","Returntype":"format","Args":"r *bufio.Reader"},{"Uniquefunname":"func match(magic string, b []byte) bool","Funname":"match","Returntype":"bool","Args":"magic string, b []byte"},{"Uniquefunname":"func sniff(r *bufio.Reader) format","Funname":"sniff","Returntype":"format","Args":"r *bufio.Reader"}],"Records":[{"Name":"struct:imgutil.format","Fields":["imgutil.format.magic string","imgutil.format.name string"]},{"Name":"var:imgutil","Fields":["imgutil.formats"]}]} {"Filepath":"imgutil/imgutil.go","Functions":[{"Uniquefunname":"func CanDecodeConfig(filename string) bool","Funname":"CanDecodeConfig","Returntype":"bool","Args":"filename string"},{"Uniquefunname":"func GetSupportedFormats() strv.Strv","Funname":"GetSupportedFormats","Returntype":"strv.Strv","Args":""},{"Uniquefunname":"func IsSupported(filename string) bool","Funname":"IsSupported","Returntype":"bool","Args":"filename string"},{"Uniquefunname":"func Load(filename string) (image.Image, error)","Funname":"Load","Returntype":"(image.Image, error)","Args":"filename string"},{"Uniquefunname":"func SavePng(img image.Image, filename string, enc *png.Encoder) error","Funname":"SavePng","Returntype":"error","Args":"img image.Image, filename string, enc *png.Encoder"},{"Uniquefunname":"func CanDecodeConfig(filename string) bool","Funname":"imgutil.CanDecodeConfig","Returntype":"bool","Args":"filename string"},{"Uniquefunname":"func GetSupportedFormats() strv.Strv","Funname":"imgutil.GetSupportedFormats","Returntype":"strv.Strv","Args":""},{"Uniquefunname":"func IsSupported(filename string) bool","Funname":"imgutil.IsSupported","Returntype":"bool","Args":"filename string"},{"Uniquefunname":"func Load(filename string) (image.Image, error)","Funname":"imgutil.Load","Returntype":"(image.Image, error)","Args":"filename string"},{"Uniquefunname":"func SavePng(img image.Image, filename string, enc *png.Encoder) error","Funname":"imgutil.SavePng","Returntype":"error","Args":"img image.Image, filename string, enc *png.Encoder"},{"Uniquefunname":"func loadCommon(filename string) (image.Image, error)","Funname":"imgutil.loadCommon","Returntype":"(image.Image, error)","Args":"filename string"},{"Uniquefunname":"func loadViaGdkPixbuf(filename string) (image.Image, error)","Funname":"imgutil.loadViaGdkPixbuf","Returntype":"(image.Image, error)","Args":"filename string"},{"Uniquefunname":"func loadCommon(filename string) (image.Image, error)","Funname":"loadCommon","Returntype":"(image.Image, error)","Args":"filename string"},{"Uniquefunname":"func loadViaGdkPixbuf(filename string) (image.Image, error)","Funname":"loadViaGdkPixbuf","Returntype":"(image.Image, error)","Args":"filename string"}],"Records":[{"Name":"const:imgutil","Fields":["imgutil.FormatBMP","imgutil.FormatGIF","imgutil.FormatJPEG","imgutil.FormatPNG","imgutil.FormatTIFF"]},{"Name":"var:imgutil","Fields":["imgutil.supportedFormats"]}]} {"Filepath":"imgutil/imgutil_test.go","Functions":[{"Uniquefunname":"func TestCanDecodeConfig(t *testing.T)","Funname":"TestCanDecodeConfig","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestIsSupported(t *testing.T)","Funname":"TestIsSupported","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestLoad(t *testing.T)","Funname":"TestLoad","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSavePng(t *testing.T)","Funname":"TestSavePng","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSniffFormat(t *testing.T)","Funname":"TestSniffFormat","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestCanDecodeConfig(t *testing.T)","Funname":"imgutil.TestCanDecodeConfig","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestIsSupported(t *testing.T)","Funname":"imgutil.TestIsSupported","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestLoad(t *testing.T)","Funname":"imgutil.TestLoad","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSavePng(t *testing.T)","Funname":"imgutil.TestSavePng","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSniffFormat(t *testing.T)","Funname":"imgutil.TestSniffFormat","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"initializer/initializer.go","Functions":[{"Uniquefunname":"func (i *Initializer) GetError() error","Funname":"GetError","Returntype":"error","Args":""},{"Uniquefunname":"func (i *Initializer) Init(fn func(interface","Funname":"Init","Returntype":"*Initializer","Args":"fn func(interface{}) (interface{}, error)"},{"Uniquefunname":"func NewInitializer() *Initializer","Funname":"NewInitializer","Returntype":"*Initializer","Args":""},{"Uniquefunname":"func initWithHandler(fn func(interface{}) (interface{}, error), handler func(interface{}) (interface{}, error))*Initializer","Funname":"initWithHandler","Returntype":"*Initializer","Args":"fn func(interface{}) (interface{}, error), handler func(interface{}) (interface{}, error)"},{"Uniquefunname":"func (i *Initializer) GetError() error","Funname":"initializer.Initializer.GetError","Returntype":"error","Args":""},{"Uniquefunname":"func (i *Initializer) Init(fn func(interface","Funname":"initializer.Initializer.Init","Returntype":"*Initializer","Args":"fn func(interface{}) (interface{}, error)"},{"Uniquefunname":"func initializer.Initializer.initWithHandler(fn func(interface{}) (interface{}, error), handler func(interface{}) (interface{}, error))*Initializer","Funname":"initializer.Initializer.initWithHandler","Returntype":"*Initializer","Args":"fn func(interface{}) (interface{}, error), handler func(interface{}) (interface{}, error)"},{"Uniquefunname":"func NewInitializer() *Initializer","Funname":"initializer.NewInitializer","Returntype":"*Initializer","Args":""},{"Uniquefunname":"func noop(v interface","Funname":"initializer.noop","Returntype":"(interface{}, error)","Args":"v interface{}"},{"Uniquefunname":"func noop(v interface","Funname":"noop","Returntype":"(interface{}, error)","Args":"v interface{}"}],"Records":[{"Name":"struct:initializer.Initializer","Fields":["initializer.Initializer.e error","initializer.Initializer.v interface{}"]}]} {"Filepath":"initializer/initializer_test.go","Functions":[{"Uniquefunname":"func TestInitializer(t *testing.T)","Funname":"TestInitializer","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestInitializerError(t *testing.T)","Funname":"TestInitializerError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestInitializer(t *testing.T)","Funname":"initializer_test.TestInitializer","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestInitializerError(t *testing.T)","Funname":"initializer_test.TestInitializerError","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"initializer/v2/initializer.go","Functions":[{"Uniquefunname":"func (i *Initializer) Do(fn func() error) *Initializer","Funname":"Do","Returntype":"*Initializer","Args":"fn func() error"},{"Uniquefunname":"func Do(fn func() error) *Initializer","Funname":"Do","Returntype":"*Initializer","Args":"fn func() error"},{"Uniquefunname":"func (i *Initializer) GetError() error","Funname":"GetError","Returntype":"error","Args":""},{"Uniquefunname":"func (i *Initializer) init(fn func() error) *Initializer","Funname":"init","Returntype":"*Initializer","Args":"fn func() error"},{"Uniquefunname":"func Do(fn func() error) *Initializer","Funname":"initializer.Do","Returntype":"*Initializer","Args":"fn func() error"},{"Uniquefunname":"func (i *Initializer) Do(fn func() error) *Initializer","Funname":"initializer.Initializer.Do","Returntype":"*Initializer","Args":"fn func() error"},{"Uniquefunname":"func (i *Initializer) GetError() error","Funname":"initializer.Initializer.GetError","Returntype":"error","Args":""},{"Uniquefunname":"func (i *Initializer) init(fn func() error) *Initializer","Funname":"initializer.Initializer.init","Returntype":"*Initializer","Args":"fn func() error"}],"Records":[{"Name":"struct:initializer.Initializer","Fields":["initializer.Initializer.e error"]}]} {"Filepath":"initializer/v2/initializer_test.go","Functions":[{"Uniquefunname":"func TestInitializer(t *testing.T)","Funname":"TestInitializer","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestInitializerError(t *testing.T)","Funname":"TestInitializerError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func e1() error","Funname":"e1","Returntype":"error","Args":""},{"Uniquefunname":"func e2() error","Funname":"e2","Returntype":"error","Args":""},{"Uniquefunname":"func TestInitializer(t *testing.T)","Funname":"initializer_test.TestInitializer","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestInitializerError(t *testing.T)","Funname":"initializer_test.TestInitializerError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func e1() error","Funname":"initializer_test.e1","Returntype":"error","Args":""},{"Uniquefunname":"func e2() error","Funname":"initializer_test.e2","Returntype":"error","Args":""}],"Records":null} {"Filepath":"iso/country.go","Functions":[{"Uniquefunname":"func GetAllCountryCode() (codeList []string, err error)","Funname":"GetAllCountryCode","Returntype":"(codeList []string, err error)","Args":""},{"Uniquefunname":"func GetAllCountryNames() (nameList []string, err error)","Funname":"GetAllCountryNames","Returntype":"(nameList []string, err error)","Args":""},{"Uniquefunname":"func GetCountryCodeForLanguage(language string) (code string, err error)","Funname":"GetCountryCodeForLanguage","Returntype":"(code string, err error)","Args":"language string"},{"Uniquefunname":"func GetCountryDatabase() (*CountryDatabase, error)","Funname":"GetCountryDatabase","Returntype":"(*CountryDatabase, error)","Args":""},{"Uniquefunname":"func GetCountryNameForCode(code string) (name string, err error)","Funname":"GetCountryNameForCode","Returntype":"(name string, err error)","Args":"code string"},{"Uniquefunname":"func GetLocaleCountryCode() (code string, err error)","Funname":"GetLocaleCountryCode","Returntype":"(code string, err error)","Args":""},{"Uniquefunname":"func GetLocaleCountryName() (name string, err error)","Funname":"GetLocaleCountryName","Returntype":"(name string, err error)","Args":""},{"Uniquefunname":"func getLocalLanguage() string","Funname":"getLocalLanguage","Returntype":"string","Args":""},{"Uniquefunname":"func GetAllCountryCode() (codeList []string, err error)","Funname":"iso.GetAllCountryCode","Returntype":"(codeList []string, err error)","Args":""},{"Uniquefunname":"func GetAllCountryNames() (nameList []string, err error)","Funname":"iso.GetAllCountryNames","Returntype":"(nameList []string, err error)","Args":""},{"Uniquefunname":"func GetCountryCodeForLanguage(language string) (code string, err error)","Funname":"iso.GetCountryCodeForLanguage","Returntype":"(code string, err error)","Args":"language string"},{"Uniquefunname":"func GetCountryDatabase() (*CountryDatabase, error)","Funname":"iso.GetCountryDatabase","Returntype":"(*CountryDatabase, error)","Args":""},{"Uniquefunname":"func GetCountryNameForCode(code string) (name string, err error)","Funname":"iso.GetCountryNameForCode","Returntype":"(name string, err error)","Args":"code string"},{"Uniquefunname":"func GetLocaleCountryCode() (code string, err error)","Funname":"iso.GetLocaleCountryCode","Returntype":"(code string, err error)","Args":""},{"Uniquefunname":"func GetLocaleCountryName() (name string, err error)","Funname":"iso.GetLocaleCountryName","Returntype":"(name string, err error)","Args":""},{"Uniquefunname":"func getLocalLanguage() string","Funname":"iso.getLocalLanguage","Returntype":"string","Args":""}],"Records":[{"Name":"struct:iso.Country","Fields":["iso.Country.Alpha2Code string","iso.Country.Alpha3Code string","iso.Country.CommonName string","iso.Country.Name string","iso.Country.NumericCode string","iso.Country.OfficialName string"]},{"Name":"struct:iso.CountryDatabase","Fields":["iso.CountryDatabase.Countries []Country"]},{"Name":"var:iso","Fields":["iso.countryDatabase","iso.countryDatabaseLock","iso.errCountryCodeInvalid","iso.errLanguageFormatInvalid"]},{"Name":"const:iso","Fields":["iso.iso3166XMLFile"]}]} {"Filepath":"iso/country_test.go","Functions":[{"Uniquefunname":"func (*testWrapper) TestGetCountryCodeForLanguage(c *C.C)","Funname":"TestGetCountryCodeForLanguage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetCountryDatabase(c *C.C)","Funname":"TestGetCountryDatabase","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetCountryInfoForCode(c *C.C)","Funname":"TestGetCountryInfoForCode","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetLocaleCountryInfo(c *C.C)","Funname":"TestGetLocaleCountryInfo","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetCountryCodeForLanguage(c *C.C)","Funname":"iso.testWrapper.TestGetCountryCodeForLanguage","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetCountryDatabase(c *C.C)","Funname":"iso.testWrapper.TestGetCountryDatabase","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetCountryInfoForCode(c *C.C)","Funname":"iso.testWrapper.TestGetCountryInfoForCode","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetLocaleCountryInfo(c *C.C)","Funname":"iso.testWrapper.TestGetLocaleCountryInfo","Returntype":"","Args":"c *C.C"}],"Records":[{"Name":"const:iso","Fields":["iso.envLanguage"]}]} {"Filepath":"iso/iso_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func iso.Test(t *testing.T)","Funname":"iso.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"iso.init","Returntype":"","Args":""}],"Records":null} {"Filepath":"keyfile/get.go","Functions":[{"Uniquefunname":"func (err ValueInvalidUTF8Error) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (f *KeyFile) GetBoolList(section, key string) ([]bool, error)","Funname":"GetBoolList","Returntype":"([]bool, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetFloat64(section, key string) (float64, error)","Funname":"GetFloat64","Returntype":"(float64, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetFloat64List(section, key string) ([]float64, error)","Funname":"GetFloat64List","Returntype":"([]float64, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetInt(section, key string) (int, error)","Funname":"GetInt","Returntype":"(int, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetInt64(section, key string) (int64, error)","Funname":"GetInt64","Returntype":"(int64, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetIntList(section, key string) ([]int, error)","Funname":"GetIntList","Returntype":"([]int, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetLocaleString(section, key, locale string) (string, error)","Funname":"GetLocaleString","Returntype":"(string, error)","Args":"section, key, locale string"},{"Uniquefunname":"func (f *KeyFile) GetLocaleStringList(section, key, locale string) ([]string, error)","Funname":"GetLocaleStringList","Returntype":"([]string, error)","Args":"section, key, locale string"},{"Uniquefunname":"func (f *KeyFile) GetString(section, key string) (string, error)","Funname":"GetString","Returntype":"(string, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetStringList(section, key string) ([]string, error)","Funname":"GetStringList","Returntype":"([]string, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetUint64(section, key string) (uint64, error)","Funname":"GetUint64","Returntype":"(uint64, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetBoolList(section, key string) ([]bool, error)","Funname":"keyfile.KeyFile.GetBoolList","Returntype":"([]bool, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetFloat64(section, key string) (float64, error)","Funname":"keyfile.KeyFile.GetFloat64","Returntype":"(float64, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetFloat64List(section, key string) ([]float64, error)","Funname":"keyfile.KeyFile.GetFloat64List","Returntype":"([]float64, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetInt(section, key string) (int, error)","Funname":"keyfile.KeyFile.GetInt","Returntype":"(int, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetInt64(section, key string) (int64, error)","Funname":"keyfile.KeyFile.GetInt64","Returntype":"(int64, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetIntList(section, key string) ([]int, error)","Funname":"keyfile.KeyFile.GetIntList","Returntype":"([]int, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetLocaleString(section, key, locale string) (string, error)","Funname":"keyfile.KeyFile.GetLocaleString","Returntype":"(string, error)","Args":"section, key, locale string"},{"Uniquefunname":"func (f *KeyFile) GetLocaleStringList(section, key, locale string) ([]string, error)","Funname":"keyfile.KeyFile.GetLocaleStringList","Returntype":"([]string, error)","Args":"section, key, locale string"},{"Uniquefunname":"func (f *KeyFile) GetString(section, key string) (string, error)","Funname":"keyfile.KeyFile.GetString","Returntype":"(string, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetStringList(section, key string) ([]string, error)","Funname":"keyfile.KeyFile.GetStringList","Returntype":"([]string, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetUint64(section, key string) (uint64, error)","Funname":"keyfile.KeyFile.GetUint64","Returntype":"(uint64, error)","Args":"section, key string"},{"Uniquefunname":"func (err ValueInvalidUTF8Error) Error() string","Funname":"keyfile.ValueInvalidUTF8Error.Error","Returntype":"string","Args":""},{"Uniquefunname":"func parseValueAsBool(value string) (bool, error)","Funname":"keyfile.parseValueAsBool","Returntype":"(bool, error)","Args":"value string"},{"Uniquefunname":"func keyfile.parseValueAsString(value string, wantArray bool, listSeparator byte)(string, []string, error)","Funname":"keyfile.parseValueAsString","Returntype":"(string, []string, error)","Args":"value string, wantArray bool, listSeparator byte"},{"Uniquefunname":"func parseValueAsBool(value string) (bool, error)","Funname":"parseValueAsBool","Returntype":"(bool, error)","Args":"value string"},{"Uniquefunname":"func parseValueAsString(value string, wantArray bool, listSeparator byte)(string, []string, error)","Funname":"parseValueAsString","Returntype":"(string, []string, error)","Args":"value string, wantArray bool, listSeparator byte"}],"Records":[{"Name":"struct:keyfile.ValueInvalidUTF8Error","Fields":["keyfile.ValueInvalidUTF8Error.Key string","keyfile.ValueInvalidUTF8Error.Section string"]}]} {"Filepath":"keyfile/keyfile.go","Functions":[{"Uniquefunname":"func (f *KeyFile) DeleteKey(section, key string) bool","Funname":"DeleteKey","Returntype":"bool","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) DeleteSection(section string) bool","Funname":"DeleteSection","Returntype":"bool","Args":"section string"},{"Uniquefunname":"func (err InvalidValueError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err KeyNotFoundError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err SectionNotFoundError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (f *KeyFile) GetBool(section, key string) (bool, error)","Funname":"GetBool","Returntype":"(bool, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetKeyComments(section, key string) string","Funname":"GetKeyComments","Returntype":"string","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetKeys(section string) []string","Funname":"GetKeys","Returntype":"[]string","Args":"section string"},{"Uniquefunname":"func (f *KeyFile) GetSection(section string) (map[string]string, error)","Funname":"GetSection","Returntype":"(map[string]string, error)","Args":"section string"},{"Uniquefunname":"func (f *KeyFile) GetSectionComments(section string) string","Funname":"GetSectionComments","Returntype":"string","Args":"section string"},{"Uniquefunname":"func (f *KeyFile) GetSections() []string","Funname":"GetSections","Returntype":"[]string","Args":""},{"Uniquefunname":"func (f *KeyFile) GetValue(section, key string) (string, error)","Funname":"GetValue","Returntype":"(string, error)","Args":"section, key string"},{"Uniquefunname":"func NewKeyFile() *KeyFile","Funname":"NewKeyFile","Returntype":"*KeyFile","Args":""},{"Uniquefunname":"func (f *KeyFile) SetKeyComments(section, key, comments string) bool","Funname":"SetKeyComments","Returntype":"bool","Args":"section, key, comments string"},{"Uniquefunname":"func (f *KeyFile) SetKeyRegexp(keyReg *regexp.Regexp)","Funname":"SetKeyRegexp","Returntype":"","Args":"keyReg *regexp.Regexp"},{"Uniquefunname":"func (f *KeyFile) SetSectionComments(section, comments string) bool","Funname":"SetSectionComments","Returntype":"bool","Args":"section, comments string"},{"Uniquefunname":"func (f *KeyFile) SetValue(section, key, value string) bool","Funname":"SetValue","Returntype":"bool","Args":"section, key, value string"},{"Uniquefunname":"func (err InvalidValueError) Error() string","Funname":"keyfile.InvalidValueError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func (f *KeyFile) DeleteKey(section, key string) bool","Funname":"keyfile.KeyFile.DeleteKey","Returntype":"bool","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) DeleteSection(section string) bool","Funname":"keyfile.KeyFile.DeleteSection","Returntype":"bool","Args":"section string"},{"Uniquefunname":"func (f *KeyFile) GetBool(section, key string) (bool, error)","Funname":"keyfile.KeyFile.GetBool","Returntype":"(bool, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetKeyComments(section, key string) string","Funname":"keyfile.KeyFile.GetKeyComments","Returntype":"string","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) GetKeys(section string) []string","Funname":"keyfile.KeyFile.GetKeys","Returntype":"[]string","Args":"section string"},{"Uniquefunname":"func (f *KeyFile) GetSection(section string) (map[string]string, error)","Funname":"keyfile.KeyFile.GetSection","Returntype":"(map[string]string, error)","Args":"section string"},{"Uniquefunname":"func (f *KeyFile) GetSectionComments(section string) string","Funname":"keyfile.KeyFile.GetSectionComments","Returntype":"string","Args":"section string"},{"Uniquefunname":"func (f *KeyFile) GetSections() []string","Funname":"keyfile.KeyFile.GetSections","Returntype":"[]string","Args":""},{"Uniquefunname":"func (f *KeyFile) GetValue(section, key string) (string, error)","Funname":"keyfile.KeyFile.GetValue","Returntype":"(string, error)","Args":"section, key string"},{"Uniquefunname":"func (f *KeyFile) SetKeyComments(section, key, comments string) bool","Funname":"keyfile.KeyFile.SetKeyComments","Returntype":"bool","Args":"section, key, comments string"},{"Uniquefunname":"func (f *KeyFile) SetKeyRegexp(keyReg *regexp.Regexp)","Funname":"keyfile.KeyFile.SetKeyRegexp","Returntype":"","Args":"keyReg *regexp.Regexp"},{"Uniquefunname":"func (f *KeyFile) SetSectionComments(section, comments string) bool","Funname":"keyfile.KeyFile.SetSectionComments","Returntype":"bool","Args":"section, comments string"},{"Uniquefunname":"func (f *KeyFile) SetValue(section, key, value string) bool","Funname":"keyfile.KeyFile.SetValue","Returntype":"bool","Args":"section, key, value string"},{"Uniquefunname":"func (err KeyNotFoundError) Error() string","Funname":"keyfile.KeyNotFoundError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func NewKeyFile() *KeyFile","Funname":"keyfile.NewKeyFile","Returntype":"*KeyFile","Args":""},{"Uniquefunname":"func (err SectionNotFoundError) Error() string","Funname":"keyfile.SectionNotFoundError.Error","Returntype":"string","Args":""}],"Records":[{"Name":"struct:keyfile.InvalidValueError","Fields":["keyfile.InvalidValueError.Value string"]},{"Name":"struct:keyfile.KeyFile","Fields":["keyfile.KeyFile.ListSeparator byte","keyfile.KeyFile.data map[string]map[string]string","keyfile.KeyFile.keyComments map[string]map[string]string","keyfile.KeyFile.keyList map[string][]string","keyfile.KeyFile.keyReg *regexp.Regexp","keyfile.KeyFile.mutex sync.RWMutex","keyfile.KeyFile.sectionComments map[string]string","keyfile.KeyFile.sectionList []string"]},{"Name":"struct:keyfile.KeyNotFoundError","Fields":["keyfile.KeyNotFoundError.Name string"]},{"Name":"var:keyfile","Fields":["keyfile.LineBreak"]},{"Name":"struct:keyfile.SectionNotFoundError","Fields":["keyfile.SectionNotFoundError.Name string"]}]} {"Filepath":"keyfile/keyfile_test.go","Functions":[{"Uniquefunname":"func TestGetString(t *testing.T)","Funname":"TestGetString","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetStringList(t *testing.T)","Funname":"TestGetStringList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestLoadFromData(t *testing.T)","Funname":"TestLoadFromData","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestLoadFromFile(t *testing.T)","Funname":"TestLoadFromFile","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSaveToWriter(t *testing.T)","Funname":"TestSaveToWriter","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSetBoolList(t *testing.T)","Funname":"TestSetBoolList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSetIntList(t *testing.T)","Funname":"TestSetIntList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSetString(t *testing.T)","Funname":"TestSetString","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSetStringList(t *testing.T)","Funname":"TestSetStringList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetString(t *testing.T)","Funname":"keyfile.TestGetString","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetStringList(t *testing.T)","Funname":"keyfile.TestGetStringList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestLoadFromData(t *testing.T)","Funname":"keyfile.TestLoadFromData","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestLoadFromFile(t *testing.T)","Funname":"keyfile.TestLoadFromFile","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSaveToWriter(t *testing.T)","Funname":"keyfile.TestSaveToWriter","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSetBoolList(t *testing.T)","Funname":"keyfile.TestSetBoolList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSetIntList(t *testing.T)","Funname":"keyfile.TestSetIntList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSetString(t *testing.T)","Funname":"keyfile.TestSetString","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSetStringList(t *testing.T)","Funname":"keyfile.TestSetStringList","Returntype":"","Args":"t *testing.T"}],"Records":[{"Name":"const:keyfile","Fields":["keyfile.desktopFileContent0","keyfile.desktopFileContent1","keyfile.desktopFileContent2","keyfile.desktopFileContent3","keyfile.desktopFileContent4","keyfile.keyFileContent0","keyfile.keyFileContent1","keyfile.keyFileContent2"]}]} {"Filepath":"keyfile/read.go","Functions":[{"Uniquefunname":"func (err BlankSectionNameError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err EntryNotInSectionError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err InvalidKeyError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err ParseError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (f *KeyFile) LoadFromData(data []byte) error","Funname":"LoadFromData","Returntype":"error","Args":"data []byte"},{"Uniquefunname":"func (f *KeyFile) LoadFromFile(filename string) error","Funname":"LoadFromFile","Returntype":"error","Args":"filename string"},{"Uniquefunname":"func (f *KeyFile) LoadFromReader(reader io.Reader) error","Funname":"LoadFromReader","Returntype":"error","Args":"reader io.Reader"},{"Uniquefunname":"func (err BlankSectionNameError) Error() string","Funname":"keyfile.BlankSectionNameError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err EntryNotInSectionError) Error() string","Funname":"keyfile.EntryNotInSectionError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func (err InvalidKeyError) Error() string","Funname":"keyfile.InvalidKeyError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func (f *KeyFile) LoadFromData(data []byte) error","Funname":"keyfile.KeyFile.LoadFromData","Returntype":"error","Args":"data []byte"},{"Uniquefunname":"func (f *KeyFile) LoadFromFile(filename string) error","Funname":"keyfile.KeyFile.LoadFromFile","Returntype":"error","Args":"filename string"},{"Uniquefunname":"func (f *KeyFile) LoadFromReader(reader io.Reader) error","Funname":"keyfile.KeyFile.LoadFromReader","Returntype":"error","Args":"reader io.Reader"},{"Uniquefunname":"func (err ParseError) Error() string","Funname":"keyfile.ParseError.Error","Returntype":"string","Args":""}],"Records":[{"Name":"struct:keyfile.EntryNotInSectionError","Fields":["keyfile.EntryNotInSectionError.Line string"]},{"Name":"struct:keyfile.InvalidKeyError","Fields":["keyfile.InvalidKeyError.Key string"]},{"Name":"struct:keyfile.ParseError","Fields":["keyfile.ParseError.Line string"]},{"Name":"var:keyfile","Fields":["keyfile.errEmptyKey"]}]} {"Filepath":"keyfile/set.go","Functions":[{"Uniquefunname":"func (f *KeyFile) SetBool(section, key string, value bool)","Funname":"SetBool","Returntype":"","Args":"section, key string, value bool"},{"Uniquefunname":"func (f *KeyFile) SetBoolList(section, key string, values []bool)","Funname":"SetBoolList","Returntype":"","Args":"section, key string, values []bool"},{"Uniquefunname":"func (f *KeyFile) SetFloat64(section, key string, value float64)","Funname":"SetFloat64","Returntype":"","Args":"section, key string, value float64"},{"Uniquefunname":"func (f *KeyFile) SetFloat64List(section, key string, values []float64)","Funname":"SetFloat64List","Returntype":"","Args":"section, key string, values []float64"},{"Uniquefunname":"func (f *KeyFile) SetInt(section, key string, value int)","Funname":"SetInt","Returntype":"","Args":"section, key string, value int"},{"Uniquefunname":"func (f *KeyFile) SetInt64(section, key string, value int64)","Funname":"SetInt64","Returntype":"","Args":"section, key string, value int64"},{"Uniquefunname":"func (f *KeyFile) SetIntList(section, key string, values []int)","Funname":"SetIntList","Returntype":"","Args":"section, key string, values []int"},{"Uniquefunname":"func (f *KeyFile) SetString(section, key, value string)","Funname":"SetString","Returntype":"","Args":"section, key, value string"},{"Uniquefunname":"func (f *KeyFile) SetStringList(section, key string, values []string)","Funname":"SetStringList","Returntype":"","Args":"section, key string, values []string"},{"Uniquefunname":"func (f *KeyFile) SetUint64(section, key string, value uint64)","Funname":"SetUint64","Returntype":"","Args":"section, key string, value uint64"},{"Uniquefunname":"func (f *KeyFile) SetBool(section, key string, value bool)","Funname":"keyfile.KeyFile.SetBool","Returntype":"","Args":"section, key string, value bool"},{"Uniquefunname":"func (f *KeyFile) SetBoolList(section, key string, values []bool)","Funname":"keyfile.KeyFile.SetBoolList","Returntype":"","Args":"section, key string, values []bool"},{"Uniquefunname":"func (f *KeyFile) SetFloat64(section, key string, value float64)","Funname":"keyfile.KeyFile.SetFloat64","Returntype":"","Args":"section, key string, value float64"},{"Uniquefunname":"func (f *KeyFile) SetFloat64List(section, key string, values []float64)","Funname":"keyfile.KeyFile.SetFloat64List","Returntype":"","Args":"section, key string, values []float64"},{"Uniquefunname":"func (f *KeyFile) SetInt(section, key string, value int)","Funname":"keyfile.KeyFile.SetInt","Returntype":"","Args":"section, key string, value int"},{"Uniquefunname":"func (f *KeyFile) SetInt64(section, key string, value int64)","Funname":"keyfile.KeyFile.SetInt64","Returntype":"","Args":"section, key string, value int64"},{"Uniquefunname":"func (f *KeyFile) SetIntList(section, key string, values []int)","Funname":"keyfile.KeyFile.SetIntList","Returntype":"","Args":"section, key string, values []int"},{"Uniquefunname":"func (f *KeyFile) SetString(section, key, value string)","Funname":"keyfile.KeyFile.SetString","Returntype":"","Args":"section, key, value string"},{"Uniquefunname":"func (f *KeyFile) SetStringList(section, key string, values []string)","Funname":"keyfile.KeyFile.SetStringList","Returntype":"","Args":"section, key string, values []string"},{"Uniquefunname":"func (f *KeyFile) SetUint64(section, key string, value uint64)","Funname":"keyfile.KeyFile.SetUint64","Returntype":"","Args":"section, key string, value uint64"},{"Uniquefunname":"func stringEscape(in string) string","Funname":"keyfile.stringEscape","Returntype":"string","Args":"in string"},{"Uniquefunname":"func stringEscape(in string) string","Funname":"stringEscape","Returntype":"string","Args":"in string"}],"Records":null} {"Filepath":"keyfile/write.go","Functions":[{"Uniquefunname":"func (kf *KeyFile) SaveToFile(file string) error","Funname":"SaveToFile","Returntype":"error","Args":"file string"},{"Uniquefunname":"func (f *KeyFile) SaveToWriter(w io.Writer) error","Funname":"SaveToWriter","Returntype":"error","Args":"w io.Writer"},{"Uniquefunname":"func (kf *KeyFile) SaveToFile(file string) error","Funname":"keyfile.KeyFile.SaveToFile","Returntype":"error","Args":"file string"},{"Uniquefunname":"func (f *KeyFile) SaveToWriter(w io.Writer) error","Funname":"keyfile.KeyFile.SaveToWriter","Returntype":"error","Args":"w io.Writer"}],"Records":null} {"Filepath":"libc/libc.go","Functions":[{"Uniquefunname":"func NewTm(t time.Time) Tm","Funname":"NewTm","Returntype":"Tm","Args":"t time.Time"},{"Uniquefunname":"func Strftime(format string, tm Tm) (s string)","Funname":"Strftime","Returntype":"(s string)","Args":"format string, tm Tm"},{"Uniquefunname":"func NewTm(t time.Time) Tm","Funname":"libc.NewTm","Returntype":"Tm","Args":"t time.Time"},{"Uniquefunname":"func Strftime(format string, tm Tm) (s string)","Funname":"libc.Strftime","Returntype":"(s string)","Args":"format string, tm Tm"},{"Uniquefunname":"func (tm Tm) native() *C.struct_tm","Funname":"libc.Tm.native","Returntype":"*C.struct_tm","Args":""},{"Uniquefunname":"func (tm Tm) native() *C.struct_tm","Funname":"native","Returntype":"*C.struct_tm","Args":""}],"Records":[{"Name":"struct:libc.Tm","Fields":["libc.Tm.core C.struct_tm"]},{"Name":"const:libc","Fields":["libc.initialBufSize"]}]} {"Filepath":"locale/locale.go","Functions":[{"Uniquefunname":"func ExplodeLocale(locale string) *Components","Funname":"ExplodeLocale","Returntype":"*Components","Args":"locale string"},{"Uniquefunname":"func GetLanguageNames() []string","Funname":"GetLanguageNames","Returntype":"[]string","Args":""},{"Uniquefunname":"func GetLocaleVariants(locale string) (variants []string)","Funname":"GetLocaleVariants","Returntype":"(variants []string)","Args":"locale string"},{"Uniquefunname":"func guessCategoryValue(categoryName string) (ret string)","Funname":"guessCategoryValue","Returntype":"(ret string)","Args":"categoryName string"},{"Uniquefunname":"func ExplodeLocale(locale string) *Components","Funname":"locale.ExplodeLocale","Returntype":"*Components","Args":"locale string"},{"Uniquefunname":"func GetLanguageNames() []string","Funname":"locale.GetLanguageNames","Returntype":"[]string","Args":""},{"Uniquefunname":"func GetLocaleVariants(locale string) (variants []string)","Funname":"locale.GetLocaleVariants","Returntype":"(variants []string)","Args":"locale string"},{"Uniquefunname":"func guessCategoryValue(categoryName string) (ret string)","Funname":"locale.guessCategoryValue","Returntype":"(ret string)","Args":"categoryName string"},{"Uniquefunname":"func readAliases(filename string) (aliasTable map[string]string)","Funname":"locale.readAliases","Returntype":"(aliasTable map[string]string)","Args":"filename string"},{"Uniquefunname":"func unaliasLang(lang string) string","Funname":"locale.unaliasLang","Returntype":"string","Args":"lang string"},{"Uniquefunname":"func readAliases(filename string) (aliasTable map[string]string)","Funname":"readAliases","Returntype":"(aliasTable map[string]string)","Args":"filename string"},{"Uniquefunname":"func unaliasLang(lang string) string","Funname":"unaliasLang","Returntype":"string","Args":"lang string"}],"Records":[{"Name":"const:locale","Fields":["locale.ComponentCodeset","locale.ComponentModifier","locale.ComponentTerritory","locale.charAt","locale.charDot","locale.charUscore"]},{"Name":"struct:locale.Components","Fields":["locale.Components.Codeset string","locale.Components.Language string","locale.Components.Mask uint","locale.Components.Modifier string","locale.Components.Territory string"]},{"Name":"struct:locale._LanguageNamesCache","Fields":["locale._LanguageNamesCache.Language string","locale._LanguageNamesCache.Names []string","locale._LanguageNamesCache.mutex sync.Mutex"]},{"Name":"var:locale","Fields":["locale.aliasFile","locale.aliases","locale.aliasesOnce","locale.languageNameCache","locale.splitor"]}]} {"Filepath":"locale/locale_test.go","Functions":[{"Uniquefunname":"func TestExplodeLocale(t *testing.T)","Funname":"TestExplodeLocale","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetLanguageNames(t *testing.T)","Funname":"TestGetLanguageNames","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetLocaleVariants(t *testing.T)","Funname":"TestGetLocaleVariants","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_readAliases(t *testing.T)","Funname":"Test_readAliases","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_unaliasLang(t *testing.T)","Funname":"Test_unaliasLang","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestExplodeLocale(t *testing.T)","Funname":"locale.TestExplodeLocale","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetLanguageNames(t *testing.T)","Funname":"locale.TestGetLanguageNames","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetLocaleVariants(t *testing.T)","Funname":"locale.TestGetLocaleVariants","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_readAliases(t *testing.T)","Funname":"locale.Test_readAliases","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_unaliasLang(t *testing.T)","Funname":"locale.Test_unaliasLang","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"log/backend_console.go","Functions":[{"Uniquefunname":"func (b *backendConsole) close() (err error)","Funname":"close","Returntype":"(err error)","Args":""},{"Uniquefunname":"func (b *backendConsole) formatMsg(level Priority, msg string) (fmtMsg string, err error)","Funname":"formatMsg","Returntype":"(fmtMsg string, err error)","Args":"level Priority, msg string"},{"Uniquefunname":"func getSyslogPrefix(name string) (prefix string)","Funname":"getSyslogPrefix","Returntype":"(prefix string)","Args":"name string"},{"Uniquefunname":"func (b *backendConsole) log(level Priority, msg string) (err error)","Funname":"log","Returntype":"(err error)","Args":"level Priority, msg string"},{"Uniquefunname":"func (b *backendConsole) close() (err error)","Funname":"log.backendConsole.close","Returntype":"(err error)","Args":""},{"Uniquefunname":"func (b *backendConsole) formatMsg(level Priority, msg string) (fmtMsg string, err error)","Funname":"log.backendConsole.formatMsg","Returntype":"(fmtMsg string, err error)","Args":"level Priority, msg string"},{"Uniquefunname":"func (b *backendConsole) log(level Priority, msg string) (err error)","Funname":"log.backendConsole.log","Returntype":"(err error)","Args":"level Priority, msg string"},{"Uniquefunname":"func getSyslogPrefix(name string) (prefix string)","Funname":"log.getSyslogPrefix","Returntype":"(prefix string)","Args":"name string"},{"Uniquefunname":"func newBackendConsole(name string) (b *backendConsole)","Funname":"log.newBackendConsole","Returntype":"(b *backendConsole)","Args":"name string"},{"Uniquefunname":"func newBackendConsole(name string) (b *backendConsole)","Funname":"newBackendConsole","Returntype":"(b *backendConsole)","Args":"name string"}],"Records":[{"Name":"var:log","Fields":["log.DebugConsoleEnv"]},{"Name":"struct:log.backendConsole","Fields":["log.backendConsole.name string","log.backendConsole.syslogMode bool"]},{"Name":"const:log","Fields":["log.defaultDebugConsoleEnv"]}]} {"Filepath":"log/backend_syslog.go","Functions":[{"Uniquefunname":"func (b *backendSyslog) close() (err error)","Funname":"close","Returntype":"(err error)","Args":""},{"Uniquefunname":"func (b *backendSyslog) log(level Priority, msg string) (err error)","Funname":"log","Returntype":"(err error)","Args":"level Priority, msg string"},{"Uniquefunname":"func (b *backendSyslog) close() (err error)","Funname":"log.backendSyslog.close","Returntype":"(err error)","Args":""},{"Uniquefunname":"func (b *backendSyslog) log(level Priority, msg string) (err error)","Funname":"log.backendSyslog.log","Returntype":"(err error)","Args":"level Priority, msg string"},{"Uniquefunname":"func newBackendSyslog(name string) (b *backendSyslog)","Funname":"log.newBackendSyslog","Returntype":"(b *backendSyslog)","Args":"name string"},{"Uniquefunname":"func newSyslogWriter(name string) (l *syslog.Writer, err error)","Funname":"log.newSyslogWriter","Returntype":"(l *syslog.Writer, err error)","Args":"name string"},{"Uniquefunname":"func newBackendSyslog(name string) (b *backendSyslog)","Funname":"newBackendSyslog","Returntype":"(b *backendSyslog)","Args":"name string"},{"Uniquefunname":"func newSyslogWriter(name string) (l *syslog.Writer, err error)","Funname":"newSyslogWriter","Returntype":"(l *syslog.Writer, err error)","Args":"name string"}],"Records":[{"Name":"var:log","Fields":["log.SyslogTagPrefix"]},{"Name":"struct:log.backendSyslog","Fields":["log.backendSyslog.name string","log.backendSyslog.writer *syslog.Writer"]},{"Name":"const:log","Fields":["log.defaultSyslogTagPrefix"]}]} {"Filepath":"log/logger.go","Functions":[{"Uniquefunname":"func (l *Logger) AddBackend(b Backend) bool","Funname":"AddBackend","Returntype":"bool","Args":"b Backend"},{"Uniquefunname":"func (l *Logger) AddBackendConsole() bool","Funname":"AddBackendConsole","Returntype":"bool","Args":""},{"Uniquefunname":"func (l *Logger) AddBackendSyslog() bool","Funname":"AddBackendSyslog","Returntype":"bool","Args":""},{"Uniquefunname":"func (l *Logger) AddExtArgForRestart(arg string)","Funname":"AddExtArgForRestart","Returntype":"","Args":"arg string"},{"Uniquefunname":"func (l *Logger) BeginTracing()","Funname":"BeginTracing","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) Debug(v ...interface","Funname":"Debug","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Debugf(format string, v ...interface","Funname":"Debugf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) EndTracing()","Funname":"EndTracing","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) Error(v ...interface","Funname":"Error","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Errorf(format string, v ...interface","Funname":"Errorf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) Fatal(v ...interface","Funname":"Fatal","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Fatalf(format string, v ...interface","Funname":"Fatalf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) GetLogLevel() Priority","Funname":"GetLogLevel","Returntype":"Priority","Args":""},{"Uniquefunname":"func (l *Logger) Info(v ...interface","Funname":"Info","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Infof(format string, v ...interface","Funname":"Infof","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func NewLogger(name string) (l *Logger)","Funname":"NewLogger","Returntype":"(l *Logger)","Args":"name string"},{"Uniquefunname":"func (l *Logger) Panic(v ...interface","Funname":"Panic","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Panicf(format string, v ...interface","Funname":"Panicf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) RemoveBackend(b Backend)","Funname":"RemoveBackend","Returntype":"","Args":"b Backend"},{"Uniquefunname":"func (l *Logger) RemoveBackendConsole()","Funname":"RemoveBackendConsole","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) RemoveBackendSyslog()","Funname":"RemoveBackendSyslog","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) ResetBackends()","Funname":"ResetBackends","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) SetLogLevel(level Priority) *Logger","Funname":"SetLogLevel","Returntype":"*Logger","Args":"level Priority"},{"Uniquefunname":"func (l *Logger) SetRestartCommand(exefile string, args ...string)","Funname":"SetRestartCommand","Returntype":"","Args":"exefile string, args ...string"},{"Uniquefunname":"func (l *Logger) Warning(v ...interface","Funname":"Warning","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Warningf(format string, v ...interface","Funname":"Warningf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func buildFormatMsg(calldepth int, loop bool, format string, v ...interface","Funname":"buildFormatMsg","Returntype":"(msg string)","Args":"calldepth int, loop bool, format string, v ...interface{}"},{"Uniquefunname":"func buildMsg(calldepth int, loop bool, v ...interface","Funname":"buildMsg","Returntype":"(msg string)","Args":"calldepth int, loop bool, v ...interface{}"},{"Uniquefunname":"func doBuildMsg(calldepth int, loop bool, s string) (msg string)","Funname":"doBuildMsg","Returntype":"(msg string)","Args":"calldepth int, loop bool, s string"},{"Uniquefunname":"func (l *Logger) doLog(level Priority, msg string)","Funname":"doLog","Returntype":"","Args":"level Priority, msg string"},{"Uniquefunname":"func (l *Logger) doRemoveBackend(i int)","Funname":"doRemoveBackend","Returntype":"","Args":"i int"},{"Uniquefunname":"func getDefaultLogLevel(name string) (level Priority)","Funname":"getDefaultLogLevel","Returntype":"(level Priority)","Args":"name string"},{"Uniquefunname":"func (l *Logger) isNeedLog(level Priority) bool","Funname":"isNeedLog","Returntype":"bool","Args":"level Priority"},{"Uniquefunname":"func (l *Logger) isNeedTraceMore(level Priority) bool","Funname":"isNeedTraceMore","Returntype":"bool","Args":"level Priority"},{"Uniquefunname":"func (l *Logger) launchCrashReporter()","Funname":"launchCrashReporter","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) log(level Priority, v ...interface","Funname":"log","Returntype":"","Args":"level Priority, v ...interface{}"},{"Uniquefunname":"func (l *Logger) AddBackend(b Backend) bool","Funname":"log.Logger.AddBackend","Returntype":"bool","Args":"b Backend"},{"Uniquefunname":"func (l *Logger) AddBackendConsole() bool","Funname":"log.Logger.AddBackendConsole","Returntype":"bool","Args":""},{"Uniquefunname":"func (l *Logger) AddBackendSyslog() bool","Funname":"log.Logger.AddBackendSyslog","Returntype":"bool","Args":""},{"Uniquefunname":"func (l *Logger) AddExtArgForRestart(arg string)","Funname":"log.Logger.AddExtArgForRestart","Returntype":"","Args":"arg string"},{"Uniquefunname":"func (l *Logger) BeginTracing()","Funname":"log.Logger.BeginTracing","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) Debug(v ...interface","Funname":"log.Logger.Debug","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Debugf(format string, v ...interface","Funname":"log.Logger.Debugf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) EndTracing()","Funname":"log.Logger.EndTracing","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) Error(v ...interface","Funname":"log.Logger.Error","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Errorf(format string, v ...interface","Funname":"log.Logger.Errorf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) Fatal(v ...interface","Funname":"log.Logger.Fatal","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Fatalf(format string, v ...interface","Funname":"log.Logger.Fatalf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) GetLogLevel() Priority","Funname":"log.Logger.GetLogLevel","Returntype":"Priority","Args":""},{"Uniquefunname":"func (l *Logger) Info(v ...interface","Funname":"log.Logger.Info","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Infof(format string, v ...interface","Funname":"log.Logger.Infof","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) Panic(v ...interface","Funname":"log.Logger.Panic","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Panicf(format string, v ...interface","Funname":"log.Logger.Panicf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) RemoveBackend(b Backend)","Funname":"log.Logger.RemoveBackend","Returntype":"","Args":"b Backend"},{"Uniquefunname":"func (l *Logger) RemoveBackendConsole()","Funname":"log.Logger.RemoveBackendConsole","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) RemoveBackendSyslog()","Funname":"log.Logger.RemoveBackendSyslog","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) ResetBackends()","Funname":"log.Logger.ResetBackends","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) SetLogLevel(level Priority) *Logger","Funname":"log.Logger.SetLogLevel","Returntype":"*Logger","Args":"level Priority"},{"Uniquefunname":"func (l *Logger) SetRestartCommand(exefile string, args ...string)","Funname":"log.Logger.SetRestartCommand","Returntype":"","Args":"exefile string, args ...string"},{"Uniquefunname":"func (l *Logger) Warning(v ...interface","Funname":"log.Logger.Warning","Returntype":"","Args":"v ...interface{}"},{"Uniquefunname":"func (l *Logger) Warningf(format string, v ...interface","Funname":"log.Logger.Warningf","Returntype":"","Args":"format string, v ...interface{}"},{"Uniquefunname":"func (l *Logger) doLog(level Priority, msg string)","Funname":"log.Logger.doLog","Returntype":"","Args":"level Priority, msg string"},{"Uniquefunname":"func (l *Logger) doRemoveBackend(i int)","Funname":"log.Logger.doRemoveBackend","Returntype":"","Args":"i int"},{"Uniquefunname":"func (l *Logger) isNeedLog(level Priority) bool","Funname":"log.Logger.isNeedLog","Returntype":"bool","Args":"level Priority"},{"Uniquefunname":"func (l *Logger) isNeedTraceMore(level Priority) bool","Funname":"log.Logger.isNeedTraceMore","Returntype":"bool","Args":"level Priority"},{"Uniquefunname":"func (l *Logger) launchCrashReporter()","Funname":"log.Logger.launchCrashReporter","Returntype":"","Args":""},{"Uniquefunname":"func (l *Logger) log(level Priority, v ...interface","Funname":"log.Logger.log","Returntype":"","Args":"level Priority, v ...interface{}"},{"Uniquefunname":"func (l *Logger) logf(level Priority, format string, v ...interface","Funname":"log.Logger.logf","Returntype":"","Args":"level Priority, format string, v ...interface{}"},{"Uniquefunname":"func NewLogger(name string) (l *Logger)","Funname":"log.NewLogger","Returntype":"(l *Logger)","Args":"name string"},{"Uniquefunname":"func buildFormatMsg(calldepth int, loop bool, format string, v ...interface","Funname":"log.buildFormatMsg","Returntype":"(msg string)","Args":"calldepth int, loop bool, format string, v ...interface{}"},{"Uniquefunname":"func buildMsg(calldepth int, loop bool, v ...interface","Funname":"log.buildMsg","Returntype":"(msg string)","Args":"calldepth int, loop bool, v ...interface{}"},{"Uniquefunname":"func doBuildMsg(calldepth int, loop bool, s string) (msg string)","Funname":"log.doBuildMsg","Returntype":"(msg string)","Args":"calldepth int, loop bool, s string"},{"Uniquefunname":"func getDefaultLogLevel(name string) (level Priority)","Funname":"log.getDefaultLogLevel","Returntype":"(level Priority)","Args":"name string"},{"Uniquefunname":"func matchLogger(name, expr string) bool","Funname":"log.matchLogger","Returntype":"bool","Args":"name, expr string"},{"Uniquefunname":"func (l *Logger) logf(level Priority, format string, v ...interface","Funname":"logf","Returntype":"","Args":"level Priority, format string, v ...interface{}"},{"Uniquefunname":"func matchLogger(name, expr string) bool","Funname":"matchLogger","Returntype":"bool","Args":"name, expr string"}],"Records":[{"Name":"interface","Fields":["log.Backend"]},{"Name":"var:log","Fields":["log.DebugEnv","log.DebugFile","log.DebugLevelEnv","log.DebugMatchEnv","log.errUnknownLogLevel","log.std"]},{"Name":"const:log","Fields":["log.LevelDebug","log.LevelDisable","log.LevelError","log.LevelFatal","log.LevelInfo","log.LevelPanic","log.LevelWarning","log.crashReporterExe","log.defaultDebugEnv","log.defaultDebugFile","log.defaultDebugLelveEnv","log.defaultDebugMatchEnv"]},{"Name":"struct:log.Logger","Fields":["log.Logger.backends []Backend","log.Logger.backendsLock sync.Mutex","log.Logger.config *restartConfig","log.Logger.level Priority","log.Logger.name string"]}]} {"Filepath":"log/logger_test.go","Functions":[{"Uniquefunname":"func (*testWrapper) BenchmarkSyslog(c *C.C)","Funname":"BenchmarkSyslog","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestAddRemoveBackend(c *C.C)","Funname":"TestAddRemoveBackend","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugConsoleEnv(c *C.C)","Funname":"TestDebugConsoleEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugEnv(c *C.C)","Funname":"TestDebugEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugFile(c *C.C)","Funname":"TestDebugFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugLevelEnv(c *C.C)","Funname":"TestDebugLevelEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugMatchEnv(c *C.C)","Funname":"TestDebugMatchEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugMixEnv(c *C.C)","Funname":"TestDebugMixEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestFmtSprint(c *C.C)","Funname":"TestFmtSprint","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestFuncTracing(c *C.C)","Funname":"TestFuncTracing","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGeneral(c *C.C)","Funname":"TestGeneral","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsNeedLog(c *C.C)","Funname":"TestIsNeedLog","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsNeedTraceMore(c *C.C)","Funname":"TestIsNeedTraceMore","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func checkOutput(c *C.C, regfmt string, preferResult bool)","Funname":"checkOutput","Returntype":"","Args":"c *C.C, regfmt string, preferResult bool"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func log.Test(t *testing.T)","Funname":"log.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func checkOutput(c *C.C, regfmt string, preferResult bool)","Funname":"log.checkOutput","Returntype":"","Args":"c *C.C, regfmt string, preferResult bool"},{"Uniquefunname":"func init()","Funname":"log.init","Returntype":"","Args":""},{"Uniquefunname":"func readOutput() string","Funname":"log.readOutput","Returntype":"string","Args":""},{"Uniquefunname":"func redirectOutput()","Funname":"log.redirectOutput","Returntype":"","Args":""},{"Uniquefunname":"func resetOutput()","Funname":"log.resetOutput","Returntype":"","Args":""},{"Uniquefunname":"func restoreOutput()","Funname":"log.restoreOutput","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) BenchmarkSyslog(c *C.C)","Funname":"log.testWrapper.BenchmarkSyslog","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestAddRemoveBackend(c *C.C)","Funname":"log.testWrapper.TestAddRemoveBackend","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugConsoleEnv(c *C.C)","Funname":"log.testWrapper.TestDebugConsoleEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugEnv(c *C.C)","Funname":"log.testWrapper.TestDebugEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugFile(c *C.C)","Funname":"log.testWrapper.TestDebugFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugLevelEnv(c *C.C)","Funname":"log.testWrapper.TestDebugLevelEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugMatchEnv(c *C.C)","Funname":"log.testWrapper.TestDebugMatchEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestDebugMixEnv(c *C.C)","Funname":"log.testWrapper.TestDebugMixEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestFmtSprint(c *C.C)","Funname":"log.testWrapper.TestFmtSprint","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestFuncTracing(c *C.C)","Funname":"log.testWrapper.TestFuncTracing","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGeneral(c *C.C)","Funname":"log.testWrapper.TestGeneral","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsNeedLog(c *C.C)","Funname":"log.testWrapper.TestIsNeedLog","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsNeedTraceMore(c *C.C)","Funname":"log.testWrapper.TestIsNeedTraceMore","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func readOutput() string","Funname":"readOutput","Returntype":"string","Args":""},{"Uniquefunname":"func redirectOutput()","Funname":"redirectOutput","Returntype":"","Args":""},{"Uniquefunname":"func resetOutput()","Funname":"resetOutput","Returntype":"","Args":""},{"Uniquefunname":"func restoreOutput()","Funname":"restoreOutput","Returntype":"","Args":""}],"Records":[{"Name":"var:log","Fields":["log._","log.originStdout","log.redirectStdout","log.redirectStdoutFile"]}]} {"Filepath":"log/restart_config.go","Functions":[{"Uniquefunname":"func newRestartConfig(logname string) *restartConfig","Funname":"log.newRestartConfig","Returntype":"*restartConfig","Args":"logname string"},{"Uniquefunname":"func newRestartConfig(logname string) *restartConfig","Funname":"newRestartConfig","Returntype":"*restartConfig","Args":"logname string"}],"Records":[{"Name":"var:log","Fields":["log.crashReporterArgs"]},{"Name":"struct:log.restartConfig","Fields":["log.restartConfig.AppName string","log.restartConfig.LogDetail string","log.restartConfig.RestartCommand []string","log.restartConfig.RestartDirectory string","log.restartConfig.RestartEnv map[string]string"]}]} {"Filepath":"log/utils.go","Functions":[{"Uniquefunname":"func fmtSprint(v ...interface","Funname":"fmtSprint","Returntype":"(s string)","Args":"v ...interface{}"},{"Uniquefunname":"func isStringInArray(s string, arr []string) bool","Funname":"isStringInArray","Returntype":"bool","Args":"s string, arr []string"},{"Uniquefunname":"func fmtSprint(v ...interface","Funname":"log.fmtSprint","Returntype":"(s string)","Args":"v ...interface{}"},{"Uniquefunname":"func isStringInArray(s string, arr []string) bool","Funname":"log.isStringInArray","Returntype":"bool","Args":"s string, arr []string"}],"Records":null} {"Filepath":"mime/mime.go","Functions":[{"Uniquefunname":"func GetAppList(mime string) []string","Funname":"GetAppList","Returntype":"[]string","Args":"mime string"},{"Uniquefunname":"func GetDefaultApp(mime string, mustSupportURIs bool) (string, error)","Funname":"GetDefaultApp","Returntype":"(string, error)","Args":"mime string, mustSupportURIs bool"},{"Uniquefunname":"func Query(uri string) (string, error)","Funname":"Query","Returntype":"(string, error)","Args":"uri string"},{"Uniquefunname":"func SetDefaultApp(mime, desktopId string) error","Funname":"SetDefaultApp","Returntype":"error","Args":"mime, desktopId string"},{"Uniquefunname":"func doQueryFile(file string) (string, error)","Funname":"doQueryFile","Returntype":"(string, error)","Args":"file string"},{"Uniquefunname":"func GetAppList(mime string) []string","Funname":"mime.GetAppList","Returntype":"[]string","Args":"mime string"},{"Uniquefunname":"func GetDefaultApp(mime string, mustSupportURIs bool) (string, error)","Funname":"mime.GetDefaultApp","Returntype":"(string, error)","Args":"mime string, mustSupportURIs bool"},{"Uniquefunname":"func Query(uri string) (string, error)","Funname":"mime.Query","Returntype":"(string, error)","Args":"uri string"},{"Uniquefunname":"func SetDefaultApp(mime, desktopId string) error","Funname":"mime.SetDefaultApp","Returntype":"error","Args":"mime, desktopId string"},{"Uniquefunname":"func doQueryFile(file string) (string, error)","Funname":"mime.doQueryFile","Returntype":"(string, error)","Args":"file string"}],"Records":[{"Name":"const:mime","Fields":["mime.MimeTypeCursor","mime.MimeTypeGtk","mime.MimeTypeIcon"]}]} {"Filepath":"mime/mime_test.go","Functions":[{"Uniquefunname":"func TestQueryURI(t *testing.T)","Funname":"TestQueryURI","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestQueryURI(t *testing.T)","Funname":"mime.TestQueryURI","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"mime/theme.go","Functions":[{"Uniquefunname":"func isCursorTheme(file string) (bool, error)","Funname":"isCursorTheme","Returntype":"(bool, error)","Args":"file string"},{"Uniquefunname":"func isFilesInDir(files []string, dir string) (bool, error)","Funname":"isFilesInDir","Returntype":"(bool, error)","Args":"files []string, dir string"},{"Uniquefunname":"func isGtkTheme(file string) (bool, error)","Funname":"isGtkTheme","Returntype":"(bool, error)","Args":"file string"},{"Uniquefunname":"func isIconTheme(file string) (bool, error)","Funname":"isIconTheme","Returntype":"(bool, error)","Args":"file string"},{"Uniquefunname":"func isCursorTheme(file string) (bool, error)","Funname":"mime.isCursorTheme","Returntype":"(bool, error)","Args":"file string"},{"Uniquefunname":"func isFilesInDir(files []string, dir string) (bool, error)","Funname":"mime.isFilesInDir","Returntype":"(bool, error)","Args":"files []string, dir string"},{"Uniquefunname":"func isGtkTheme(file string) (bool, error)","Funname":"mime.isGtkTheme","Returntype":"(bool, error)","Args":"file string"},{"Uniquefunname":"func isIconTheme(file string) (bool, error)","Funname":"mime.isIconTheme","Returntype":"(bool, error)","Args":"file string"},{"Uniquefunname":"func queryThemeMime(file string) (string, error)","Funname":"mime.queryThemeMime","Returntype":"(string, error)","Args":"file string"},{"Uniquefunname":"func queryThemeMime(file string) (string, error)","Funname":"queryThemeMime","Returntype":"(string, error)","Args":"file string"}],"Records":[{"Name":"const:mime","Fields":["mime.mimeTypeXCursor"]}]} {"Filepath":"mime/theme_test.go","Functions":[{"Uniquefunname":"func TestIsCursorTheme(t *testing.T)","Funname":"TestIsCursorTheme","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestIsGtkTheme(t *testing.T)","Funname":"TestIsGtkTheme","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestIsIconTheme(t *testing.T)","Funname":"TestIsIconTheme","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestIsCursorTheme(t *testing.T)","Funname":"mime.TestIsCursorTheme","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestIsGtkTheme(t *testing.T)","Funname":"mime.TestIsGtkTheme","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestIsIconTheme(t *testing.T)","Funname":"mime.TestIsIconTheme","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"mobileprovider/mobileprovider.go","Functions":[{"Uniquefunname":"func GetAPN(countryCode, providerName, apnValue, apnUsageType string) (apn *APN, err error)","Funname":"GetAPN","Returntype":"(apn *APN, err error)","Args":"countryCode, providerName, apnValue, apnUsageType string"},{"Uniquefunname":"func GetAPNName(apn *APN) (name string)","Funname":"GetAPNName","Returntype":"(name string)","Args":"apn *APN"},{"Uniquefunname":"func GetAPNUsageType(apn *APN) (usageType string)","Funname":"GetAPNUsageType","Returntype":"(usageType string)","Args":"apn *APN"},{"Uniquefunname":"func GetAllCountryCode() (codeList []string, err error)","Funname":"GetAllCountryCode","Returntype":"(codeList []string, err error)","Args":""},{"Uniquefunname":"func GetCDMA(countryCode, providerName string) (cdma *CDMA, err error)","Funname":"GetCDMA","Returntype":"(cdma *CDMA, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func GetDefaultProvider(countryCode string) (defaultProvider string, err error)","Funname":"GetDefaultProvider","Returntype":"(defaultProvider string, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetGSM(countryCode, providerName string) (gsm *GSM, err error)","Funname":"GetGSM","Returntype":"(gsm *GSM, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func GetGSMForNetworkID(mcc, mnc string) (gsm *GSM, err error)","Funname":"GetGSMForNetworkID","Returntype":"(gsm *GSM, err error)","Args":"mcc, mnc string"},{"Uniquefunname":"func GetMobileProviderDatabase() (*MobileServiceProviderDatabase, error)","Funname":"GetMobileProviderDatabase","Returntype":"(*MobileServiceProviderDatabase, error)","Args":""},{"Uniquefunname":"func GetProvider(countryCode, providerName string) (provider *Provider, err error)","Funname":"GetProvider","Returntype":"(provider *Provider, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func GetProviderNames(countryCode string) (names []string, err error)","Funname":"GetProviderNames","Returntype":"(names []string, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetProviders(countryCode string) (providers []*Provider, err error)","Funname":"GetProviders","Returntype":"(providers []*Provider, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetAPN(countryCode, providerName, apnValue, apnUsageType string) (apn *APN, err error)","Funname":"mobileprovider.GetAPN","Returntype":"(apn *APN, err error)","Args":"countryCode, providerName, apnValue, apnUsageType string"},{"Uniquefunname":"func GetAPNName(apn *APN) (name string)","Funname":"mobileprovider.GetAPNName","Returntype":"(name string)","Args":"apn *APN"},{"Uniquefunname":"func GetAPNUsageType(apn *APN) (usageType string)","Funname":"mobileprovider.GetAPNUsageType","Returntype":"(usageType string)","Args":"apn *APN"},{"Uniquefunname":"func GetAllCountryCode() (codeList []string, err error)","Funname":"mobileprovider.GetAllCountryCode","Returntype":"(codeList []string, err error)","Args":""},{"Uniquefunname":"func GetCDMA(countryCode, providerName string) (cdma *CDMA, err error)","Funname":"mobileprovider.GetCDMA","Returntype":"(cdma *CDMA, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func GetDefaultProvider(countryCode string) (defaultProvider string, err error)","Funname":"mobileprovider.GetDefaultProvider","Returntype":"(defaultProvider string, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetGSM(countryCode, providerName string) (gsm *GSM, err error)","Funname":"mobileprovider.GetGSM","Returntype":"(gsm *GSM, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func GetGSMForNetworkID(mcc, mnc string) (gsm *GSM, err error)","Funname":"mobileprovider.GetGSMForNetworkID","Returntype":"(gsm *GSM, err error)","Args":"mcc, mnc string"},{"Uniquefunname":"func GetMobileProviderDatabase() (*MobileServiceProviderDatabase, error)","Funname":"mobileprovider.GetMobileProviderDatabase","Returntype":"(*MobileServiceProviderDatabase, error)","Args":""},{"Uniquefunname":"func GetProvider(countryCode, providerName string) (provider *Provider, err error)","Funname":"mobileprovider.GetProvider","Returntype":"(provider *Provider, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func GetProviderNames(countryCode string) (names []string, err error)","Funname":"mobileprovider.GetProviderNames","Returntype":"(names []string, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetProviders(countryCode string) (providers []*Provider, err error)","Funname":"mobileprovider.GetProviders","Returntype":"(providers []*Provider, err error)","Args":"countryCode string"}],"Records":[{"Name":"var:mobileprovider","Fields":["mobileprovider.errAPNNotFound","mobileprovider.errCDMANotFound","mobileprovider.errCountryNotFound","mobileprovider.errGSMNotFound","mobileprovider.errPlanNotFound","mobileprovider.errProviderNotFound","mobileprovider.mobileProviderDatabase","mobileprovider.mobileProviderDatabaseLock"]},{"Name":"const:mobileprovider","Fields":["mobileprovider.mobileServiceProvidersXMLFile"]}]} {"Filepath":"mobileprovider/mobileprovider_plan.go","Functions":[{"Uniquefunname":"func GetDefaultCDMAPlanForCountry(countryCode string) (defaultCDMAPlan Plan, err error)","Funname":"GetDefaultCDMAPlanForCountry","Returntype":"(defaultCDMAPlan Plan, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetDefaultGSMPlanForCountry(countryCode string) (defaultGSMPlan Plan, err error)","Funname":"GetDefaultGSMPlanForCountry","Returntype":"(defaultGSMPlan Plan, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetDefaultPlan(countryCode, providerName string) (defaultPlan Plan, err error)","Funname":"GetDefaultPlan","Returntype":"(defaultPlan Plan, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func GetPlans(countryCode, providerName string) (plans []Plan, err error)","Funname":"GetPlans","Returntype":"(plans []Plan, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func MarshalPlan(plan Plan) (jsonStr string)","Funname":"MarshalPlan","Returntype":"(jsonStr string)","Args":"plan Plan"},{"Uniquefunname":"func UnmarshalPlan(jsonStr string) (plan *Plan, err error)","Funname":"UnmarshalPlan","Returntype":"(plan *Plan, err error)","Args":"jsonStr string"},{"Uniquefunname":"func getDefaultGSMInternetPlanForCountry(countryCode string)(defaultGSMInternetPlan Plan, err error)","Funname":"getDefaultGSMInternetPlanForCountry","Returntype":"(defaultGSMInternetPlan Plan, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetDefaultCDMAPlanForCountry(countryCode string) (defaultCDMAPlan Plan, err error)","Funname":"mobileprovider.GetDefaultCDMAPlanForCountry","Returntype":"(defaultCDMAPlan Plan, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetDefaultGSMPlanForCountry(countryCode string) (defaultGSMPlan Plan, err error)","Funname":"mobileprovider.GetDefaultGSMPlanForCountry","Returntype":"(defaultGSMPlan Plan, err error)","Args":"countryCode string"},{"Uniquefunname":"func GetDefaultPlan(countryCode, providerName string) (defaultPlan Plan, err error)","Funname":"mobileprovider.GetDefaultPlan","Returntype":"(defaultPlan Plan, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func GetPlans(countryCode, providerName string) (plans []Plan, err error)","Funname":"mobileprovider.GetPlans","Returntype":"(plans []Plan, err error)","Args":"countryCode, providerName string"},{"Uniquefunname":"func MarshalPlan(plan Plan) (jsonStr string)","Funname":"mobileprovider.MarshalPlan","Returntype":"(jsonStr string)","Args":"plan Plan"},{"Uniquefunname":"func UnmarshalPlan(jsonStr string) (plan *Plan, err error)","Funname":"mobileprovider.UnmarshalPlan","Returntype":"(plan *Plan, err error)","Args":"jsonStr string"},{"Uniquefunname":"func mobileprovider.getDefaultGSMInternetPlanForCountry(countryCode string)(defaultGSMInternetPlan Plan, err error)","Funname":"mobileprovider.getDefaultGSMInternetPlanForCountry","Returntype":"(defaultGSMInternetPlan Plan, err error)","Args":"countryCode string"}],"Records":[{"Name":"struct:mobileprovider.Plan","Fields":["mobileprovider.Plan.APNUsageType string","mobileprovider.Plan.APNValue string","mobileprovider.Plan.IsGSM bool","mobileprovider.Plan.Name string","mobileprovider.Plan.ProviderName string"]}]} {"Filepath":"mobileprovider/mobileprovider_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestGetAPN(c *C.C)","Funname":"TestGetAPN","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetCDMA(c *C.C)","Funname":"TestGetCDMA","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetDefaultCDMAPlanForCountry(c *C.C)","Funname":"TestGetDefaultCDMAPlanForCountry","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetDefaultGSMPlanForCountry(c *C.C)","Funname":"TestGetDefaultGSMPlanForCountry","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetDefaultPlan(c *C.C)","Funname":"TestGetDefaultPlan","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetGSM(c *C.C)","Funname":"TestGetGSM","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetGSMForNetworkID(c *C.C)","Funname":"TestGetGSMForNetworkID","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetPlans(c *C.C)","Funname":"TestGetPlans","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetProvider(c *C.C)","Funname":"TestGetProvider","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetProviderNames(c *C.C)","Funname":"TestGetProviderNames","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetProviders(c *C.C)","Funname":"TestGetProviders","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestMobileProvider(c *C.C)","Funname":"TestMobileProvider","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func mobileprovider.Test(t *testing.T)","Funname":"mobileprovider.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"mobileprovider.init","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) TestGetAPN(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetAPN","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetCDMA(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetCDMA","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetDefaultCDMAPlanForCountry(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetDefaultCDMAPlanForCountry","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetDefaultGSMPlanForCountry(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetDefaultGSMPlanForCountry","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetDefaultPlan(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetDefaultPlan","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetGSM(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetGSM","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetGSMForNetworkID(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetGSMForNetworkID","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetPlans(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetPlans","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetProvider(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetProvider","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetProviderNames(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetProviderNames","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetProviders(c *C.C)","Funname":"mobileprovider.testWrapper.TestGetProviders","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestMobileProvider(c *C.C)","Funname":"mobileprovider.testWrapper.TestMobileProvider","Returntype":"","Args":"c *C.C"}],"Records":null} {"Filepath":"mobileprovider/mobileprovider_type.go","Functions":null,"Records":[{"Name":"struct:mobileprovider.APN","Fields":["mobileprovider.APN.DNS []string","mobileprovider.APN.Gateway string","mobileprovider.APN.MMSC string","mobileprovider.APN.MMSproxy string","mobileprovider.APN.Name []*Name","mobileprovider.APN.Password string","mobileprovider.APN.Plan []*APNPlan","mobileprovider.APN.Usage *Usage","mobileprovider.APN.Username string","mobileprovider.APN.Value string"]},{"Name":"struct:mobileprovider.APNPlan","Fields":["mobileprovider.APNPlan.Type string"]},{"Name":"struct:mobileprovider.BalanceCheck","Fields":["mobileprovider.BalanceCheck.DTMF []string","mobileprovider.BalanceCheck.SMS []*SMS","mobileprovider.BalanceCheck.USSD []*USSD","mobileprovider.BalanceCheck.USSDResponse []string"]},{"Name":"struct:mobileprovider.BalanceTopUp","Fields":["mobileprovider.BalanceTopUp.SMS []*SMS","mobileprovider.BalanceTopUp.USSD []*USSD"]},{"Name":"struct:mobileprovider.CDMA","Fields":["mobileprovider.CDMA.DNS []string","mobileprovider.CDMA.Name []*Name","mobileprovider.CDMA.Password string","mobileprovider.CDMA.SID []*SID","mobileprovider.CDMA.Username string"]},{"Name":"struct:mobileprovider.Country","Fields":["mobileprovider.Country.Code string","mobileprovider.Country.Providers []*Provider"]},{"Name":"struct:mobileprovider.GSM","Fields":["mobileprovider.GSM.APN []*APN","mobileprovider.GSM.BalanceCheck []*BalanceCheck","mobileprovider.GSM.BalanceTopUp []*BalanceTopUp","mobileprovider.GSM.MsisdnQuery []*MsisdnQuery","mobileprovider.GSM.NetworkID []*NetworkID","mobileprovider.GSM.Voicemail []string"]},{"Name":"struct:mobileprovider.MobileServiceProviderDatabase","Fields":["mobileprovider.MobileServiceProviderDatabase.Countries []*Country","mobileprovider.MobileServiceProviderDatabase.Format string"]},{"Name":"struct:mobileprovider.MsisdnQuery","Fields":["mobileprovider.MsisdnQuery.SMS []*SMS","mobileprovider.MsisdnQuery.USSD []*USSD"]},{"Name":"struct:mobileprovider.Name","Fields":["mobileprovider.Name.Body string","mobileprovider.Name.XMLLang string"]},{"Name":"struct:mobileprovider.NetworkID","Fields":["mobileprovider.NetworkID.MCC string","mobileprovider.NetworkID.MNC string"]},{"Name":"const:mobileprovider","Fields":["mobileprovider.PlanTypeValuePostpaid","mobileprovider.PlanTypeValuePrepaid","mobileprovider.ProviderPrimaryValueFalse","mobileprovider.ProviderPrimaryValueTrue","mobileprovider.UsageTypeInternet","mobileprovider.UsageTypeMMS","mobileprovider.UsageTypeWAP"]},{"Name":"struct:mobileprovider.Provider","Fields":["mobileprovider.Provider.CDMA *CDMA","mobileprovider.Provider.GSM *GSM","mobileprovider.Provider.Name *Name","mobileprovider.Provider.Primary ProviderPrimaryValue"]},{"Name":"struct:mobileprovider.SID","Fields":["mobileprovider.SID.Value string"]},{"Name":"struct:mobileprovider.SMS","Fields":["mobileprovider.SMS.Body string","mobileprovider.SMS.Text string"]},{"Name":"struct:mobileprovider.USSD","Fields":["mobileprovider.USSD.Body string","mobileprovider.USSD.Replacement string"]},{"Name":"struct:mobileprovider.Usage","Fields":["mobileprovider.Usage.Type string"]}]} {"Filepath":"multierr/append.go","Functions":[{"Uniquefunname":"func Append(err error, errs ...error) *Error","Funname":"Append","Returntype":"*Error","Args":"err error, errs ...error"},{"Uniquefunname":"func Append(err error, errs ...error) *Error","Funname":"multierr.Append","Returntype":"*Error","Args":"err error, errs ...error"}],"Records":null} {"Filepath":"multierr/append_test.go","Functions":[{"Uniquefunname":"func TestAppend_Error(t *testing.T)","Funname":"TestAppend_Error","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NilError(t *testing.T)","Funname":"TestAppend_NilError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NilErrorArg(t *testing.T)","Funname":"TestAppend_NilErrorArg","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NilErrorIfaceArg(t *testing.T)","Funname":"TestAppend_NilErrorIfaceArg","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NonError(t *testing.T)","Funname":"TestAppend_NonError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NonError_Error(t *testing.T)","Funname":"TestAppend_NonError_Error","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_Error(t *testing.T)","Funname":"multierr.TestAppend_Error","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NilError(t *testing.T)","Funname":"multierr.TestAppend_NilError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NilErrorArg(t *testing.T)","Funname":"multierr.TestAppend_NilErrorArg","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NilErrorIfaceArg(t *testing.T)","Funname":"multierr.TestAppend_NilErrorIfaceArg","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NonError(t *testing.T)","Funname":"multierr.TestAppend_NonError","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAppend_NonError_Error(t *testing.T)","Funname":"multierr.TestAppend_NonError_Error","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"multierr/format.go","Functions":[{"Uniquefunname":"func ListFormatFunc(es []error) string","Funname":"ListFormatFunc","Returntype":"string","Args":"es []error"},{"Uniquefunname":"func ListFormatFunc(es []error) string","Funname":"multierr.ListFormatFunc","Returntype":"string","Args":"es []error"}],"Records":null} {"Filepath":"multierr/format_test.go","Functions":[{"Uniquefunname":"func TestListFormatFuncMultiple(t *testing.T)","Funname":"TestListFormatFuncMultiple","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestListFormatFuncSingle(t *testing.T)","Funname":"TestListFormatFuncSingle","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestListFormatFuncMultiple(t *testing.T)","Funname":"multierr.TestListFormatFuncMultiple","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestListFormatFuncSingle(t *testing.T)","Funname":"multierr.TestListFormatFuncSingle","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"multierr/multierr.go","Functions":[{"Uniquefunname":"func (e *Error) Append(errs ...error)","Funname":"Append","Returntype":"","Args":"errs ...error"},{"Uniquefunname":"func (e *Error) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (e *Error) ErrorOrNil() error","Funname":"ErrorOrNil","Returntype":"error","Args":""},{"Uniquefunname":"func (e *Error) GoString() string","Funname":"GoString","Returntype":"string","Args":""},{"Uniquefunname":"func New() *Error","Funname":"New","Returntype":"*Error","Args":""},{"Uniquefunname":"func (e *Error) WrappedErrors() []error","Funname":"WrappedErrors","Returntype":"[]error","Args":""},{"Uniquefunname":"func (e *Error) Append(errs ...error)","Funname":"multierr.Error.Append","Returntype":"","Args":"errs ...error"},{"Uniquefunname":"func (e *Error) Error() string","Funname":"multierr.Error.Error","Returntype":"string","Args":""},{"Uniquefunname":"func (e *Error) ErrorOrNil() error","Funname":"multierr.Error.ErrorOrNil","Returntype":"error","Args":""},{"Uniquefunname":"func (e *Error) GoString() string","Funname":"multierr.Error.GoString","Returntype":"string","Args":""},{"Uniquefunname":"func (e *Error) WrappedErrors() []error","Funname":"multierr.Error.WrappedErrors","Returntype":"[]error","Args":""},{"Uniquefunname":"func New() *Error","Funname":"multierr.New","Returntype":"*Error","Args":""}],"Records":[{"Name":"struct:multierr.Error","Fields":["multierr.Error.ErrorFormat ErrorFormatFunc","multierr.Error.Errors []error"]}]} {"Filepath":"multierr/multierr_test.go","Functions":[{"Uniquefunname":"func TestErrorErrorOrNil(t *testing.T)","Funname":"TestErrorErrorOrNil","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestErrorError_custom(t *testing.T)","Funname":"TestErrorError_custom","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestErrorError_default(t *testing.T)","Funname":"TestErrorError_default","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestErrorWrappedErrors(t *testing.T)","Funname":"TestErrorWrappedErrors","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestError_Impl(t *testing.T)","Funname":"TestError_Impl","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestErrorErrorOrNil(t *testing.T)","Funname":"multierr.TestErrorErrorOrNil","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestErrorError_custom(t *testing.T)","Funname":"multierr.TestErrorError_custom","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestErrorError_default(t *testing.T)","Funname":"multierr.TestErrorError_default","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestErrorWrappedErrors(t *testing.T)","Funname":"multierr.TestErrorWrappedErrors","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestError_Impl(t *testing.T)","Funname":"multierr.TestError_Impl","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"notify/const.go","Functions":[{"Uniquefunname":"func (i ClosedReason) String() string","Funname":"String","Returntype":"string","Args":""},{"Uniquefunname":"func (i ClosedReason) String() string","Funname":"notify.ClosedReason.String","Returntype":"string","Args":""}],"Records":[{"Name":"const:notify","Fields":["notify.ClosedReasonCallCloseNotification","notify.ClosedReasonDismissedByUser","notify.ClosedReasonExpired","notify.ClosedReasonInvalid","notify.ClosedReasonUnknown","notify.ExpiresDefault","notify.ExpiresMillisecond","notify.ExpiresNever","notify.ExpiresSecond","notify.HintActionIcons","notify.HintCategory","notify.HintDesktopEntry","notify.HintImageData","notify.HintImagePath","notify.HintResident","notify.HintSoundFile","notify.HintSoundName","notify.HintSuppressSound","notify.HintTransient","notify.HintUrgency","notify.HintX","notify.HintY","notify.UrgencyCritical","notify.UrgencyLow","notify.UrgencyNormal","notify.dbusDest","notify.dbusPath"]}]} {"Filepath":"notify/image.go","Functions":[{"Uniquefunname":"func NewImage(src image.Image) *Image","Funname":"NewImage","Returntype":"*Image","Args":"src image.Image"},{"Uniquefunname":"func (n *Notification) SetImage(img image.Image)","Funname":"SetImage","Returntype":"","Args":"img image.Image"},{"Uniquefunname":"func newImageFromRGBA(img *image.RGBA) *Image","Funname":"newImageFromRGBA","Returntype":"*Image","Args":"img *image.RGBA"},{"Uniquefunname":"func NewImage(src image.Image) *Image","Funname":"notify.NewImage","Returntype":"*Image","Args":"src image.Image"},{"Uniquefunname":"func (n *Notification) SetImage(img image.Image)","Funname":"notify.Notification.SetImage","Returntype":"","Args":"img image.Image"},{"Uniquefunname":"func newImageFromRGBA(img *image.RGBA) *Image","Funname":"notify.newImageFromRGBA","Returntype":"*Image","Args":"img *image.RGBA"},{"Uniquefunname":"func toRGBA(src image.Image) *image.RGBA","Funname":"notify.toRGBA","Returntype":"*image.RGBA","Args":"src image.Image"},{"Uniquefunname":"func toRGBA(src image.Image) *image.RGBA","Funname":"toRGBA","Returntype":"*image.RGBA","Args":"src image.Image"}],"Records":[{"Name":"struct:notify.Image","Fields":["notify.Image.BitsPerSample int32","notify.Image.Channels int32","notify.Image.HasAlpha bool","notify.Image.Height int32","notify.Image.Pix []byte","notify.Image.RowStride int32","notify.Image.Width int32"]}]} {"Filepath":"notify/notification.go","Functions":[{"Uniquefunname":"func (n *Notification) AddAction(action, label string, callback ActionCallback)","Funname":"AddAction","Returntype":"","Args":"action, label string, callback ActionCallback"},{"Uniquefunname":"func (n *Notification) ClearActions()","Funname":"ClearActions","Returntype":"","Args":""},{"Uniquefunname":"func (n *Notification) ClearHints()","Funname":"ClearHints","Returntype":"","Args":""},{"Uniquefunname":"func (n *Notification) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (n *Notification) Closed() *event.Event","Funname":"Closed","Returntype":"*event.Event","Args":""},{"Uniquefunname":"func (n *Notification) Destroy()","Funname":"Destroy","Returntype":"","Args":""},{"Uniquefunname":"func (n *Notification) GetClosedReason() ClosedReason","Funname":"GetClosedReason","Returntype":"ClosedReason","Args":""},{"Uniquefunname":"func NewNotification(summary, body, icon string) *Notification","Funname":"NewNotification","Returntype":"*Notification","Args":"summary, body, icon string"},{"Uniquefunname":"func (n *Notification) SetCategory(category string)","Funname":"SetCategory","Returntype":"","Args":"category string"},{"Uniquefunname":"func (n *Notification) SetHint(key string, value interface","Funname":"SetHint","Returntype":"","Args":"key string, value interface{}"},{"Uniquefunname":"func (n *Notification) SetUrgency(urgency byte)","Funname":"SetUrgency","Returntype":"","Args":"urgency byte"},{"Uniquefunname":"func (n *Notification) Show() error","Funname":"Show","Returntype":"error","Args":""},{"Uniquefunname":"func (n *Notification) Update(summary, body, icon string)","Funname":"Update","Returntype":"","Args":"summary, body, icon string"},{"Uniquefunname":"func (n *Notification) getAppName() string","Funname":"getAppName","Returntype":"string","Args":""},{"Uniquefunname":"func NewNotification(summary, body, icon string) *Notification","Funname":"notify.NewNotification","Returntype":"*Notification","Args":"summary, body, icon string"},{"Uniquefunname":"func (n *Notification) AddAction(action, label string, callback ActionCallback)","Funname":"notify.Notification.AddAction","Returntype":"","Args":"action, label string, callback ActionCallback"},{"Uniquefunname":"func (n *Notification) ClearActions()","Funname":"notify.Notification.ClearActions","Returntype":"","Args":""},{"Uniquefunname":"func (n *Notification) ClearHints()","Funname":"notify.Notification.ClearHints","Returntype":"","Args":""},{"Uniquefunname":"func (n *Notification) Close() error","Funname":"notify.Notification.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (n *Notification) Closed() *event.Event","Funname":"notify.Notification.Closed","Returntype":"*event.Event","Args":""},{"Uniquefunname":"func (n *Notification) Destroy()","Funname":"notify.Notification.Destroy","Returntype":"","Args":""},{"Uniquefunname":"func (n *Notification) GetClosedReason() ClosedReason","Funname":"notify.Notification.GetClosedReason","Returntype":"ClosedReason","Args":""},{"Uniquefunname":"func (n *Notification) SetCategory(category string)","Funname":"notify.Notification.SetCategory","Returntype":"","Args":"category string"},{"Uniquefunname":"func (n *Notification) SetHint(key string, value interface","Funname":"notify.Notification.SetHint","Returntype":"","Args":"key string, value interface{}"},{"Uniquefunname":"func (n *Notification) SetUrgency(urgency byte)","Funname":"notify.Notification.SetUrgency","Returntype":"","Args":"urgency byte"},{"Uniquefunname":"func (n *Notification) Show() error","Funname":"notify.Notification.Show","Returntype":"error","Args":""},{"Uniquefunname":"func (n *Notification) Update(summary, body, icon string)","Funname":"notify.Notification.Update","Returntype":"","Args":"summary, body, icon string"},{"Uniquefunname":"func (n *Notification) getAppName() string","Funname":"notify.Notification.getAppName","Returntype":"string","Args":""}],"Records":[{"Name":"struct:notify.Notification","Fields":["notify.Notification.AppName string","notify.Notification.Body string","notify.Notification.Icon string","notify.Notification.Summary string","notify.Notification.Timeout int32","notify.Notification.actionInvokedConnectRet func()","notify.Notification.actionMap map[string]ActionCallback","notify.Notification.actions []string","notify.Notification.closed *event.Event","notify.Notification.closedReason ClosedReason","notify.Notification.hints _HintMap","notify.Notification.id uint32","notify.Notification.mu sync.Mutex","notify.Notification.notificationClosedConnectRet func()"]}]} {"Filepath":"notify/notify.go","Functions":[{"Uniquefunname":"func Destroy()","Funname":"Destroy","Returntype":"","Args":""},{"Uniquefunname":"func GetAppName() string","Funname":"GetAppName","Returntype":"string","Args":""},{"Uniquefunname":"func GetServerCaps() ([]string, error)","Funname":"GetServerCaps","Returntype":"([]string, error)","Args":""},{"Uniquefunname":"func GetServerInfo() (*ServerInfo, error)","Funname":"GetServerInfo","Returntype":"(*ServerInfo, error)","Args":""},{"Uniquefunname":"func Init(appName string) bool","Funname":"Init","Returntype":"bool","Args":"appName string"},{"Uniquefunname":"func IsInitted() bool","Funname":"IsInitted","Returntype":"bool","Args":""},{"Uniquefunname":"func SetAppName(name string)","Funname":"SetAppName","Returntype":"","Args":"name string"},{"Uniquefunname":"func Destroy()","Funname":"notify.Destroy","Returntype":"","Args":""},{"Uniquefunname":"func GetAppName() string","Funname":"notify.GetAppName","Returntype":"string","Args":""},{"Uniquefunname":"func GetServerCaps() ([]string, error)","Funname":"notify.GetServerCaps","Returntype":"([]string, error)","Args":""},{"Uniquefunname":"func GetServerInfo() (*ServerInfo, error)","Funname":"notify.GetServerInfo","Returntype":"(*ServerInfo, error)","Args":""},{"Uniquefunname":"func Init(appName string) bool","Funname":"notify.Init","Returntype":"bool","Args":"appName string"},{"Uniquefunname":"func IsInitted() bool","Funname":"notify.IsInitted","Returntype":"bool","Args":""},{"Uniquefunname":"func SetAppName(name string)","Funname":"notify.SetAppName","Returntype":"","Args":"name string"}],"Records":[{"Name":"struct:notify.ServerInfo","Fields":["notify.ServerInfo.Name string","notify.ServerInfo.SpecVersion string","notify.ServerInfo.Vendor string","notify.ServerInfo.Version string"]},{"Name":"var:notify","Fields":["notify.defaultAppName","notify.isInitted","notify.notifier"]}]} {"Filepath":"notify/dbusnotify/init.go","Functions":[{"Uniquefunname":"func dbusAddMatch(rule string) (err error)","Funname":"dbusAddMatch","Returntype":"(err error)","Args":"rule string"},{"Uniquefunname":"func dbusCall(method string, flags dbus.Flags, args ...interface","Funname":"dbusCall","Returntype":"(err error)","Args":"method string, flags dbus.Flags, args ...interface{}"},{"Uniquefunname":"func dbusRemoveMatch(rule string) (err error)","Funname":"dbusRemoveMatch","Returntype":"(err error)","Args":"rule string"},{"Uniquefunname":"func dbusAddMatch(rule string) (err error)","Funname":"dbusnotify.dbusAddMatch","Returntype":"(err error)","Args":"rule string"},{"Uniquefunname":"func dbusCall(method string, flags dbus.Flags, args ...interface","Funname":"dbusnotify.dbusCall","Returntype":"(err error)","Args":"method string, flags dbus.Flags, args ...interface{}"},{"Uniquefunname":"func dbusRemoveMatch(rule string) (err error)","Funname":"dbusnotify.dbusRemoveMatch","Returntype":"(err error)","Args":"rule string"},{"Uniquefunname":"func getBus() *dbus.Conn","Funname":"dbusnotify.getBus","Returntype":"*dbus.Conn","Args":""},{"Uniquefunname":"func getRuleCounter() map[string]int","Funname":"dbusnotify.getRuleCounter","Returntype":"map[string]int","Args":""},{"Uniquefunname":"func getBus() *dbus.Conn","Funname":"getBus","Returntype":"*dbus.Conn","Args":""},{"Uniquefunname":"func getRuleCounter() map[string]int","Funname":"getRuleCounter","Returntype":"map[string]int","Args":""}],"Records":[{"Name":"var:dbusnotify","Fields":["dbusnotify.__conn","dbusnotify.__connLock","dbusnotify.__ruleCounter","dbusnotify.__ruleCounterLock"]}]} {"Filepath":"notify/dbusnotify/notify.go","Functions":[{"Uniquefunname":"func (obj *Notifier) CloseNotification(id uint32) (_err error)","Funname":"CloseNotification","Returntype":"(_err error)","Args":"id uint32"},{"Uniquefunname":"func (obj *Notifier) ConnectActionInvoked(callback func(id uint32, action_key string)) func()","Funname":"ConnectActionInvoked","Returntype":"func()","Args":"callback func(id uint32, action_key string)"},{"Uniquefunname":"func (obj *Notifier) ConnectNotificationClosed(callback func(id uint32, reason uint32)) func()","Funname":"ConnectNotificationClosed","Returntype":"func()","Args":"callback func(id uint32, reason uint32)"},{"Uniquefunname":"func DestroyNotifier(obj *Notifier)","Funname":"DestroyNotifier","Returntype":"","Args":"obj *Notifier"},{"Uniquefunname":"func (obj *Notifier) GetCapabilities() (caps []string, _err error)","Funname":"GetCapabilities","Returntype":"(caps []string, _err error)","Args":""},{"Uniquefunname":"func GetServerInformation()(name string, vendor string, version string, spec_version string, _err error)","Funname":"GetServerInformation","Returntype":"(name string, vendor string, version string, spec_version string, _err error)","Args":""},{"Uniquefunname":"func NewNotifier(destName string, path dbus.ObjectPath) (*Notifier, error)","Funname":"NewNotifier","Returntype":"(*Notifier, error)","Args":"destName string, path dbus.ObjectPath"},{"Uniquefunname":"func Notify(app_name string, id uint32, icon string, summary string, body string, actions []string, hints map[string]dbus.Variant, timeout int32)(id_ uint32, _err error)","Funname":"Notify","Returntype":"(id_ uint32, _err error)","Args":"app_name string, id uint32, icon string, summary string, body string, actions []string, hints map[string]dbus.Variant, timeout int32"},{"Uniquefunname":"func (obj *Notifier) _createSignalChan() chan *dbus.Signal","Funname":"_createSignalChan","Returntype":"chan *dbus.Signal","Args":""},{"Uniquefunname":"func (obj *Notifier) _deleteSignalChan(ch chan *dbus.Signal)","Funname":"_deleteSignalChan","Returntype":"","Args":"ch chan *dbus.Signal"},{"Uniquefunname":"func DestroyNotifier(obj *Notifier)","Funname":"dbusnotify.DestroyNotifier","Returntype":"","Args":"obj *Notifier"},{"Uniquefunname":"func NewNotifier(destName string, path dbus.ObjectPath) (*Notifier, error)","Funname":"dbusnotify.NewNotifier","Returntype":"(*Notifier, error)","Args":"destName string, path dbus.ObjectPath"},{"Uniquefunname":"func (obj *Notifier) CloseNotification(id uint32) (_err error)","Funname":"dbusnotify.Notifier.CloseNotification","Returntype":"(_err error)","Args":"id uint32"},{"Uniquefunname":"func (obj *Notifier) ConnectActionInvoked(callback func(id uint32, action_key string)) func()","Funname":"dbusnotify.Notifier.ConnectActionInvoked","Returntype":"func()","Args":"callback func(id uint32, action_key string)"},{"Uniquefunname":"func (obj *Notifier) ConnectNotificationClosed(callback func(id uint32, reason uint32)) func()","Funname":"dbusnotify.Notifier.ConnectNotificationClosed","Returntype":"func()","Args":"callback func(id uint32, reason uint32)"},{"Uniquefunname":"func (obj *Notifier) GetCapabilities() (caps []string, _err error)","Funname":"dbusnotify.Notifier.GetCapabilities","Returntype":"(caps []string, _err error)","Args":""},{"Uniquefunname":"func dbusnotify.Notifier.GetServerInformation()(name string, vendor string, version string, spec_version string, _err error)","Funname":"dbusnotify.Notifier.GetServerInformation","Returntype":"(name string, vendor string, version string, spec_version string, _err error)","Args":""},{"Uniquefunname":"func dbusnotify.Notifier.Notify(app_name string, id uint32, icon string, summary string, body string, actions []string, hints map[string]dbus.Variant, timeout int32)(id_ uint32, _err error)","Funname":"dbusnotify.Notifier.Notify","Returntype":"(id_ uint32, _err error)","Args":"app_name string, id uint32, icon string, summary string, body string, actions []string, hints map[string]dbus.Variant, timeout int32"},{"Uniquefunname":"func (obj *Notifier) _createSignalChan() chan *dbus.Signal","Funname":"dbusnotify.Notifier._createSignalChan","Returntype":"chan *dbus.Signal","Args":""},{"Uniquefunname":"func (obj *Notifier) _deleteSignalChan(ch chan *dbus.Signal)","Funname":"dbusnotify.Notifier._deleteSignalChan","Returntype":"","Args":"ch chan *dbus.Signal"}],"Records":[{"Name":"struct:dbusnotify.Notifier","Fields":["dbusnotify.Notifier.DestName string","dbusnotify.Notifier.Path dbus.ObjectPath","dbusnotify.Notifier.core dbus.BusObject","dbusnotify.Notifier.signals map[chan *dbus.Signal]struct{}","dbusnotify.Notifier.signalsLocker sync.Mutex"]},{"Name":"var:dbusnotify","Fields":["dbusnotify._","dbusnotify._","dbusnotify._","dbusnotify._"]}]} {"Filepath":"notify/examples/action.go","Functions":[{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func main()","Funname":"main","Returntype":"","Args":""},{"Uniquefunname":"func init()","Funname":"main.init","Returntype":"","Args":""},{"Uniquefunname":"func main()","Funname":"main.main","Returntype":"","Args":""},{"Uniquefunname":"func show()","Funname":"main.show","Returntype":"","Args":""},{"Uniquefunname":"func show()","Funname":"show","Returntype":"","Args":""}],"Records":null} {"Filepath":"notify/examples/image.go","Functions":[{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func loadImage(filename string) (image.Image, error)","Funname":"loadImage","Returntype":"(image.Image, error)","Args":"filename string"},{"Uniquefunname":"func main()","Funname":"main","Returntype":"","Args":""},{"Uniquefunname":"func init()","Funname":"main.init","Returntype":"","Args":""},{"Uniquefunname":"func loadImage(filename string) (image.Image, error)","Funname":"main.loadImage","Returntype":"(image.Image, error)","Args":"filename string"},{"Uniquefunname":"func main()","Funname":"main.main","Returntype":"","Args":""},{"Uniquefunname":"func show(filename string)","Funname":"main.show","Returntype":"","Args":"filename string"},{"Uniquefunname":"func show(filename string)","Funname":"show","Returntype":"","Args":"filename string"}],"Records":null} {"Filepath":"notify/examples/simple.go","Functions":[{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func main()","Funname":"main","Returntype":"","Args":""},{"Uniquefunname":"func init()","Funname":"main.init","Returntype":"","Args":""},{"Uniquefunname":"func main()","Funname":"main.main","Returntype":"","Args":""}],"Records":null} {"Filepath":"notify/examples/update.go","Functions":[{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func main()","Funname":"main","Returntype":"","Args":""},{"Uniquefunname":"func init()","Funname":"main.init","Returntype":"","Args":""},{"Uniquefunname":"func main()","Funname":"main.main","Returntype":"","Args":""}],"Records":null} {"Filepath":"pam/handler.go","Functions":[{"Uniquefunname":"func (f ConversationFunc) RespondPAM(s Style, msg string) (string, error)","Funname":"RespondPAM","Returntype":"(string, error)","Args":"s Style, msg string"},{"Uniquefunname":"func addHandler(handler ConversationHandler) handlerId","Funname":"addHandler","Returntype":"handlerId","Args":"handler ConversationHandler"},{"Uniquefunname":"func deleteHandler(id handlerId)","Funname":"deleteHandler","Returntype":"","Args":"id handlerId"},{"Uniquefunname":"func getHandler(id handlerId) ConversationHandler","Funname":"getHandler","Returntype":"ConversationHandler","Args":"id handlerId"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func (f ConversationFunc) RespondPAM(s Style, msg string) (string, error)","Funname":"pam.ConversationFunc.RespondPAM","Returntype":"(string, error)","Args":"s Style, msg string"},{"Uniquefunname":"func addHandler(handler ConversationHandler) handlerId","Funname":"pam.addHandler","Returntype":"handlerId","Args":"handler ConversationHandler"},{"Uniquefunname":"func deleteHandler(id handlerId)","Funname":"pam.deleteHandler","Returntype":"","Args":"id handlerId"},{"Uniquefunname":"func getHandler(id handlerId) ConversationHandler","Funname":"pam.getHandler","Returntype":"ConversationHandler","Args":"id handlerId"},{"Uniquefunname":"func init()","Funname":"pam.init","Returntype":"","Args":""}],"Records":[{"Name":"interface","Fields":["pam.ConversationHandler"]},{"Name":"var:pam","Fields":["pam.globalHandlers"]}]} {"Filepath":"pam/pam.go","Functions":[{"Uniquefunname":"func (h *Transaction) AccountValidManagement(flags Flags) error","Funname":"AccountValidManagement","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) Authenticate(flags Flags) error","Funname":"Authenticate","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) ChangeAuthToken(flags Flags) error","Funname":"ChangeAuthToken","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) CloseSession(flags Flags) error","Funname":"CloseSession","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) DeleteEnv(name string) error","Funname":"DeleteEnv","Returntype":"error","Args":"name string"},{"Uniquefunname":"func (h *Transaction) End(lastStatus int) error","Funname":"End","Returntype":"error","Args":"lastStatus int"},{"Uniquefunname":"func (err Error) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (h *Transaction) GetEnv(name string) string","Funname":"GetEnv","Returntype":"string","Args":"name string"},{"Uniquefunname":"func (h *Transaction) GetEnvList() map[string]string","Funname":"GetEnvList","Returntype":"map[string]string","Args":""},{"Uniquefunname":"func (h *Transaction) GetItemStr(itemType Item) (string, error)","Funname":"GetItemStr","Returntype":"(string, error)","Args":"itemType Item"},{"Uniquefunname":"func (h *Transaction) LastStatus() int","Funname":"LastStatus","Returntype":"int","Args":""},{"Uniquefunname":"func (h *Transaction) OpenSession(flags Flags) error","Funname":"OpenSession","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) PutEnv(name, value string) error","Funname":"PutEnv","Returntype":"error","Args":"name, value string"},{"Uniquefunname":"func (h *Transaction) SetCredentials(flags Flags) error","Funname":"SetCredentials","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) SetItemStr(itemType Item, item string) error","Funname":"SetItemStr","Returntype":"error","Args":"itemType Item, item string"},{"Uniquefunname":"func Start(service, user string, handler ConversationHandler) (*Transaction, error)","Funname":"Start","Returntype":"(*Transaction, error)","Args":"service, user string, handler ConversationHandler"},{"Uniquefunname":"func StartFunc(service, user string, handler func(Style, string) (string, error))(*Transaction, error)","Funname":"StartFunc","Returntype":"(*Transaction, error)","Args":"service, user string, handler func(Style, string) (string, error)"},{"Uniquefunname":"func cbPAMConv(style C.int, msg *C.char, id C.long, resp **C.char) C.int","Funname":"cbPAMConv","Returntype":"C.int","Args":"style C.int, msg *C.char, id C.long, resp **C.char"},{"Uniquefunname":"func next(p **C.char) **C.char","Funname":"next","Returntype":"**C.char","Args":"p **C.char"},{"Uniquefunname":"func (err Error) Error() string","Funname":"pam.Error.Error","Returntype":"string","Args":""},{"Uniquefunname":"func Start(service, user string, handler ConversationHandler) (*Transaction, error)","Funname":"pam.Start","Returntype":"(*Transaction, error)","Args":"service, user string, handler ConversationHandler"},{"Uniquefunname":"func pam.StartFunc(service, user string, handler func(Style, string) (string, error))(*Transaction, error)","Funname":"pam.StartFunc","Returntype":"(*Transaction, error)","Args":"service, user string, handler func(Style, string) (string, error)"},{"Uniquefunname":"func (h *Transaction) AccountValidManagement(flags Flags) error","Funname":"pam.Transaction.AccountValidManagement","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) Authenticate(flags Flags) error","Funname":"pam.Transaction.Authenticate","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) ChangeAuthToken(flags Flags) error","Funname":"pam.Transaction.ChangeAuthToken","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) CloseSession(flags Flags) error","Funname":"pam.Transaction.CloseSession","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) DeleteEnv(name string) error","Funname":"pam.Transaction.DeleteEnv","Returntype":"error","Args":"name string"},{"Uniquefunname":"func (h *Transaction) End(lastStatus int) error","Funname":"pam.Transaction.End","Returntype":"error","Args":"lastStatus int"},{"Uniquefunname":"func (h *Transaction) GetEnv(name string) string","Funname":"pam.Transaction.GetEnv","Returntype":"string","Args":"name string"},{"Uniquefunname":"func (h *Transaction) GetEnvList() map[string]string","Funname":"pam.Transaction.GetEnvList","Returntype":"map[string]string","Args":""},{"Uniquefunname":"func (h *Transaction) GetItemStr(itemType Item) (string, error)","Funname":"pam.Transaction.GetItemStr","Returntype":"(string, error)","Args":"itemType Item"},{"Uniquefunname":"func (h *Transaction) LastStatus() int","Funname":"pam.Transaction.LastStatus","Returntype":"int","Args":""},{"Uniquefunname":"func (h *Transaction) OpenSession(flags Flags) error","Funname":"pam.Transaction.OpenSession","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) PutEnv(name, value string) error","Funname":"pam.Transaction.PutEnv","Returntype":"error","Args":"name, value string"},{"Uniquefunname":"func (h *Transaction) SetCredentials(flags Flags) error","Funname":"pam.Transaction.SetCredentials","Returntype":"error","Args":"flags Flags"},{"Uniquefunname":"func (h *Transaction) SetItemStr(itemType Item, item string) error","Funname":"pam.Transaction.SetItemStr","Returntype":"error","Args":"itemType Item, item string"},{"Uniquefunname":"func (h *Transaction) toErr(errNum C.int) error","Funname":"pam.Transaction.toErr","Returntype":"error","Args":"errNum C.int"},{"Uniquefunname":"func cbPAMConv(style C.int, msg *C.char, id C.long, resp **C.char) C.int","Funname":"pam.cbPAMConv","Returntype":"C.int","Args":"style C.int, msg *C.char, id C.long, resp **C.char"},{"Uniquefunname":"func next(p **C.char) **C.char","Funname":"pam.next","Returntype":"**C.char","Args":"p **C.char"},{"Uniquefunname":"func (h *Transaction) toErr(errNum C.int) error","Funname":"toErr","Returntype":"error","Args":"errNum C.int"}],"Records":[{"Name":"const:pam","Fields":["pam.Authtok","pam.ChangeExpiredAuthtok","pam.DeleteCred","pam.DisallowNullAuthtok","pam.ErrorMsg","pam.EstablishCred","pam.Oldauthtok","pam.PromptEchoOff","pam.PromptEchoOn","pam.RefreshCred","pam.ReinitializeCred","pam.Rhost","pam.Ruser","pam.Service","pam.Silent","pam.TextInfo","pam.Tty","pam.User","pam.UserPrompt"]},{"Name":"struct:pam.Error","Fields":["pam.Error.Code int","pam.Error.Msg string"]},{"Name":"struct:pam.Transaction","Fields":["pam.Transaction.handlerId handlerId","pam.Transaction.ptr *C.pam_handle_t","pam.Transaction.status C.int"]}]} {"Filepath":"pinyin/datas.go","Functions":null,"Records":[{"Name":"var:pinyin","Fields":["pinyin.PinyinDataMap"]}]} {"Filepath":"pinyin/pinyin.go","Functions":[{"Uniquefunname":"func HansToPinyin(hans string) []string","Funname":"HansToPinyin","Returntype":"[]string","Args":"hans string"},{"Uniquefunname":"func getPinyinByHan(han int64) []string","Funname":"getPinyinByHan","Returntype":"[]string","Args":"han int64"},{"Uniquefunname":"func getPinyinFromKey(key string) []string","Funname":"getPinyinFromKey","Returntype":"[]string","Args":"key string"},{"Uniquefunname":"func HansToPinyin(hans string) []string","Funname":"pinyin.HansToPinyin","Returntype":"[]string","Args":"hans string"},{"Uniquefunname":"func getPinyinByHan(han int64) []string","Funname":"pinyin.getPinyinByHan","Returntype":"[]string","Args":"han int64"},{"Uniquefunname":"func getPinyinFromKey(key string) []string","Funname":"pinyin.getPinyinFromKey","Returntype":"[]string","Args":"key string"},{"Uniquefunname":"func rangeArray(a1, a2 []string) []string","Funname":"pinyin.rangeArray","Returntype":"[]string","Args":"a1, a2 []string"},{"Uniquefunname":"func rangeArray(a1, a2 []string) []string","Funname":"rangeArray","Returntype":"[]string","Args":"a1, a2 []string"}],"Records":null} {"Filepath":"pinyin_search/pinyin_search.go","Functions":[{"Uniquefunname":"func GeneralizeQuery(q string) string","Funname":"GeneralizeQuery","Returntype":"string","Args":"q string"},{"Uniquefunname":"func (blocks Blocks) Match(query string) bool","Funname":"Match","Returntype":"bool","Args":"query string"},{"Uniquefunname":"func Split(str string) Blocks","Funname":"Split","Returntype":"Blocks","Args":"str string"},{"Uniquefunname":"func (zb zhBlock) getList() []string","Funname":"getList","Returntype":"[]string","Args":""},{"Uniquefunname":"func getPyList(py string) []string","Funname":"getPyList","Returntype":"[]string","Args":"py string"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func (c commonBlock) isBlock()","Funname":"isBlock","Returntype":"","Args":""},{"Uniquefunname":"func (zb zhBlock) isBlock()","Funname":"isBlock","Returntype":"","Args":""},{"Uniquefunname":"func matchAux(target, query string) (isMatch bool, end bool, n int)","Funname":"matchAux","Returntype":"(isMatch bool, end bool, n int)","Args":"target, query string"},{"Uniquefunname":"func matchBegin(blocks []block, query string) (result bool)","Funname":"matchBegin","Returntype":"(result bool)","Args":"blocks []block, query string"},{"Uniquefunname":"func (blocks Blocks) Match(query string) bool","Funname":"pinyin_search.Blocks.Match","Returntype":"bool","Args":"query string"},{"Uniquefunname":"func GeneralizeQuery(q string) string","Funname":"pinyin_search.GeneralizeQuery","Returntype":"string","Args":"q string"},{"Uniquefunname":"func Split(str string) Blocks","Funname":"pinyin_search.Split","Returntype":"Blocks","Args":"str string"},{"Uniquefunname":"func (c commonBlock) isBlock()","Funname":"pinyin_search.commonBlock.isBlock","Returntype":"","Args":""},{"Uniquefunname":"func getPyList(py string) []string","Funname":"pinyin_search.getPyList","Returntype":"[]string","Args":"py string"},{"Uniquefunname":"func init()","Funname":"pinyin_search.init","Returntype":"","Args":""},{"Uniquefunname":"func matchAux(target, query string) (isMatch bool, end bool, n int)","Funname":"pinyin_search.matchAux","Returntype":"(isMatch bool, end bool, n int)","Args":"target, query string"},{"Uniquefunname":"func matchBegin(blocks []block, query string) (result bool)","Funname":"pinyin_search.matchBegin","Returntype":"(result bool)","Args":"blocks []block, query string"},{"Uniquefunname":"func strSliceUniq(slice []string) []string","Funname":"pinyin_search.strSliceUniq","Returntype":"[]string","Args":"slice []string"},{"Uniquefunname":"func strSliceUniqAux(in []string) []string","Funname":"pinyin_search.strSliceUniqAux","Returntype":"[]string","Args":"in []string"},{"Uniquefunname":"func (zb zhBlock) getList() []string","Funname":"pinyin_search.zhBlock.getList","Returntype":"[]string","Args":""},{"Uniquefunname":"func (zb zhBlock) isBlock()","Funname":"pinyin_search.zhBlock.isBlock","Returntype":"","Args":""},{"Uniquefunname":"func strSliceUniq(slice []string) []string","Funname":"strSliceUniq","Returntype":"[]string","Args":"slice []string"},{"Uniquefunname":"func strSliceUniqAux(in []string) []string","Funname":"strSliceUniqAux","Returntype":"[]string","Args":"in []string"}],"Records":[{"Name":"interface","Fields":["pinyin_search.block"]},{"Name":"var:pinyin_search","Fields":["pinyin_search.pinyinArgs"]},{"Name":"struct:pinyin_search.zhBlock","Fields":["pinyin_search.zhBlock.pys []string","pinyin_search.zhBlock.zh rune"]}]} {"Filepath":"pinyin_search/t1_test.go","Functions":[{"Uniquefunname":"func TestGeneralize(t *testing.T)","Funname":"TestGeneralize","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMatch(t *testing.T)","Funname":"TestMatch","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSplit(t *testing.T)","Funname":"TestSplit","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_getPyList(t *testing.T)","Funname":"Test_getPyList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_matchAux(t *testing.T)","Funname":"Test_matchAux","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_matchBegin(t *testing.T)","Funname":"Test_matchBegin","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_strSliceUniq(t *testing.T)","Funname":"Test_strSliceUniq","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGeneralize(t *testing.T)","Funname":"pinyin_search.TestGeneralize","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestMatch(t *testing.T)","Funname":"pinyin_search.TestMatch","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestSplit(t *testing.T)","Funname":"pinyin_search.TestSplit","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_getPyList(t *testing.T)","Funname":"pinyin_search.Test_getPyList","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_matchAux(t *testing.T)","Funname":"pinyin_search.Test_matchAux","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_matchBegin(t *testing.T)","Funname":"pinyin_search.Test_matchBegin","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func Test_strSliceUniq(t *testing.T)","Funname":"pinyin_search.Test_strSliceUniq","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"procfs/procfs.go","Functions":[{"Uniquefunname":"func (p Process) Cmdline() ([]string, error)","Funname":"Cmdline","Returntype":"([]string, error)","Args":""},{"Uniquefunname":"func (p Process) Cwd() (string, error)","Funname":"Cwd","Returntype":"(string, error)","Args":""},{"Uniquefunname":"func (p Process) Environ() (EnvVars, error)","Funname":"Environ","Returntype":"(EnvVars, error)","Args":""},{"Uniquefunname":"func (err StatusFieldNotFoundErr) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (p Process) Exe() (string, error)","Funname":"Exe","Returntype":"(string, error)","Args":""},{"Uniquefunname":"func (p Process) Exist() bool","Funname":"Exist","Returntype":"bool","Args":""},{"Uniquefunname":"func (vars EnvVars) Get(key string) string","Funname":"Get","Returntype":"string","Args":"key string"},{"Uniquefunname":"func (vars EnvVars) Lookup(key string) (string, bool)","Funname":"Lookup","Returntype":"(string, bool)","Args":"key string"},{"Uniquefunname":"func (st Status) PPid() (uint, error)","Funname":"PPid","Returntype":"(uint, error)","Args":""},{"Uniquefunname":"func (p Process) Status() (Status, error)","Funname":"Status","Returntype":"(Status, error)","Args":""},{"Uniquefunname":"func (st Status) Uids() ([]uint, error)","Funname":"Uids","Returntype":"([]uint, error)","Args":""},{"Uniquefunname":"func (p Process) getFile(name string) string","Funname":"getFile","Returntype":"string","Args":"name string"},{"Uniquefunname":"func (st Status) lookup(key string) (string, error)","Funname":"lookup","Returntype":"(string, error)","Args":"key string"},{"Uniquefunname":"func (vars EnvVars) Get(key string) string","Funname":"procfs.EnvVars.Get","Returntype":"string","Args":"key string"},{"Uniquefunname":"func (vars EnvVars) Lookup(key string) (string, bool)","Funname":"procfs.EnvVars.Lookup","Returntype":"(string, bool)","Args":"key string"},{"Uniquefunname":"func (p Process) Cmdline() ([]string, error)","Funname":"procfs.Process.Cmdline","Returntype":"([]string, error)","Args":""},{"Uniquefunname":"func (p Process) Cwd() (string, error)","Funname":"procfs.Process.Cwd","Returntype":"(string, error)","Args":""},{"Uniquefunname":"func (p Process) Environ() (EnvVars, error)","Funname":"procfs.Process.Environ","Returntype":"(EnvVars, error)","Args":""},{"Uniquefunname":"func (p Process) Exe() (string, error)","Funname":"procfs.Process.Exe","Returntype":"(string, error)","Args":""},{"Uniquefunname":"func (p Process) Exist() bool","Funname":"procfs.Process.Exist","Returntype":"bool","Args":""},{"Uniquefunname":"func (p Process) Status() (Status, error)","Funname":"procfs.Process.Status","Returntype":"(Status, error)","Args":""},{"Uniquefunname":"func (p Process) getFile(name string) string","Funname":"procfs.Process.getFile","Returntype":"string","Args":"name string"},{"Uniquefunname":"func (st Status) PPid() (uint, error)","Funname":"procfs.Status.PPid","Returntype":"(uint, error)","Args":""},{"Uniquefunname":"func (st Status) Uids() ([]uint, error)","Funname":"procfs.Status.Uids","Returntype":"([]uint, error)","Args":""},{"Uniquefunname":"func (st Status) lookup(key string) (string, error)","Funname":"procfs.Status.lookup","Returntype":"(string, error)","Args":"key string"},{"Uniquefunname":"func (err StatusFieldNotFoundErr) Error() string","Funname":"procfs.StatusFieldNotFoundErr.Error","Returntype":"string","Args":""}],"Records":[{"Name":"struct:procfs.StatusFieldNotFoundErr","Fields":["procfs.StatusFieldNotFoundErr.Field string"]}]} {"Filepath":"procfs/procfs_test.go","Functions":[{"Uniquefunname":"func TestCmdline(t *testing.T)","Funname":"TestCmdline","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestCwd(t *testing.T)","Funname":"TestCwd","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestEnvVars(t *testing.T)","Funname":"TestEnvVars","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestEnvion(t *testing.T)","Funname":"TestEnvion","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestExe(t *testing.T)","Funname":"TestExe","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestExist(t *testing.T)","Funname":"TestExist","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetFile(t *testing.T)","Funname":"TestGetFile","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestStatus(t *testing.T)","Funname":"TestStatus","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestCmdline(t *testing.T)","Funname":"procfs.TestCmdline","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestCwd(t *testing.T)","Funname":"procfs.TestCwd","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestEnvVars(t *testing.T)","Funname":"procfs.TestEnvVars","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestEnvion(t *testing.T)","Funname":"procfs.TestEnvion","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestExe(t *testing.T)","Funname":"procfs.TestExe","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestExist(t *testing.T)","Funname":"procfs.TestExist","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetFile(t *testing.T)","Funname":"procfs.TestGetFile","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestStatus(t *testing.T)","Funname":"procfs.TestStatus","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"profile/profile.go","Functions":[{"Uniquefunname":"func (prof *_Profile) File() string","Funname":"File","Returntype":"string","Args":""},{"Uniquefunname":"func (cfg *Config) Start() error","Funname":"Start","Returntype":"error","Args":""},{"Uniquefunname":"func (prof *_BlockProfile) Start(writer io.Writer)","Funname":"Start","Returntype":"","Args":"writer io.Writer"},{"Uniquefunname":"func (prof *_CPUProfile) Start(writer io.Writer)","Funname":"Start","Returntype":"","Args":"writer io.Writer"},{"Uniquefunname":"func (prof *_MemProfile) Start(writer io.Writer)","Funname":"Start","Returntype":"","Args":"writer io.Writer"},{"Uniquefunname":"func (cfg *Config) Stop()","Funname":"Stop","Returntype":"","Args":""},{"Uniquefunname":"func (prof *_BlockProfile) Stop()","Funname":"Stop","Returntype":"","Args":""},{"Uniquefunname":"func (prof *_CPUProfile) Stop()","Funname":"Stop","Returntype":"","Args":""},{"Uniquefunname":"func (prof *_MemProfile) Stop()","Funname":"Stop","Returntype":"","Args":""},{"Uniquefunname":"func (cfg *Config) enableProfile(prof interface","Funname":"enableProfile","Returntype":"error","Args":"prof interface { File() string; Start(io.Writer); Stop();}"},{"Uniquefunname":"func newBlockProfile(file string) *_BlockProfile","Funname":"newBlockProfile","Returntype":"*_BlockProfile","Args":"file string"},{"Uniquefunname":"func newCPUProfile(file string) *_CPUProfile","Funname":"newCPUProfile","Returntype":"*_CPUProfile","Args":"file string"},{"Uniquefunname":"func newMemPrifle(file string) *_MemProfile","Funname":"newMemPrifle","Returntype":"*_MemProfile","Args":"file string"},{"Uniquefunname":"func (cfg *Config) Start() error","Funname":"profile.Config.Start","Returntype":"error","Args":""},{"Uniquefunname":"func (cfg *Config) Stop()","Funname":"profile.Config.Stop","Returntype":"","Args":""},{"Uniquefunname":"func (cfg *Config) enableProfile(prof interface","Funname":"profile.Config.enableProfile","Returntype":"error","Args":"prof interface { File() string; Start(io.Writer); Stop();}"},{"Uniquefunname":"func (cfg *Config) stop()","Funname":"profile.Config.stop","Returntype":"","Args":""},{"Uniquefunname":"func (prof *_BlockProfile) Start(writer io.Writer)","Funname":"profile._BlockProfile.Start","Returntype":"","Args":"writer io.Writer"},{"Uniquefunname":"func (prof *_BlockProfile) Stop()","Funname":"profile._BlockProfile.Stop","Returntype":"","Args":""},{"Uniquefunname":"func (prof *_CPUProfile) Start(writer io.Writer)","Funname":"profile._CPUProfile.Start","Returntype":"","Args":"writer io.Writer"},{"Uniquefunname":"func (prof *_CPUProfile) Stop()","Funname":"profile._CPUProfile.Stop","Returntype":"","Args":""},{"Uniquefunname":"func (prof *_MemProfile) Start(writer io.Writer)","Funname":"profile._MemProfile.Start","Returntype":"","Args":"writer io.Writer"},{"Uniquefunname":"func (prof *_MemProfile) Stop()","Funname":"profile._MemProfile.Stop","Returntype":"","Args":""},{"Uniquefunname":"func (prof *_Profile) File() string","Funname":"profile._Profile.File","Returntype":"string","Args":""},{"Uniquefunname":"func newBlockProfile(file string) *_BlockProfile","Funname":"profile.newBlockProfile","Returntype":"*_BlockProfile","Args":"file string"},{"Uniquefunname":"func newCPUProfile(file string) *_CPUProfile","Funname":"profile.newCPUProfile","Returntype":"*_CPUProfile","Args":"file string"},{"Uniquefunname":"func newMemPrifle(file string) *_MemProfile","Funname":"profile.newMemPrifle","Returntype":"*_MemProfile","Args":"file string"},{"Uniquefunname":"func (cfg *Config) stop()","Funname":"stop","Returntype":"","Args":""}],"Records":[{"Name":"struct:profile.Config","Fields":["profile.Config.BlockProfile string","profile.Config.CPUProfile string","profile.Config.MemProfile string","profile.Config.NoShutdownHook bool","profile.Config.closeOnce sync.Once","profile.Config.closers []func()"]},{"Name":"struct:profile._Profile","Fields":["profile._Profile.file string","profile._Profile.writer io.Writer"]}]} {"Filepath":"profile/profile_test.go","Functions":[{"Uniquefunname":"func ExampleConfig_Start()","Funname":"ExampleConfig_Start","Returntype":"","Args":""},{"Uniquefunname":"func ExampleConfig_Stop()","Funname":"ExampleConfig_Stop","Returntype":"","Args":""},{"Uniquefunname":"func ExampleConfig_Start()","Funname":"profile.ExampleConfig_Start","Returntype":"","Args":""},{"Uniquefunname":"func ExampleConfig_Stop()","Funname":"profile.ExampleConfig_Stop","Returntype":"","Args":""}],"Records":null} {"Filepath":"profile/time.go","Functions":[{"Uniquefunname":"func (t *Timer) Elapsed() time.Duration","Funname":"Elapsed","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func NewTimer() *Timer","Funname":"NewTimer","Returntype":"*Timer","Args":""},{"Uniquefunname":"func (t *Timer) TotalCost() time.Duration","Funname":"TotalCost","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func NewTimer() *Timer","Funname":"profile.NewTimer","Returntype":"*Timer","Args":""},{"Uniquefunname":"func (t *Timer) Elapsed() time.Duration","Funname":"profile.Timer.Elapsed","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func (t *Timer) TotalCost() time.Duration","Funname":"profile.Timer.TotalCost","Returntype":"time.Duration","Args":""}],"Records":[{"Name":"struct:profile.Timer","Fields":["profile.Timer.endTime time.Time","profile.Timer.moduleStartTime time.Time","profile.Timer.startTime time.Time"]}]} {"Filepath":"proxy/dev_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestMain(c *C.C)","Funname":"TestMain","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func proxy.Test(t *testing.T)","Funname":"proxy.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"proxy.init","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) TestMain(c *C.C)","Funname":"proxy.testWrapper.TestMain","Returntype":"","Args":"c *C.C"}],"Records":null} {"Filepath":"proxy/proxy.go","Functions":[{"Uniquefunname":"func SetupProxy()","Funname":"SetupProxy","Returntype":"","Args":""},{"Uniquefunname":"func doSetEnv(env, value string)","Funname":"doSetEnv","Returntype":"","Args":"env, value string"},{"Uniquefunname":"func getProxyChildSettings(proxyType string) (childSettings *gio.Settings, err error)","Funname":"getProxyChildSettings","Returntype":"(childSettings *gio.Settings, err error)","Args":"proxyType string"},{"Uniquefunname":"func getProxyValue(proxyType string) (proxyValue string)","Funname":"getProxyValue","Returntype":"(proxyValue string)","Args":"proxyType string"},{"Uniquefunname":"func listenProxyGsettings()","Funname":"listenProxyGsettings","Returntype":"","Args":""},{"Uniquefunname":"func SetupProxy()","Funname":"proxy.SetupProxy","Returntype":"","Args":""},{"Uniquefunname":"func doSetEnv(env, value string)","Funname":"proxy.doSetEnv","Returntype":"","Args":"env, value string"},{"Uniquefunname":"func getProxyChildSettings(proxyType string) (childSettings *gio.Settings, err error)","Funname":"proxy.getProxyChildSettings","Returntype":"(childSettings *gio.Settings, err error)","Args":"proxyType string"},{"Uniquefunname":"func getProxyValue(proxyType string) (proxyValue string)","Funname":"proxy.getProxyValue","Returntype":"(proxyValue string)","Args":"proxyType string"},{"Uniquefunname":"func listenProxyGsettings()","Funname":"proxy.listenProxyGsettings","Returntype":"","Args":""},{"Uniquefunname":"func showEnv(envName string)","Funname":"proxy.showEnv","Returntype":"","Args":"envName string"},{"Uniquefunname":"func showEnvs()","Funname":"proxy.showEnvs","Returntype":"","Args":""},{"Uniquefunname":"func updateProxyEnvs()","Funname":"proxy.updateProxyEnvs","Returntype":"","Args":""},{"Uniquefunname":"func showEnv(envName string)","Funname":"showEnv","Returntype":"","Args":"envName string"},{"Uniquefunname":"func showEnvs()","Funname":"showEnvs","Returntype":"","Args":""},{"Uniquefunname":"func updateProxyEnvs()","Funname":"updateProxyEnvs","Returntype":"","Args":""}],"Records":[{"Name":"const:proxy","Fields":["proxy.envAllProxy","proxy.envAutoProxy","proxy.envFtpProxy","proxy.envHttpProxy","proxy.envHttpsProxy","proxy.envNoProxy","proxy.envSocksProxy","proxy.gchildProxyFtp","proxy.gchildProxyHttp","proxy.gchildProxyHttps","proxy.gchildProxySocks","proxy.gkeyProxyAuto","proxy.gkeyProxyHost","proxy.gkeyProxyIgnoreHosts","proxy.gkeyProxyMode","proxy.gkeyProxyPort","proxy.gsettingsIdProxy","proxy.proxyModeAuto","proxy.proxyModeManual","proxy.proxyModeNone","proxy.proxyTypeFtp","proxy.proxyTypeHttp","proxy.proxyTypeHttps","proxy.proxyTypeSocks"]},{"Name":"var:proxy","Fields":["proxy.logger","proxy.proxyChildSettingsFtp","proxy.proxyChildSettingsHttp","proxy.proxyChildSettingsHttps","proxy.proxyChildSettingsSocks","proxy.proxySettings"]}]} {"Filepath":"pulse/card.go","Functions":[{"Uniquefunname":"func (infos CardPortInfos) Get(name string, direction int) (CardPortInfo, error)","Funname":"Get","Returntype":"(CardPortInfo, error)","Args":"name string, direction int"},{"Uniquefunname":"func (card *Card) SetProfile(name string)","Funname":"SetProfile","Returntype":"","Args":"name string"},{"Uniquefunname":"func (infos CardPortInfos) TrySelectProfile(portName string) (string, error)","Funname":"TrySelectProfile","Returntype":"(string, error)","Args":"portName string"},{"Uniquefunname":"func (card *Card) SetProfile(name string)","Funname":"pulse.Card.SetProfile","Returntype":"","Args":"name string"},{"Uniquefunname":"func (infos CardPortInfos) Get(name string, direction int) (CardPortInfo, error)","Funname":"pulse.CardPortInfos.Get","Returntype":"(CardPortInfo, error)","Args":"name string, direction int"},{"Uniquefunname":"func (infos CardPortInfos) TrySelectProfile(portName string) (string, error)","Funname":"pulse.CardPortInfos.TrySelectProfile","Returntype":"(string, error)","Args":"portName string"},{"Uniquefunname":"func toCardInfo(info *C.pa_card_info) (c *Card)","Funname":"pulse.toCardInfo","Returntype":"(c *Card)","Args":"info *C.pa_card_info"},{"Uniquefunname":"func toCardInfo(info *C.pa_card_info) (c *Card)","Funname":"toCardInfo","Returntype":"(c *Card)","Args":"info *C.pa_card_info"}],"Records":[{"Name":"struct:pulse.Card","Fields":["pulse.Card.ActiveProfile ProfileInfo2","pulse.Card.Driver string","pulse.Card.Index uint32","pulse.Card.Name string","pulse.Card.OwnerModule uint32","pulse.Card.Ports CardPortInfos","pulse.Card.Profiles ProfileInfos2","pulse.Card.PropList map[string]string"]},{"Name":"struct:pulse.CardPortInfo","Fields":["pulse.CardPortInfo.Direction int","pulse.CardPortInfo.Profiles ProfileInfos2"]},{"Name":"const:pulse","Fields":["pulse.DirectionSink","pulse.DirectionSource"]}]} {"Filepath":"pulse/info_test.go","Functions":[{"Uniquefunname":"func TestQueryInfo(t *testing.T)","Funname":"TestQueryInfo","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestQueryInfo(t *testing.T)","Funname":"pulse.TestQueryInfo","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"pulse/mainloop_callbacks.go","Functions":[{"Uniquefunname":"func (c *Context) AddEventChan(ch chan\u003c- *Event)","Funname":"AddEventChan","Returntype":"","Args":"ch chan\u003c- *Event"},{"Uniquefunname":"func (c *Context) AddStateChan(ch chan\u003c- int)","Funname":"AddStateChan","Returntype":"","Args":"ch chan\u003c- int"},{"Uniquefunname":"func (c *Context) RemoveEventChan(ch chan\u003c- *Event)","Funname":"RemoveEventChan","Returntype":"","Args":"ch chan\u003c- *Event"},{"Uniquefunname":"func (c *Context) RemoveStateChan(ch chan\u003c- int)","Funname":"RemoveStateChan","Returntype":"","Args":"ch chan\u003c- int"},{"Uniquefunname":"func freeContext(ctx *Context)","Funname":"freeContext","Returntype":"","Args":"ctx *Context"},{"Uniquefunname":"func go_handle_changed(facility int, event_type int, idx uint32)","Funname":"go_handle_changed","Returntype":"","Args":"facility int, event_type int, idx uint32"},{"Uniquefunname":"func go_handle_state_changed(state int)","Funname":"go_handle_state_changed","Returntype":"","Args":"state int"},{"Uniquefunname":"func go_receive_some_info(cookie int64, infoType int, info unsafe.Pointer, eol int)","Funname":"go_receive_some_info","Returntype":"","Args":"cookie int64, infoType int, info unsafe.Pointer, eol int"},{"Uniquefunname":"func go_update_volume_meter(source_index uint32, sink_index uint32, v float64)","Funname":"go_update_volume_meter","Returntype":"","Args":"source_index uint32, sink_index uint32, v float64"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func (c *Context) AddEventChan(ch chan\u003c- *Event)","Funname":"pulse.Context.AddEventChan","Returntype":"","Args":"ch chan\u003c- *Event"},{"Uniquefunname":"func (c *Context) AddStateChan(ch chan\u003c- int)","Funname":"pulse.Context.AddStateChan","Returntype":"","Args":"ch chan\u003c- int"},{"Uniquefunname":"func (c *Context) RemoveEventChan(ch chan\u003c- *Event)","Funname":"pulse.Context.RemoveEventChan","Returntype":"","Args":"ch chan\u003c- *Event"},{"Uniquefunname":"func (c *Context) RemoveStateChan(ch chan\u003c- int)","Funname":"pulse.Context.RemoveStateChan","Returntype":"","Args":"ch chan\u003c- int"},{"Uniquefunname":"func (c *Context) safeDo(fn func())","Funname":"pulse.Context.safeDo","Returntype":"","Args":"fn func()"},{"Uniquefunname":"func freeContext(ctx *Context)","Funname":"pulse.freeContext","Returntype":"","Args":"ctx *Context"},{"Uniquefunname":"func go_handle_changed(facility int, event_type int, idx uint32)","Funname":"pulse.go_handle_changed","Returntype":"","Args":"facility int, event_type int, idx uint32"},{"Uniquefunname":"func go_handle_state_changed(state int)","Funname":"pulse.go_handle_state_changed","Returntype":"","Args":"state int"},{"Uniquefunname":"func go_receive_some_info(cookie int64, infoType int, info unsafe.Pointer, eol int)","Funname":"pulse.go_receive_some_info","Returntype":"","Args":"cookie int64, infoType int, info unsafe.Pointer, eol int"},{"Uniquefunname":"func go_update_volume_meter(source_index uint32, sink_index uint32, v float64)","Funname":"pulse.go_update_volume_meter","Returntype":"","Args":"source_index uint32, sink_index uint32, v float64"},{"Uniquefunname":"func init()","Funname":"pulse.init","Returntype":"","Args":""},{"Uniquefunname":"func startHandleSafeDo()","Funname":"pulse.startHandleSafeDo","Returntype":"","Args":""},{"Uniquefunname":"func (c *Context) safeDo(fn func())","Funname":"safeDo","Returntype":"","Args":"fn func()"},{"Uniquefunname":"func startHandleSafeDo()","Funname":"startHandleSafeDo","Returntype":"","Args":""}],"Records":[{"Name":"var:pulse","Fields":["pulse.pendingSafeDo"]},{"Name":"struct:pulse.safeDoCtx","Fields":["pulse.safeDoCtx.fn func()","pulse.safeDoCtx.loop *C.pa_threaded_mainloop"]}]} {"Filepath":"pulse/meter.go","Functions":[{"Uniquefunname":"func (s *SourceMeter) ConnectChanged(cb func(v float64))","Funname":"ConnectChanged","Returntype":"","Args":"cb func(v float64)"},{"Uniquefunname":"func (s *SourceMeter) Destroy()","Funname":"Destroy","Returntype":"","Args":""},{"Uniquefunname":"func NewSourceMeter(c *Context, idx uint32) *SourceMeter","Funname":"NewSourceMeter","Returntype":"*SourceMeter","Args":"c *Context, idx uint32"},{"Uniquefunname":"func NewSourceMeter(c *Context, idx uint32) *SourceMeter","Funname":"pulse.NewSourceMeter","Returntype":"*SourceMeter","Args":"c *Context, idx uint32"},{"Uniquefunname":"func (s *SourceMeter) ConnectChanged(cb func(v float64))","Funname":"pulse.SourceMeter.ConnectChanged","Returntype":"","Args":"cb func(v float64)"},{"Uniquefunname":"func (s *SourceMeter) Destroy()","Funname":"pulse.SourceMeter.Destroy","Returntype":"","Args":""}],"Records":[{"Name":"struct:pulse.SourceMeter","Fields":["pulse.SourceMeter.core *C.pa_stream","pulse.SourceMeter.ctx *Context","pulse.SourceMeter.sourceIndex uint32"]},{"Name":"var:pulse","Fields":["pulse.sourceMeterCBs","pulse.sourceMeterLock"]}]} {"Filepath":"pulse/misc.go","Functions":[{"Uniquefunname":"func (cv CVolume) Avg() float64","Funname":"Avg","Returntype":"float64","Args":""},{"Uniquefunname":"func (cv CVolume) Balance(cmap ChannelMap) float64","Funname":"Balance","Returntype":"float64","Args":"cmap ChannelMap"},{"Uniquefunname":"func (cm ChannelMap) CanBalance() bool","Funname":"CanBalance","Returntype":"bool","Args":""},{"Uniquefunname":"func (cm ChannelMap) CanFade() bool","Funname":"CanFade","Returntype":"bool","Args":""},{"Uniquefunname":"func (infos ProfileInfos2) Exists(name string) bool","Funname":"Exists","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func (cv CVolume) Fade(cmap ChannelMap) float64","Funname":"Fade","Returntype":"float64","Args":"cmap ChannelMap"},{"Uniquefunname":"func (infos PortInfos) Get(name string) *PortInfo","Funname":"Get","Returntype":"*PortInfo","Args":"name string"},{"Uniquefunname":"func (infos ProfileInfos2) Len() int","Funname":"Len","Returntype":"int","Args":""},{"Uniquefunname":"func (infos ProfileInfos2) Less(i, j int) bool","Funname":"Less","Returntype":"bool","Args":"i, j int"},{"Uniquefunname":"func (infos ProfileInfos2) SelectProfile() string","Funname":"SelectProfile","Returntype":"string","Args":""},{"Uniquefunname":"func (cv CVolume) SetAvg(v float64) CVolume","Funname":"SetAvg","Returntype":"CVolume","Args":"v float64"},{"Uniquefunname":"func (cv CVolume) SetBalance(cm ChannelMap, balance float64) CVolume","Funname":"SetBalance","Returntype":"CVolume","Args":"cm ChannelMap, balance float64"},{"Uniquefunname":"func (cv CVolume) SetFade(cm ChannelMap, fade float64) CVolume","Funname":"SetFade","Returntype":"CVolume","Args":"cm ChannelMap, fade float64"},{"Uniquefunname":"func (infos ProfileInfos2) Swap(i, j int)","Funname":"Swap","Returntype":"","Args":"i, j int"},{"Uniquefunname":"func (v Volume) ToLiner() float64","Funname":"ToLiner","Returntype":"float64","Args":""},{"Uniquefunname":"func (v Volume) ToPercent() float64","Funname":"ToPercent","Returntype":"float64","Args":""},{"Uniquefunname":"func (v Volume) TodB() float64","Funname":"TodB","Returntype":"float64","Args":""},{"Uniquefunname":"func (cv CVolume) Avg() float64","Funname":"pulse.CVolume.Avg","Returntype":"float64","Args":""},{"Uniquefunname":"func (cv CVolume) Balance(cmap ChannelMap) float64","Funname":"pulse.CVolume.Balance","Returntype":"float64","Args":"cmap ChannelMap"},{"Uniquefunname":"func (cv CVolume) Fade(cmap ChannelMap) float64","Funname":"pulse.CVolume.Fade","Returntype":"float64","Args":"cmap ChannelMap"},{"Uniquefunname":"func (cv CVolume) SetAvg(v float64) CVolume","Funname":"pulse.CVolume.SetAvg","Returntype":"CVolume","Args":"v float64"},{"Uniquefunname":"func (cv CVolume) SetBalance(cm ChannelMap, balance float64) CVolume","Funname":"pulse.CVolume.SetBalance","Returntype":"CVolume","Args":"cm ChannelMap, balance float64"},{"Uniquefunname":"func (cv CVolume) SetFade(cm ChannelMap, fade float64) CVolume","Funname":"pulse.CVolume.SetFade","Returntype":"CVolume","Args":"cm ChannelMap, fade float64"},{"Uniquefunname":"func (cm ChannelMap) CanBalance() bool","Funname":"pulse.ChannelMap.CanBalance","Returntype":"bool","Args":""},{"Uniquefunname":"func (cm ChannelMap) CanFade() bool","Funname":"pulse.ChannelMap.CanFade","Returntype":"bool","Args":""},{"Uniquefunname":"func (infos PortInfos) Get(name string) *PortInfo","Funname":"pulse.PortInfos.Get","Returntype":"*PortInfo","Args":"name string"},{"Uniquefunname":"func (infos ProfileInfos2) Exists(name string) bool","Funname":"pulse.ProfileInfos2.Exists","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func (infos ProfileInfos2) Len() int","Funname":"pulse.ProfileInfos2.Len","Returntype":"int","Args":""},{"Uniquefunname":"func (infos ProfileInfos2) Less(i, j int) bool","Funname":"pulse.ProfileInfos2.Less","Returntype":"bool","Args":"i, j int"},{"Uniquefunname":"func (infos ProfileInfos2) SelectProfile() string","Funname":"pulse.ProfileInfos2.SelectProfile","Returntype":"string","Args":""},{"Uniquefunname":"func (infos ProfileInfos2) Swap(i, j int)","Funname":"pulse.ProfileInfos2.Swap","Returntype":"","Args":"i, j int"},{"Uniquefunname":"func (infos ProfileInfos2) selectByAvailable(available int) ProfileInfo2","Funname":"pulse.ProfileInfos2.selectByAvailable","Returntype":"ProfileInfo2","Args":"available int"},{"Uniquefunname":"func (v Volume) ToLiner() float64","Funname":"pulse.Volume.ToLiner","Returntype":"float64","Args":""},{"Uniquefunname":"func (v Volume) ToPercent() float64","Funname":"pulse.Volume.ToPercent","Returntype":"float64","Args":""},{"Uniquefunname":"func (v Volume) TodB() float64","Funname":"pulse.Volume.TodB","Returntype":"float64","Args":""},{"Uniquefunname":"func toBool(v C.int) bool","Funname":"pulse.toBool","Returntype":"bool","Args":"v C.int"},{"Uniquefunname":"func toProplist(c *C.pa_proplist) map[string]string","Funname":"pulse.toProplist","Returntype":"map[string]string","Args":"c *C.pa_proplist"},{"Uniquefunname":"func (infos ProfileInfos2) selectByAvailable(available int) ProfileInfo2","Funname":"selectByAvailable","Returntype":"ProfileInfo2","Args":"available int"},{"Uniquefunname":"func toBool(v C.int) bool","Funname":"toBool","Returntype":"bool","Args":"v C.int"},{"Uniquefunname":"func toProplist(c *C.pa_proplist) map[string]string","Funname":"toProplist","Returntype":"map[string]string","Args":"c *C.pa_proplist"}],"Records":[{"Name":"const:pulse","Fields":["pulse.AvailableTypeNo","pulse.AvailableTypeUnknow","pulse.AvailableTypeYes","pulse.VolumeMax","pulse.VolumeUIMax"]},{"Name":"struct:pulse.CVolume","Fields":["pulse.CVolume.core C.pa_cvolume"]},{"Name":"struct:pulse.ChannelMap","Fields":["pulse.ChannelMap.core C.pa_channel_map"]},{"Name":"struct:pulse.PortInfo","Fields":["pulse.PortInfo.Available int","pulse.PortInfo.Description string","pulse.PortInfo.Name string","pulse.PortInfo.Priority uint32"]},{"Name":"struct:pulse.ProfileInfo2","Fields":["pulse.ProfileInfo2.Available int","pulse.ProfileInfo2.Description string","pulse.ProfileInfo2.NSinks uint32","pulse.ProfileInfo2.NSources uint32","pulse.ProfileInfo2.Name string","pulse.ProfileInfo2.Priority uint32"]},{"Name":"struct:pulse.Volume","Fields":["pulse.Volume.paVolume C.pa_volume_t"]}]} {"Filepath":"pulse/proplist.go","Functions":null,"Records":[{"Name":"const:pulse","Fields":["pulse.PA_PROP_APPLICATION_ICON_NAME","pulse.PA_PROP_APPLICATION_ID","pulse.PA_PROP_APPLICATION_LANGUAGE","pulse.PA_PROP_APPLICATION_NAME","pulse.PA_PROP_APPLICATION_PROCESS_BINARY","pulse.PA_PROP_APPLICATION_PROCESS_HOST","pulse.PA_PROP_APPLICATION_PROCESS_ID","pulse.PA_PROP_APPLICATION_PROCESS_MACHINE_ID","pulse.PA_PROP_APPLICATION_PROCESS_SESSION_ID","pulse.PA_PROP_APPLICATION_PROCESS_USER","pulse.PA_PROP_APPLICATION_VERSION","pulse.PA_PROP_DEVICE_ACCESS_MODE","pulse.PA_PROP_DEVICE_API","pulse.PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE","pulse.PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE","pulse.PA_PROP_DEVICE_BUS","pulse.PA_PROP_DEVICE_BUS_PATH","pulse.PA_PROP_DEVICE_CLASS","pulse.PA_PROP_DEVICE_DESCRIPTION","pulse.PA_PROP_DEVICE_FORM_FACTOR","pulse.PA_PROP_DEVICE_ICON_NAME","pulse.PA_PROP_DEVICE_INTENDED_ROLES","pulse.PA_PROP_DEVICE_MASTER_DEVICE","pulse.PA_PROP_DEVICE_PRODUCT_ID","pulse.PA_PROP_DEVICE_PRODUCT_NAME","pulse.PA_PROP_DEVICE_PROFILE_DESCRIPTION","pulse.PA_PROP_DEVICE_PROFILE_NAME","pulse.PA_PROP_DEVICE_SERIAL","pulse.PA_PROP_DEVICE_STRING","pulse.PA_PROP_DEVICE_VENDOR_ID","pulse.PA_PROP_DEVICE_VENDOR_NAME","pulse.PA_PROP_EVENT_DESCRIPTION","pulse.PA_PROP_EVENT_ID","pulse.PA_PROP_EVENT_MOUSE_BUTTON","pulse.PA_PROP_EVENT_MOUSE_HPOS","pulse.PA_PROP_EVENT_MOUSE_VPOS","pulse.PA_PROP_EVENT_MOUSE_X","pulse.PA_PROP_EVENT_MOUSE_Y","pulse.PA_PROP_FILTER_APPLY","pulse.PA_PROP_FILTER_SUPPRESS","pulse.PA_PROP_FILTER_WANT","pulse.PA_PROP_FORMAT_CHANNELS","pulse.PA_PROP_FORMAT_CHANNEL_MAP","pulse.PA_PROP_FORMAT_RATE","pulse.PA_PROP_FORMAT_SAMPLE_FORMAT","pulse.PA_PROP_MEDIA_ARTIST","pulse.PA_PROP_MEDIA_COPYRIGHT","pulse.PA_PROP_MEDIA_FILENAME","pulse.PA_PROP_MEDIA_ICON_NAME","pulse.PA_PROP_MEDIA_LANGUAGE","pulse.PA_PROP_MEDIA_NAME","pulse.PA_PROP_MEDIA_ROLE","pulse.PA_PROP_MEDIA_SOFTWARE","pulse.PA_PROP_MEDIA_TITLE","pulse.PA_PROP_MODULE_AUTHOR","pulse.PA_PROP_MODULE_DESCRIPTION","pulse.PA_PROP_MODULE_USAGE","pulse.PA_PROP_MODULE_VERSION","pulse.PA_PROP_WINDOW_DESKTOP","pulse.PA_PROP_WINDOW_HEIGHT","pulse.PA_PROP_WINDOW_HPOS","pulse.PA_PROP_WINDOW_ICON_NAME","pulse.PA_PROP_WINDOW_ID","pulse.PA_PROP_WINDOW_NAME","pulse.PA_PROP_WINDOW_VPOS","pulse.PA_PROP_WINDOW_WIDTH","pulse.PA_PROP_WINDOW_X","pulse.PA_PROP_WINDOW_X11_DISPLAY","pulse.PA_PROP_WINDOW_X11_MONITOR","pulse.PA_PROP_WINDOW_X11_SCREEN","pulse.PA_PROP_WINDOW_X11_XID","pulse.PA_PROP_WINDOW_Y"]}]} {"Filepath":"pulse/pulse.go","Functions":[{"Uniquefunname":"func (c *Context) GetCard(index uint32) (*Card, error)","Funname":"GetCard","Returntype":"(*Card, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetCardList() (r []*Card)","Funname":"GetCardList","Returntype":"(r []*Card)","Args":""},{"Uniquefunname":"func GetContext() *Context","Funname":"GetContext","Returntype":"*Context","Args":""},{"Uniquefunname":"func GetContextForced() *Context","Funname":"GetContextForced","Returntype":"*Context","Args":""},{"Uniquefunname":"func (c *Context) GetDefaultSink() string","Funname":"GetDefaultSink","Returntype":"string","Args":""},{"Uniquefunname":"func (c *Context) GetDefaultSource() string","Funname":"GetDefaultSource","Returntype":"string","Args":""},{"Uniquefunname":"func (c *Context) GetServer() (*Server, error)","Funname":"GetServer","Returntype":"(*Server, error)","Args":""},{"Uniquefunname":"func (c *Context) GetSink(index uint32) (*Sink, error)","Funname":"GetSink","Returntype":"(*Sink, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetSinkInput(index uint32) (*SinkInput, error)","Funname":"GetSinkInput","Returntype":"(*SinkInput, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetSinkInputList() (r []*SinkInput)","Funname":"GetSinkInputList","Returntype":"(r []*SinkInput)","Args":""},{"Uniquefunname":"func (c *Context) GetSinkList() (r []*Sink)","Funname":"GetSinkList","Returntype":"(r []*Sink)","Args":""},{"Uniquefunname":"func (c *Context) GetSource(index uint32) (*Source, error)","Funname":"GetSource","Returntype":"(*Source, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetSourceList() (r []*Source)","Funname":"GetSourceList","Returntype":"(r []*Source)","Args":""},{"Uniquefunname":"func (c *Context) GetSourceOutput(index uint32) (*SourceOutput, error)","Funname":"GetSourceOutput","Returntype":"(*SourceOutput, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetSourceOutputList() (r []*SourceOutput)","Funname":"GetSourceOutputList","Returntype":"(r []*SourceOutput)","Args":""},{"Uniquefunname":"func (c *Context) LoadModule(name, argument string)","Funname":"LoadModule","Returntype":"","Args":"name, argument string"},{"Uniquefunname":"func (c *Context) MoveSinkInputsByIndex(sinkInputs []uint32, sinkIdx uint32)","Funname":"MoveSinkInputsByIndex","Returntype":"","Args":"sinkInputs []uint32, sinkIdx uint32"},{"Uniquefunname":"func (c *Context) MoveSinkInputsByName(sinkInputs []uint32, sinkName string)","Funname":"MoveSinkInputsByName","Returntype":"","Args":"sinkInputs []uint32, sinkName string"},{"Uniquefunname":"func (c *Context) MoveSourceOutputsByIndex(sourceOutputs []uint32, sourceIdx uint32)","Funname":"MoveSourceOutputsByIndex","Returntype":"","Args":"sourceOutputs []uint32, sourceIdx uint32"},{"Uniquefunname":"func (c *Context) MoveSourceOutputsByName(sourceOutputs []uint32, sourceName string)","Funname":"MoveSourceOutputsByName","Returntype":"","Args":"sourceOutputs []uint32, sourceName string"},{"Uniquefunname":"func (c *Context) SetDefaultSink(name string)","Funname":"SetDefaultSink","Returntype":"","Args":"name string"},{"Uniquefunname":"func (c *Context) SetDefaultSource(name string)","Funname":"SetDefaultSource","Returntype":"","Args":"name string"},{"Uniquefunname":"func (c *Context) SetSinkInputMute(sinkInputIndex uint32, mute bool)","Funname":"SetSinkInputMute","Returntype":"","Args":"sinkInputIndex uint32, mute bool"},{"Uniquefunname":"func (c *Context) SetSinkInputVolume(sinkInputIndex uint32, v CVolume)","Funname":"SetSinkInputVolume","Returntype":"","Args":"sinkInputIndex uint32, v CVolume"},{"Uniquefunname":"func (c *Context) SetSinkMuteByIndex(sinkIndex uint32, mute bool)","Funname":"SetSinkMuteByIndex","Returntype":"","Args":"sinkIndex uint32, mute bool"},{"Uniquefunname":"func (c *Context) SetSinkPortByIndex(sinkIndex uint32, portName string)","Funname":"SetSinkPortByIndex","Returntype":"","Args":"sinkIndex uint32, portName string"},{"Uniquefunname":"func (c *Context) SetSinkVolumeByIndex(sinkIndex uint32, v CVolume)","Funname":"SetSinkVolumeByIndex","Returntype":"","Args":"sinkIndex uint32, v CVolume"},{"Uniquefunname":"func (c *Context) SetSourceMuteByIndex(sourceIndex uint32, mute bool)","Funname":"SetSourceMuteByIndex","Returntype":"","Args":"sourceIndex uint32, mute bool"},{"Uniquefunname":"func (c *Context) SetSourcePortByIndex(sourceIndex uint32, portName string)","Funname":"SetSourcePortByIndex","Returntype":"","Args":"sourceIndex uint32, portName string"},{"Uniquefunname":"func (c *Context) SetSourceVolumeByIndex(sourceIndex uint32, v CVolume)","Funname":"SetSourceVolumeByIndex","Returntype":"","Args":"sourceIndex uint32, v CVolume"},{"Uniquefunname":"func (c *Context) SuspendSinkById(idx uint32, suspend int)","Funname":"SuspendSinkById","Returntype":"","Args":"idx uint32, suspend int"},{"Uniquefunname":"func (c *Context) SuspendSourceById(idx uint32, suspend int)","Funname":"SuspendSourceById","Returntype":"","Args":"idx uint32, suspend int"},{"Uniquefunname":"func (c *Context) GetCard(index uint32) (*Card, error)","Funname":"pulse.Context.GetCard","Returntype":"(*Card, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetCardList() (r []*Card)","Funname":"pulse.Context.GetCardList","Returntype":"(r []*Card)","Args":""},{"Uniquefunname":"func (c *Context) GetDefaultSink() string","Funname":"pulse.Context.GetDefaultSink","Returntype":"string","Args":""},{"Uniquefunname":"func (c *Context) GetDefaultSource() string","Funname":"pulse.Context.GetDefaultSource","Returntype":"string","Args":""},{"Uniquefunname":"func (c *Context) GetServer() (*Server, error)","Funname":"pulse.Context.GetServer","Returntype":"(*Server, error)","Args":""},{"Uniquefunname":"func (c *Context) GetSink(index uint32) (*Sink, error)","Funname":"pulse.Context.GetSink","Returntype":"(*Sink, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetSinkInput(index uint32) (*SinkInput, error)","Funname":"pulse.Context.GetSinkInput","Returntype":"(*SinkInput, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetSinkInputList() (r []*SinkInput)","Funname":"pulse.Context.GetSinkInputList","Returntype":"(r []*SinkInput)","Args":""},{"Uniquefunname":"func (c *Context) GetSinkList() (r []*Sink)","Funname":"pulse.Context.GetSinkList","Returntype":"(r []*Sink)","Args":""},{"Uniquefunname":"func (c *Context) GetSource(index uint32) (*Source, error)","Funname":"pulse.Context.GetSource","Returntype":"(*Source, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetSourceList() (r []*Source)","Funname":"pulse.Context.GetSourceList","Returntype":"(r []*Source)","Args":""},{"Uniquefunname":"func (c *Context) GetSourceOutput(index uint32) (*SourceOutput, error)","Funname":"pulse.Context.GetSourceOutput","Returntype":"(*SourceOutput, error)","Args":"index uint32"},{"Uniquefunname":"func (c *Context) GetSourceOutputList() (r []*SourceOutput)","Funname":"pulse.Context.GetSourceOutputList","Returntype":"(r []*SourceOutput)","Args":""},{"Uniquefunname":"func (c *Context) LoadModule(name, argument string)","Funname":"pulse.Context.LoadModule","Returntype":"","Args":"name, argument string"},{"Uniquefunname":"func (c *Context) MoveSinkInputsByIndex(sinkInputs []uint32, sinkIdx uint32)","Funname":"pulse.Context.MoveSinkInputsByIndex","Returntype":"","Args":"sinkInputs []uint32, sinkIdx uint32"},{"Uniquefunname":"func (c *Context) MoveSinkInputsByName(sinkInputs []uint32, sinkName string)","Funname":"pulse.Context.MoveSinkInputsByName","Returntype":"","Args":"sinkInputs []uint32, sinkName string"},{"Uniquefunname":"func (c *Context) MoveSourceOutputsByIndex(sourceOutputs []uint32, sourceIdx uint32)","Funname":"pulse.Context.MoveSourceOutputsByIndex","Returntype":"","Args":"sourceOutputs []uint32, sourceIdx uint32"},{"Uniquefunname":"func (c *Context) MoveSourceOutputsByName(sourceOutputs []uint32, sourceName string)","Funname":"pulse.Context.MoveSourceOutputsByName","Returntype":"","Args":"sourceOutputs []uint32, sourceName string"},{"Uniquefunname":"func (c *Context) SetDefaultSink(name string)","Funname":"pulse.Context.SetDefaultSink","Returntype":"","Args":"name string"},{"Uniquefunname":"func (c *Context) SetDefaultSource(name string)","Funname":"pulse.Context.SetDefaultSource","Returntype":"","Args":"name string"},{"Uniquefunname":"func (c *Context) SetSinkInputMute(sinkInputIndex uint32, mute bool)","Funname":"pulse.Context.SetSinkInputMute","Returntype":"","Args":"sinkInputIndex uint32, mute bool"},{"Uniquefunname":"func (c *Context) SetSinkInputVolume(sinkInputIndex uint32, v CVolume)","Funname":"pulse.Context.SetSinkInputVolume","Returntype":"","Args":"sinkInputIndex uint32, v CVolume"},{"Uniquefunname":"func (c *Context) SetSinkMuteByIndex(sinkIndex uint32, mute bool)","Funname":"pulse.Context.SetSinkMuteByIndex","Returntype":"","Args":"sinkIndex uint32, mute bool"},{"Uniquefunname":"func (c *Context) SetSinkPortByIndex(sinkIndex uint32, portName string)","Funname":"pulse.Context.SetSinkPortByIndex","Returntype":"","Args":"sinkIndex uint32, portName string"},{"Uniquefunname":"func (c *Context) SetSinkVolumeByIndex(sinkIndex uint32, v CVolume)","Funname":"pulse.Context.SetSinkVolumeByIndex","Returntype":"","Args":"sinkIndex uint32, v CVolume"},{"Uniquefunname":"func (c *Context) SetSourceMuteByIndex(sourceIndex uint32, mute bool)","Funname":"pulse.Context.SetSourceMuteByIndex","Returntype":"","Args":"sourceIndex uint32, mute bool"},{"Uniquefunname":"func (c *Context) SetSourcePortByIndex(sourceIndex uint32, portName string)","Funname":"pulse.Context.SetSourcePortByIndex","Returntype":"","Args":"sourceIndex uint32, portName string"},{"Uniquefunname":"func (c *Context) SetSourceVolumeByIndex(sourceIndex uint32, v CVolume)","Funname":"pulse.Context.SetSourceVolumeByIndex","Returntype":"","Args":"sourceIndex uint32, v CVolume"},{"Uniquefunname":"func (c *Context) SuspendSinkById(idx uint32, suspend int)","Funname":"pulse.Context.SuspendSinkById","Returntype":"","Args":"idx uint32, suspend int"},{"Uniquefunname":"func (c *Context) SuspendSourceById(idx uint32, suspend int)","Funname":"pulse.Context.SuspendSourceById","Returntype":"","Args":"idx uint32, suspend int"},{"Uniquefunname":"func GetContext() *Context","Funname":"pulse.GetContext","Returntype":"*Context","Args":""},{"Uniquefunname":"func GetContextForced() *Context","Funname":"pulse.GetContextForced","Returntype":"*Context","Args":""}],"Records":[{"Name":"struct:pulse.Context","Fields":["pulse.Context.ctx *C.pa_context","pulse.Context.eventChanList []chan\u003c- *Event","pulse.Context.loop *C.pa_threaded_mainloop","pulse.Context.mu sync.Mutex","pulse.Context.stateChanList []chan\u003c- int"]},{"Name":"const:pulse","Fields":["pulse.ContextStateAuthorizing","pulse.ContextStateConnecting","pulse.ContextStateFailed","pulse.ContextStateReady","pulse.ContextStateSettingName","pulse.ContextStateTerminated","pulse.ContextStateUnconnected","pulse.EventTypeChange","pulse.EventTypeNew","pulse.EventTypeRemove","pulse.FacilityCard","pulse.FacilityClient","pulse.FacilityModule","pulse.FacilitySampleCache","pulse.FacilityServer","pulse.FacilitySink","pulse.FacilitySinkInput","pulse.FacilitySource","pulse.FacilitySourceOutput"]},{"Name":"struct:pulse.Event","Fields":["pulse.Event.Facility int","pulse.Event.Index uint32","pulse.Event.Type int"]},{"Name":"var:pulse","Fields":["pulse.PulseInitTimeout","pulse.__context","pulse.__ctxLocker"]}]} {"Filepath":"pulse/server.go","Functions":[{"Uniquefunname":"func toServerInfo(info *C.pa_server_info) *Server","Funname":"pulse.toServerInfo","Returntype":"*Server","Args":"info *C.pa_server_info"},{"Uniquefunname":"func toServerInfo(info *C.pa_server_info) *Server","Funname":"toServerInfo","Returntype":"*Server","Args":"info *C.pa_server_info"}],"Records":[{"Name":"struct:pulse.Server","Fields":["pulse.Server.ChannelMap ChannelMap","pulse.Server.Cookie uint32","pulse.Server.DefaultSinkName string","pulse.Server.DefaultSourceName string","pulse.Server.HostName string","pulse.Server.ServerName string","pulse.Server.ServerVersion string","pulse.Server.UserName string"]}]} {"Filepath":"pulse/sink.go","Functions":[{"Uniquefunname":"func toSinkInfo(info *C.pa_sink_info) *Sink","Funname":"pulse.toSinkInfo","Returntype":"*Sink","Args":"info *C.pa_sink_info"},{"Uniquefunname":"func toSinkInfo(info *C.pa_sink_info) *Sink","Funname":"toSinkInfo","Returntype":"*Sink","Args":"info *C.pa_sink_info"}],"Records":[{"Name":"struct:pulse.Sink","Fields":["pulse.Sink.ActivePort PortInfo","pulse.Sink.BaseVolume Volume","pulse.Sink.Card uint32","pulse.Sink.ChannelMap ChannelMap","pulse.Sink.Description string","pulse.Sink.Driver string","pulse.Sink.Flags int","pulse.Sink.Index uint32","pulse.Sink.MonitorSource uint32","pulse.Sink.MonitorSourceName string","pulse.Sink.Mute bool","pulse.Sink.NVolumeSteps uint32","pulse.Sink.Name string","pulse.Sink.OwnerModule uint32","pulse.Sink.Ports []PortInfo","pulse.Sink.PropList map[string]string","pulse.Sink.Volume CVolume"]}]} {"Filepath":"pulse/sink_input.go","Functions":[{"Uniquefunname":"func toSinkInputInfo(info *C.pa_sink_input_info) *SinkInput","Funname":"pulse.toSinkInputInfo","Returntype":"*SinkInput","Args":"info *C.pa_sink_input_info"},{"Uniquefunname":"func toSinkInputInfo(info *C.pa_sink_input_info) *SinkInput","Funname":"toSinkInputInfo","Returntype":"*SinkInput","Args":"info *C.pa_sink_input_info"}],"Records":[{"Name":"struct:pulse.SinkInput","Fields":["pulse.SinkInput.ChannelMap ChannelMap","pulse.SinkInput.Client uint32","pulse.SinkInput.Corked int","pulse.SinkInput.Driver string","pulse.SinkInput.HasVolume bool","pulse.SinkInput.Index uint32","pulse.SinkInput.Mute bool","pulse.SinkInput.Name string","pulse.SinkInput.OwnerModule uint32","pulse.SinkInput.PropList map[string]string","pulse.SinkInput.ResampleMethod string","pulse.SinkInput.Sink uint32","pulse.SinkInput.Volume CVolume","pulse.SinkInput.VolumeWritable bool"]}]} {"Filepath":"pulse/source.go","Functions":[{"Uniquefunname":"func toSourceInfo(info *C.pa_source_info) *Source","Funname":"pulse.toSourceInfo","Returntype":"*Source","Args":"info *C.pa_source_info"},{"Uniquefunname":"func toSourceInfo(info *C.pa_source_info) *Source","Funname":"toSourceInfo","Returntype":"*Source","Args":"info *C.pa_source_info"}],"Records":[{"Name":"struct:pulse.Source","Fields":["pulse.Source.ActivePort PortInfo","pulse.Source.BaseVolume Volume","pulse.Source.Card uint32","pulse.Source.ChannelMap ChannelMap","pulse.Source.Description string","pulse.Source.Driver string","pulse.Source.Flags int","pulse.Source.Index uint32","pulse.Source.MonitorOfSink uint32","pulse.Source.MonitorOfSinkName string","pulse.Source.Mute bool","pulse.Source.NVolumeSteps uint32","pulse.Source.Name string","pulse.Source.OwnerModule uint32","pulse.Source.Ports []PortInfo","pulse.Source.Proplist map[string]string","pulse.Source.Volume CVolume"]}]} {"Filepath":"pulse/source_output.go","Functions":[{"Uniquefunname":"func toSourceOutputInfo(info *C.pa_source_output_info) *SourceOutput","Funname":"pulse.toSourceOutputInfo","Returntype":"*SourceOutput","Args":"info *C.pa_source_output_info"},{"Uniquefunname":"func toSourceOutputInfo(info *C.pa_source_output_info) *SourceOutput","Funname":"toSourceOutputInfo","Returntype":"*SourceOutput","Args":"info *C.pa_source_output_info"}],"Records":null} {"Filepath":"pulse/sync.go","Functions":[{"Uniquefunname":"func (c *cookie) EndOfList()","Funname":"EndOfList","Returntype":"","Args":""},{"Uniquefunname":"func (c *cookie) Failed()","Funname":"Failed","Returntype":"","Args":""},{"Uniquefunname":"func (c *cookie) Feed(paInfo *paInfo)","Funname":"Feed","Returntype":"","Args":"paInfo *paInfo"},{"Uniquefunname":"func NewPaInfo(data unsafe.Pointer, Type int) *paInfo","Funname":"NewPaInfo","Returntype":"*paInfo","Args":"data unsafe.Pointer, Type int"},{"Uniquefunname":"func (c *cookie) Reply() *paInfo","Funname":"Reply","Returntype":"*paInfo","Args":""},{"Uniquefunname":"func (c *cookie) ReplyList() []*paInfo","Funname":"ReplyList","Returntype":"[]*paInfo","Args":""},{"Uniquefunname":"func NewPaInfo(data unsafe.Pointer, Type int) *paInfo","Funname":"pulse.NewPaInfo","Returntype":"*paInfo","Args":"data unsafe.Pointer, Type int"},{"Uniquefunname":"func (c *cookie) EndOfList()","Funname":"pulse.cookie.EndOfList","Returntype":"","Args":""},{"Uniquefunname":"func (c *cookie) Failed()","Funname":"pulse.cookie.Failed","Returntype":"","Args":""},{"Uniquefunname":"func (c *cookie) Feed(paInfo *paInfo)","Funname":"pulse.cookie.Feed","Returntype":"","Args":"paInfo *paInfo"},{"Uniquefunname":"func (c *cookie) Reply() *paInfo","Funname":"pulse.cookie.Reply","Returntype":"*paInfo","Args":""},{"Uniquefunname":"func (c *cookie) ReplyList() []*paInfo","Funname":"pulse.cookie.ReplyList","Returntype":"[]*paInfo","Args":""}],"Records":[{"Name":"struct:pulse.cookie","Fields":["pulse.cookie.data chan *paInfo","pulse.cookie.id int64"]},{"Name":"var:pulse","Fields":["pulse.deleteCookie","pulse.fetchCookie","pulse.newCookie"]},{"Name":"struct:pulse.paInfo","Fields":["pulse.paInfo.Type int","pulse.paInfo.data interface{}"]}]} {"Filepath":"pulse/thread_test.go","Functions":[{"Uniquefunname":"func BenchmarkTheadSafe(b *testing.B)","Funname":"BenchmarkTheadSafe","Returntype":"","Args":"b *testing.B"},{"Uniquefunname":"func BenchmarkTheadSafe(b *testing.B)","Funname":"pulse.BenchmarkTheadSafe","Returntype":"","Args":"b *testing.B"}],"Records":null} {"Filepath":"pulse/wrap.go","Functions":[{"Uniquefunname":"func (info *paInfo) ToCard() *Card","Funname":"ToCard","Returntype":"*Card","Args":""},{"Uniquefunname":"func (info *paInfo) ToServer() *Server","Funname":"ToServer","Returntype":"*Server","Args":""},{"Uniquefunname":"func (info *paInfo) ToSink() *Sink","Funname":"ToSink","Returntype":"*Sink","Args":""},{"Uniquefunname":"func (info *paInfo) ToSinkInput() *SinkInput","Funname":"ToSinkInput","Returntype":"*SinkInput","Args":""},{"Uniquefunname":"func (info *paInfo) ToSource() *Source","Funname":"ToSource","Returntype":"*Source","Args":""},{"Uniquefunname":"func (info *paInfo) ToSourceOutput() *SourceOutput","Funname":"ToSourceOutput","Returntype":"*SourceOutput","Args":""},{"Uniquefunname":"func (info *paInfo) ToCard() *Card","Funname":"pulse.paInfo.ToCard","Returntype":"*Card","Args":""},{"Uniquefunname":"func (info *paInfo) ToServer() *Server","Funname":"pulse.paInfo.ToServer","Returntype":"*Server","Args":""},{"Uniquefunname":"func (info *paInfo) ToSink() *Sink","Funname":"pulse.paInfo.ToSink","Returntype":"*Sink","Args":""},{"Uniquefunname":"func (info *paInfo) ToSinkInput() *SinkInput","Funname":"pulse.paInfo.ToSinkInput","Returntype":"*SinkInput","Args":""},{"Uniquefunname":"func (info *paInfo) ToSource() *Source","Funname":"pulse.paInfo.ToSource","Returntype":"*Source","Args":""},{"Uniquefunname":"func (info *paInfo) ToSourceOutput() *SourceOutput","Funname":"pulse.paInfo.ToSourceOutput","Returntype":"*SourceOutput","Args":""},{"Uniquefunname":"func toCardPort(c *C.pa_card_port_info) CardPortInfo","Funname":"pulse.toCardPort","Returntype":"CardPortInfo","Args":"c *C.pa_card_port_info"},{"Uniquefunname":"func toCardPorts(n uint32, c **C.pa_card_port_info) (r CardPortInfos)","Funname":"pulse.toCardPorts","Returntype":"(r CardPortInfos)","Args":"n uint32, c **C.pa_card_port_info"},{"Uniquefunname":"func toPort(c *C.pa_sink_port_info) PortInfo","Funname":"pulse.toPort","Returntype":"PortInfo","Args":"c *C.pa_sink_port_info"},{"Uniquefunname":"func toPorts(n uint32, c **C.pa_sink_port_info) (r []PortInfo)","Funname":"pulse.toPorts","Returntype":"(r []PortInfo)","Args":"n uint32, c **C.pa_sink_port_info"},{"Uniquefunname":"func toProfile(c *C.pa_card_profile_info2) ProfileInfo2","Funname":"pulse.toProfile","Returntype":"ProfileInfo2","Args":"c *C.pa_card_profile_info2"},{"Uniquefunname":"func toProfiles(n uint32, c **C.pa_card_profile_info2) (r ProfileInfos2)","Funname":"pulse.toProfiles","Returntype":"(r ProfileInfos2)","Args":"n uint32, c **C.pa_card_profile_info2"},{"Uniquefunname":"func toSourcePort(c *C.pa_source_port_info) PortInfo","Funname":"pulse.toSourcePort","Returntype":"PortInfo","Args":"c *C.pa_source_port_info"},{"Uniquefunname":"func toSourcePorts(n uint32, c **C.pa_source_port_info) (r []PortInfo)","Funname":"pulse.toSourcePorts","Returntype":"(r []PortInfo)","Args":"n uint32, c **C.pa_source_port_info"},{"Uniquefunname":"func toCardPort(c *C.pa_card_port_info) CardPortInfo","Funname":"toCardPort","Returntype":"CardPortInfo","Args":"c *C.pa_card_port_info"},{"Uniquefunname":"func toCardPorts(n uint32, c **C.pa_card_port_info) (r CardPortInfos)","Funname":"toCardPorts","Returntype":"(r CardPortInfos)","Args":"n uint32, c **C.pa_card_port_info"},{"Uniquefunname":"func toPort(c *C.pa_sink_port_info) PortInfo","Funname":"toPort","Returntype":"PortInfo","Args":"c *C.pa_sink_port_info"},{"Uniquefunname":"func toPorts(n uint32, c **C.pa_sink_port_info) (r []PortInfo)","Funname":"toPorts","Returntype":"(r []PortInfo)","Args":"n uint32, c **C.pa_sink_port_info"},{"Uniquefunname":"func toProfile(c *C.pa_card_profile_info2) ProfileInfo2","Funname":"toProfile","Returntype":"ProfileInfo2","Args":"c *C.pa_card_profile_info2"},{"Uniquefunname":"func toProfiles(n uint32, c **C.pa_card_profile_info2) (r ProfileInfos2)","Funname":"toProfiles","Returntype":"(r ProfileInfos2)","Args":"n uint32, c **C.pa_card_profile_info2"},{"Uniquefunname":"func toSourcePort(c *C.pa_source_port_info) PortInfo","Funname":"toSourcePort","Returntype":"PortInfo","Args":"c *C.pa_source_port_info"},{"Uniquefunname":"func toSourcePorts(n uint32, c **C.pa_source_port_info) (r []PortInfo)","Funname":"toSourcePorts","Returntype":"(r []PortInfo)","Args":"n uint32, c **C.pa_source_port_info"}],"Records":[{"Name":"struct:pulse.SampleSpec","Fields":["pulse.SampleSpec.Channels uint8","pulse.SampleSpec.Format SampleFormat","pulse.SampleSpec.Rate uint32"]}]} {"Filepath":"pulse/simple/simple.go","Functions":[{"Uniquefunname":"func (c Conn) Drain() (int, error)","Funname":"Drain","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (err Error) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (c Conn) Flush() (int, error)","Funname":"Flush","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (c Conn) Free()","Funname":"Free","Returntype":"","Args":""},{"Uniquefunname":"func NewConn(server, name string, dir StreamDirection, dev, streamName string, sampleSpec *SampleSpec)(Conn, error)","Funname":"NewConn","Returntype":"(Conn, error)","Args":"server, name string, dir StreamDirection, dev, streamName string, sampleSpec *SampleSpec"},{"Uniquefunname":"func (c Conn) Write(data unsafe.Pointer, bytes uint) (int, error)","Funname":"Write","Returntype":"(int, error)","Args":"data unsafe.Pointer, bytes uint"},{"Uniquefunname":"func (ss *SampleSpec) native() *C.pa_sample_spec","Funname":"native","Returntype":"*C.pa_sample_spec","Args":""},{"Uniquefunname":"func (v Conn) native() *C.pa_simple","Funname":"native","Returntype":"*C.pa_simple","Args":""},{"Uniquefunname":"func newError(fn string, errCode C.int) error","Funname":"newError","Returntype":"error","Args":"fn string, errCode C.int"},{"Uniquefunname":"func (c Conn) Drain() (int, error)","Funname":"simple.Conn.Drain","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (c Conn) Flush() (int, error)","Funname":"simple.Conn.Flush","Returntype":"(int, error)","Args":""},{"Uniquefunname":"func (c Conn) Free()","Funname":"simple.Conn.Free","Returntype":"","Args":""},{"Uniquefunname":"func (c Conn) Write(data unsafe.Pointer, bytes uint) (int, error)","Funname":"simple.Conn.Write","Returntype":"(int, error)","Args":"data unsafe.Pointer, bytes uint"},{"Uniquefunname":"func (v Conn) native() *C.pa_simple","Funname":"simple.Conn.native","Returntype":"*C.pa_simple","Args":""},{"Uniquefunname":"func (err Error) Error() string","Funname":"simple.Error.Error","Returntype":"string","Args":""},{"Uniquefunname":"func simple.NewConn(server, name string, dir StreamDirection, dev, streamName string, sampleSpec *SampleSpec)(Conn, error)","Funname":"simple.NewConn","Returntype":"(Conn, error)","Args":"server, name string, dir StreamDirection, dev, streamName string, sampleSpec *SampleSpec"},{"Uniquefunname":"func (ss *SampleSpec) native() *C.pa_sample_spec","Funname":"simple.SampleSpec.native","Returntype":"*C.pa_sample_spec","Args":""},{"Uniquefunname":"func newError(fn string, errCode C.int) error","Funname":"simple.newError","Returntype":"error","Args":"fn string, errCode C.int"},{"Uniquefunname":"func wrapConn(ptr *C.pa_simple) Conn","Funname":"simple.wrapConn","Returntype":"Conn","Args":"ptr *C.pa_simple"},{"Uniquefunname":"func wrapConn(ptr *C.pa_simple) Conn","Funname":"wrapConn","Returntype":"Conn","Args":"ptr *C.pa_simple"}],"Records":[{"Name":"struct:simple.Conn","Fields":["simple.Conn.Ptr unsafe.Pointer"]},{"Name":"struct:simple.Error","Fields":["simple.Error.Code int","simple.Error.Fn string"]},{"Name":"const:simple","Fields":["simple.SampleFormatFloat32BE","simple.SampleFormatFloat32LE","simple.SampleFormatS16BE","simple.SampleFormatS16LE","simple.SampleFormatS16NE","simple.SampleFormatS32BE","simple.SampleFormatS32LE","simple.SampleFormatU8","simple.StreamDirectionPlayback"]},{"Name":"struct:simple.SampleSpec","Fields":["simple.SampleSpec.Channels uint8","simple.SampleSpec.Format SampleFormat","simple.SampleSpec.Rate uint32"]}]} {"Filepath":"shell/shell.go","Functions":[{"Uniquefunname":"func Encode(s string) string","Funname":"Encode","Returntype":"string","Args":"s string"},{"Uniquefunname":"func isSpecialChar(c byte) bool","Funname":"isSpecialChar","Returntype":"bool","Args":"c byte"},{"Uniquefunname":"func Encode(s string) string","Funname":"shell.Encode","Returntype":"string","Args":"s string"},{"Uniquefunname":"func isSpecialChar(c byte) bool","Funname":"shell.isSpecialChar","Returntype":"bool","Args":"c byte"}],"Records":[{"Name":"const:shell","Fields":["shell.specialChars"]}]} {"Filepath":"shell/shell_test.go","Functions":[{"Uniquefunname":"func TestEncode(t *testing.T)","Funname":"TestEncode","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestEncode(t *testing.T)","Funname":"shell.TestEncode","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"sound/player.go","Functions":[{"Uniquefunname":"func PlaySoundFile(file, device, driver, player string) error","Funname":"PlaySoundFile","Returntype":"error","Args":"file, device, driver, player string"},{"Uniquefunname":"func PlayThemeSound(theme, event, device, driver, player string) error","Funname":"PlayThemeSound","Returntype":"error","Args":"theme, event, device, driver, player string"},{"Uniquefunname":"func PlaySoundFile(file, device, driver, player string) error","Funname":"sound.PlaySoundFile","Returntype":"error","Args":"file, device, driver, player string"},{"Uniquefunname":"func PlayThemeSound(theme, event, device, driver, player string) error","Funname":"sound.PlayThemeSound","Returntype":"error","Args":"theme, event, device, driver, player string"}],"Records":[{"Name":"const:sound","Fields":["sound.PlayerLibcanberra","sound.PlayerMPV","sound.PlayerPaplay"]}]} {"Filepath":"sound/utils.go","Functions":[{"Uniquefunname":"func findThemeFile(theme, event string) (string, error)","Funname":"findThemeFile","Returntype":"(string, error)","Args":"theme, event string"},{"Uniquefunname":"func findThemeFile(theme, event string) (string, error)","Funname":"sound.findThemeFile","Returntype":"(string, error)","Args":"theme, event string"}],"Records":[{"Name":"var:sound","Fields":["sound.errInvalidEvent"]}]} {"Filepath":"sound_effect/alsa_backend.go","Functions":[{"Uniquefunname":"func (pb *ALSAPlayBackend) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (pb *ALSAPlayBackend) Drain() error","Funname":"Drain","Returntype":"error","Args":""},{"Uniquefunname":"func (pb *ALSAPlayBackend) Write(data []byte) error","Funname":"Write","Returntype":"error","Args":"data []byte"},{"Uniquefunname":"func newALSAPlayBackend(device string, sampleSpec *SampleSpec) (pb PlayBackend, err error)","Funname":"newALSAPlayBackend","Returntype":"(pb PlayBackend, err error)","Args":"device string, sampleSpec *SampleSpec"},{"Uniquefunname":"func (pb *ALSAPlayBackend) Close() error","Funname":"sound_effect.ALSAPlayBackend.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (pb *ALSAPlayBackend) Drain() error","Funname":"sound_effect.ALSAPlayBackend.Drain","Returntype":"error","Args":""},{"Uniquefunname":"func (pb *ALSAPlayBackend) Write(data []byte) error","Funname":"sound_effect.ALSAPlayBackend.Write","Returntype":"error","Args":"data []byte"},{"Uniquefunname":"func newALSAPlayBackend(device string, sampleSpec *SampleSpec) (pb PlayBackend, err error)","Funname":"sound_effect.newALSAPlayBackend","Returntype":"(pb PlayBackend, err error)","Args":"device string, sampleSpec *SampleSpec"}],"Records":[{"Name":"struct:sound_effect.ALSAPlayBackend","Fields":["sound_effect.ALSAPlayBackend.frameSize int","sound_effect.ALSAPlayBackend.pcm asound.PCM"]}]} {"Filepath":"sound_effect/ogg.go","Functions":[{"Uniquefunname":"func (d *OggDecoder) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (d *OggDecoder) Decode() ([]byte, error)","Funname":"Decode","Returntype":"([]byte, error)","Args":""},{"Uniquefunname":"func (d *OggDecoder) GetDuration() time.Duration","Funname":"GetDuration","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func (d *OggDecoder) GetSampleSpec() *SampleSpec","Funname":"GetSampleSpec","Returntype":"*SampleSpec","Args":""},{"Uniquefunname":"func newOggDecoder(file string) (Decoder, error)","Funname":"newOggDecoder","Returntype":"(Decoder, error)","Args":"file string"},{"Uniquefunname":"func (d *OggDecoder) Close() error","Funname":"sound_effect.OggDecoder.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (d *OggDecoder) Decode() ([]byte, error)","Funname":"sound_effect.OggDecoder.Decode","Returntype":"([]byte, error)","Args":""},{"Uniquefunname":"func (d *OggDecoder) GetDuration() time.Duration","Funname":"sound_effect.OggDecoder.GetDuration","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func (d *OggDecoder) GetSampleSpec() *SampleSpec","Funname":"sound_effect.OggDecoder.GetSampleSpec","Returntype":"*SampleSpec","Args":""},{"Uniquefunname":"func newOggDecoder(file string) (Decoder, error)","Funname":"sound_effect.newOggDecoder","Returntype":"(Decoder, error)","Args":"file string"}],"Records":[{"Name":"struct:sound_effect.OggDecoder","Fields":["sound_effect.OggDecoder.bufSize int","sound_effect.OggDecoder.core stb_vorbis.Decoder","sound_effect.OggDecoder.sampleSpec *SampleSpec"]}]} {"Filepath":"sound_effect/player.go","Functions":[{"Uniquefunname":"func (player *Player) Finder() *theme.Finder","Funname":"Finder","Returntype":"*theme.Finder","Args":""},{"Uniquefunname":"func (player *Player) GetDuration(theme, event string) (time.Duration, error)","Funname":"GetDuration","Returntype":"(time.Duration, error)","Args":"theme, event string"},{"Uniquefunname":"func (ss *SampleSpec) GetPaSampleSpec() *paSimple.SampleSpec","Funname":"GetPaSampleSpec","Returntype":"*paSimple.SampleSpec","Args":""},{"Uniquefunname":"func NewPlayer(useCache bool, backendType PlayBackendType) *Player","Funname":"NewPlayer","Returntype":"*Player","Args":"useCache bool, backendType PlayBackendType"},{"Uniquefunname":"func (player *Player) Play(theme, event, device string) error","Funname":"Play","Returntype":"error","Args":"theme, event, device string"},{"Uniquefunname":"func cacheItemOk(cacheItem *CacheItem, fileInfo os.FileInfo) bool","Funname":"cacheItemOk","Returntype":"bool","Args":"cacheItem *CacheItem, fileInfo os.FileInfo"},{"Uniquefunname":"func getDecoder(file string, fileInfo os.FileInfo) (Decoder, error)","Funname":"getDecoder","Returntype":"(Decoder, error)","Args":"file string, fileInfo os.FileInfo"},{"Uniquefunname":"func (Player *Player) getDuration(file string) (time.Duration, error)","Funname":"getDuration","Returntype":"(time.Duration, error)","Args":"file string"},{"Uniquefunname":"func getPlayBackend(type0 PlayBackendType, event, device string, sampleSpec *SampleSpec)(PlayBackend, error)","Funname":"getPlayBackend","Returntype":"(PlayBackend, error)","Args":"type0 PlayBackendType, event, device string, sampleSpec *SampleSpec"},{"Uniquefunname":"func (player *Player) play(file, event, device string) error","Funname":"play","Returntype":"error","Args":"file, event, device string"},{"Uniquefunname":"func (player *Player) playCacheItem(cacheItem *CacheItem, device string) error","Funname":"playCacheItem","Returntype":"error","Args":"cacheItem *CacheItem, device string"},{"Uniquefunname":"func NewPlayer(useCache bool, backendType PlayBackendType) *Player","Funname":"sound_effect.NewPlayer","Returntype":"*Player","Args":"useCache bool, backendType PlayBackendType"},{"Uniquefunname":"func (player *Player) Finder() *theme.Finder","Funname":"sound_effect.Player.Finder","Returntype":"*theme.Finder","Args":""},{"Uniquefunname":"func (player *Player) GetDuration(theme, event string) (time.Duration, error)","Funname":"sound_effect.Player.GetDuration","Returntype":"(time.Duration, error)","Args":"theme, event string"},{"Uniquefunname":"func (player *Player) Play(theme, event, device string) error","Funname":"sound_effect.Player.Play","Returntype":"error","Args":"theme, event, device string"},{"Uniquefunname":"func (Player *Player) getDuration(file string) (time.Duration, error)","Funname":"sound_effect.Player.getDuration","Returntype":"(time.Duration, error)","Args":"file string"},{"Uniquefunname":"func (player *Player) play(file, event, device string) error","Funname":"sound_effect.Player.play","Returntype":"error","Args":"file, event, device string"},{"Uniquefunname":"func (player *Player) playCacheItem(cacheItem *CacheItem, device string) error","Funname":"sound_effect.Player.playCacheItem","Returntype":"error","Args":"cacheItem *CacheItem, device string"},{"Uniquefunname":"func (ss *SampleSpec) GetPaSampleSpec() *paSimple.SampleSpec","Funname":"sound_effect.SampleSpec.GetPaSampleSpec","Returntype":"*paSimple.SampleSpec","Args":""},{"Uniquefunname":"func cacheItemOk(cacheItem *CacheItem, fileInfo os.FileInfo) bool","Funname":"sound_effect.cacheItemOk","Returntype":"bool","Args":"cacheItem *CacheItem, fileInfo os.FileInfo"},{"Uniquefunname":"func getDecoder(file string, fileInfo os.FileInfo) (Decoder, error)","Funname":"sound_effect.getDecoder","Returntype":"(Decoder, error)","Args":"file string, fileInfo os.FileInfo"},{"Uniquefunname":"func sound_effect.getPlayBackend(type0 PlayBackendType, event, device string, sampleSpec *SampleSpec)(PlayBackend, error)","Funname":"sound_effect.getPlayBackend","Returntype":"(PlayBackend, error)","Args":"type0 PlayBackendType, event, device string, sampleSpec *SampleSpec"}],"Records":[{"Name":"struct:sound_effect.CacheItem","Fields":["sound_effect.CacheItem.data [][]byte","sound_effect.CacheItem.event string","sound_effect.CacheItem.modTime time.Time","sound_effect.CacheItem.sampleSpec *SampleSpec"]},{"Name":"interface","Fields":["sound_effect.Decoder","sound_effect.PlayBackend"]},{"Name":"const:sound_effect","Fields":["sound_effect.PlayBackendALSA","sound_effect.PlayBackendPulseAudio"]},{"Name":"struct:sound_effect.Player","Fields":["sound_effect.Player.UseCache bool","sound_effect.Player.backendType PlayBackendType","sound_effect.Player.cache map[string]*CacheItem","sound_effect.Player.cacheMu sync.Mutex","sound_effect.Player.finder *theme.Finder"]},{"Name":"struct:sound_effect.SampleSpec","Fields":["sound_effect.SampleSpec.channels int","sound_effect.SampleSpec.paFormat paSimple.SampleFormat","sound_effect.SampleSpec.pcmFormat asound.PCMFormat","sound_effect.SampleSpec.rate int"]}]} {"Filepath":"sound_effect/pulse_backend.go","Functions":[{"Uniquefunname":"func (pb *PulseAudioPlayBackend) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (pb *PulseAudioPlayBackend) Drain() error","Funname":"Drain","Returntype":"error","Args":""},{"Uniquefunname":"func (pb *PulseAudioPlayBackend) Write(data []byte) error","Funname":"Write","Returntype":"error","Args":"data []byte"},{"Uniquefunname":"func newPulseAudioPlayBackend(event, device string, sampleSpec *SampleSpec)(PlayBackend, error)","Funname":"newPulseAudioPlayBackend","Returntype":"(PlayBackend, error)","Args":"event, device string, sampleSpec *SampleSpec"},{"Uniquefunname":"func (pb *PulseAudioPlayBackend) Close() error","Funname":"sound_effect.PulseAudioPlayBackend.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (pb *PulseAudioPlayBackend) Drain() error","Funname":"sound_effect.PulseAudioPlayBackend.Drain","Returntype":"error","Args":""},{"Uniquefunname":"func (pb *PulseAudioPlayBackend) Write(data []byte) error","Funname":"sound_effect.PulseAudioPlayBackend.Write","Returntype":"error","Args":"data []byte"},{"Uniquefunname":"func sound_effect.newPulseAudioPlayBackend(event, device string, sampleSpec *SampleSpec)(PlayBackend, error)","Funname":"sound_effect.newPulseAudioPlayBackend","Returntype":"(PlayBackend, error)","Args":"event, device string, sampleSpec *SampleSpec"}],"Records":[{"Name":"struct:sound_effect.PulseAudioPlayBackend","Fields":["sound_effect.PulseAudioPlayBackend.conn paSimple.Conn"]}]} {"Filepath":"sound_effect/wav.go","Functions":[{"Uniquefunname":"func (d *WavDecoder) Close() error","Funname":"Close","Returntype":"error","Args":""},{"Uniquefunname":"func (d *WavDecoder) Decode() ([]byte, error)","Funname":"Decode","Returntype":"([]byte, error)","Args":""},{"Uniquefunname":"func (d *WavDecoder) GetDuration() time.Duration","Funname":"GetDuration","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func (d *WavDecoder) GetSampleSpec() *SampleSpec","Funname":"GetSampleSpec","Returntype":"*SampleSpec","Args":""},{"Uniquefunname":"func getWavFormat(wavFile wav.File) (paSimple.SampleFormat, asound.PCMFormat, error)","Funname":"getWavFormat","Returntype":"(paSimple.SampleFormat, asound.PCMFormat, error)","Args":"wavFile wav.File"},{"Uniquefunname":"func newWavDecoder(filename string, fileInfo os.FileInfo) (Decoder, error)","Funname":"newWavDecoder","Returntype":"(Decoder, error)","Args":"filename string, fileInfo os.FileInfo"},{"Uniquefunname":"func (d *WavDecoder) read(buf []byte) (int, error)","Funname":"read","Returntype":"(int, error)","Args":"buf []byte"},{"Uniquefunname":"func (d *WavDecoder) Close() error","Funname":"sound_effect.WavDecoder.Close","Returntype":"error","Args":""},{"Uniquefunname":"func (d *WavDecoder) Decode() ([]byte, error)","Funname":"sound_effect.WavDecoder.Decode","Returntype":"([]byte, error)","Args":""},{"Uniquefunname":"func (d *WavDecoder) GetDuration() time.Duration","Funname":"sound_effect.WavDecoder.GetDuration","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func (d *WavDecoder) GetSampleSpec() *SampleSpec","Funname":"sound_effect.WavDecoder.GetSampleSpec","Returntype":"*SampleSpec","Args":""},{"Uniquefunname":"func (d *WavDecoder) read(buf []byte) (int, error)","Funname":"sound_effect.WavDecoder.read","Returntype":"(int, error)","Args":"buf []byte"},{"Uniquefunname":"func getWavFormat(wavFile wav.File) (paSimple.SampleFormat, asound.PCMFormat, error)","Funname":"sound_effect.getWavFormat","Returntype":"(paSimple.SampleFormat, asound.PCMFormat, error)","Args":"wavFile wav.File"},{"Uniquefunname":"func newWavDecoder(filename string, fileInfo os.FileInfo) (Decoder, error)","Funname":"sound_effect.newWavDecoder","Returntype":"(Decoder, error)","Args":"filename string, fileInfo os.FileInfo"}],"Records":[{"Name":"struct:sound_effect.WavDecoder","Fields":["sound_effect.WavDecoder.bufSize int","sound_effect.WavDecoder.bytesPerFrame int","sound_effect.WavDecoder.duration time.Duration","sound_effect.WavDecoder.f *os.File","sound_effect.WavDecoder.reader *wav.Reader","sound_effect.WavDecoder.sampleSpec *SampleSpec"]}]} {"Filepath":"sound_effect/theme/theme.go","Functions":[{"Uniquefunname":"func (finder *Finder) Find(reqTheme, reqOutputProfile, reqName string) string","Funname":"Find","Returntype":"string","Args":"reqTheme, reqOutputProfile, reqName string"},{"Uniquefunname":"func (finder *Finder) GetTheme(name string) (*Theme, error)","Funname":"GetTheme","Returntype":"(*Theme, error)","Args":"name string"},{"Uniquefunname":"func LoadTheme(filename string) (*Theme, error)","Funname":"LoadTheme","Returntype":"(*Theme, error)","Args":"filename string"},{"Uniquefunname":"func NewFinder() *Finder","Funname":"NewFinder","Returntype":"*Finder","Args":""},{"Uniquefunname":"func (finder *Finder) find(reqTheme, reqOutputProfile, reqName string) string","Funname":"find","Returntype":"string","Args":"reqTheme, reqOutputProfile, reqName string"},{"Uniquefunname":"func getNames(name string, acc []string) []string","Funname":"getNames","Returntype":"[]string","Args":"name string, acc []string"},{"Uniquefunname":"func isNameOk(name string) bool","Funname":"isNameOk","Returntype":"bool","Args":"name string"},{"Uniquefunname":"func (finder *Finder) lookup(theme *Theme, reqOutputProfile, reqName string) string","Funname":"lookup","Returntype":"string","Args":"theme *Theme, reqOutputProfile, reqName string"},{"Uniquefunname":"func (finder *Finder) Find(reqTheme, reqOutputProfile, reqName string) string","Funname":"theme.Finder.Find","Returntype":"string","Args":"reqTheme, reqOutputProfile, reqName string"},{"Uniquefunname":"func (finder *Finder) GetTheme(name string) (*Theme, error)","Funname":"theme.Finder.GetTheme","Returntype":"(*Theme, error)","Args":"name string"},{"Uniquefunname":"func (finder *Finder) find(reqTheme, reqOutputProfile, reqName string) string","Funname":"theme.Finder.find","Returntype":"string","Args":"reqTheme, reqOutputProfile, reqName string"},{"Uniquefunname":"func (finder *Finder) lookup(theme *Theme, reqOutputProfile, reqName string) string","Funname":"theme.Finder.lookup","Returntype":"string","Args":"theme *Theme, reqOutputProfile, reqName string"},{"Uniquefunname":"func LoadTheme(filename string) (*Theme, error)","Funname":"theme.LoadTheme","Returntype":"(*Theme, error)","Args":"filename string"},{"Uniquefunname":"func NewFinder() *Finder","Funname":"theme.NewFinder","Returntype":"*Finder","Args":""},{"Uniquefunname":"func getNames(name string, acc []string) []string","Funname":"theme.getNames","Returntype":"[]string","Args":"name string, acc []string"},{"Uniquefunname":"func isNameOk(name string) bool","Funname":"theme.isNameOk","Returntype":"bool","Args":"name string"}],"Records":[{"Name":"struct:theme.Finder","Fields":["theme.Finder.dataDirs []string","theme.Finder.loadedThemes map[string]*Theme","theme.Finder.mu sync.Mutex"]},{"Name":"struct:theme.SubDir","Fields":["theme.SubDir.Name string","theme.SubDir.OutputProfile string"]},{"Name":"struct:theme.Theme","Fields":["theme.Theme.Directories []string","theme.Theme.Inherits []string","theme.Theme.InternalName string","theme.Theme.Path string","theme.Theme.SubDirs []SubDir"]}]} {"Filepath":"stb_vorbis/stb_vorbis.go","Functions":[{"Uniquefunname":"func (d Decoder) Close()","Funname":"Close","Returntype":"","Args":""},{"Uniquefunname":"func DecodeFile(filename string) (result []int16, channels int, sampleRate int, err error)","Funname":"DecodeFile","Returntype":"(result []int16, channels int, sampleRate int, err error)","Args":"filename string"},{"Uniquefunname":"func (err Error) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func (d Decoder) GetError() error","Funname":"GetError","Returntype":"error","Args":""},{"Uniquefunname":"func (d Decoder) GetInfo() Info","Funname":"GetInfo","Returntype":"Info","Args":""},{"Uniquefunname":"func (d Decoder) GetSamplesShortInterleaved(channels int, buffer []byte) int","Funname":"GetSamplesShortInterleaved","Returntype":"int","Args":"channels int, buffer []byte"},{"Uniquefunname":"func OpenFile(filename string) (Decoder, error)","Funname":"OpenFile","Returntype":"(Decoder, error)","Args":"filename string"},{"Uniquefunname":"func (d Decoder) StreamLengthInSamples() uint","Funname":"StreamLengthInSamples","Returntype":"uint","Args":""},{"Uniquefunname":"func (v Decoder) native() *C.stb_vorbis","Funname":"native","Returntype":"*C.stb_vorbis","Args":""},{"Uniquefunname":"func setSliceDataLen(pSlice, pData unsafe.Pointer, len int)","Funname":"setSliceDataLen","Returntype":"","Args":"pSlice, pData unsafe.Pointer, len int"},{"Uniquefunname":"func DecodeFile(filename string) (result []int16, channels int, sampleRate int, err error)","Funname":"stb_vorbis.DecodeFile","Returntype":"(result []int16, channels int, sampleRate int, err error)","Args":"filename string"},{"Uniquefunname":"func (d Decoder) Close()","Funname":"stb_vorbis.Decoder.Close","Returntype":"","Args":""},{"Uniquefunname":"func (d Decoder) GetError() error","Funname":"stb_vorbis.Decoder.GetError","Returntype":"error","Args":""},{"Uniquefunname":"func (d Decoder) GetInfo() Info","Funname":"stb_vorbis.Decoder.GetInfo","Returntype":"Info","Args":""},{"Uniquefunname":"func (d Decoder) GetSamplesShortInterleaved(channels int, buffer []byte) int","Funname":"stb_vorbis.Decoder.GetSamplesShortInterleaved","Returntype":"int","Args":"channels int, buffer []byte"},{"Uniquefunname":"func (d Decoder) StreamLengthInSamples() uint","Funname":"stb_vorbis.Decoder.StreamLengthInSamples","Returntype":"uint","Args":""},{"Uniquefunname":"func (v Decoder) native() *C.stb_vorbis","Funname":"stb_vorbis.Decoder.native","Returntype":"*C.stb_vorbis","Args":""},{"Uniquefunname":"func (err Error) Error() string","Funname":"stb_vorbis.Error.Error","Returntype":"string","Args":""},{"Uniquefunname":"func OpenFile(filename string) (Decoder, error)","Funname":"stb_vorbis.OpenFile","Returntype":"(Decoder, error)","Args":"filename string"},{"Uniquefunname":"func setSliceDataLen(pSlice, pData unsafe.Pointer, len int)","Funname":"stb_vorbis.setSliceDataLen","Returntype":"","Args":"pSlice, pData unsafe.Pointer, len int"},{"Uniquefunname":"func wrapDecoder(ptr *C.stb_vorbis) Decoder","Funname":"stb_vorbis.wrapDecoder","Returntype":"Decoder","Args":"ptr *C.stb_vorbis"},{"Uniquefunname":"func wrapDecoder(ptr *C.stb_vorbis) Decoder","Funname":"wrapDecoder","Returntype":"Decoder","Args":"ptr *C.stb_vorbis"}],"Records":[{"Name":"const:stb_vorbis","Fields":["stb_vorbis.BadPacketType","stb_vorbis.CantFindLastPage","stb_vorbis.FeatureNotSupported","stb_vorbis.FileOpenFailure","stb_vorbis.IncorrectStreamSerialNumber","stb_vorbis.InvalidAPIMixing","stb_vorbis.InvalidContinuedPacketFlag","stb_vorbis.InvalidFirstPage","stb_vorbis.InvalidSetup","stb_vorbis.InvalidStream","stb_vorbis.InvalidStreamStructureVersion","stb_vorbis.MissingCapturePattern","stb_vorbis.NeedMoreData","stb_vorbis.NoError","stb_vorbis.OutOfMem","stb_vorbis.SeekFailed","stb_vorbis.SeekInvalid","stb_vorbis.SeekWithoutLength","stb_vorbis.TooManyChannels","stb_vorbis.UnexpectedEOF"]},{"Name":"struct:stb_vorbis.Decoder","Fields":["stb_vorbis.Decoder.Ptr unsafe.Pointer"]},{"Name":"struct:stb_vorbis.Error","Fields":["stb_vorbis.Error.Code int"]},{"Name":"struct:stb_vorbis.Info","Fields":["stb_vorbis.Info.Channels int","stb_vorbis.Info.SampleRate uint"]}]} {"Filepath":"strv/strv.go","Functions":[{"Uniquefunname":"func (vector Strv) Add(str string) (Strv, bool)","Funname":"Add","Returntype":"(Strv, bool)","Args":"str string"},{"Uniquefunname":"func (vector Strv) Contains(str string) bool","Funname":"Contains","Returntype":"bool","Args":"str string"},{"Uniquefunname":"func (vector Strv) Delete(str string) (Strv, bool)","Funname":"Delete","Returntype":"(Strv, bool)","Args":"str string"},{"Uniquefunname":"func (v1 Strv) Equal(v2 Strv) bool","Funname":"Equal","Returntype":"bool","Args":"v2 Strv"},{"Uniquefunname":"func (vector Strv) FilterEmpty() Strv","Funname":"FilterEmpty","Returntype":"Strv","Args":""},{"Uniquefunname":"func (vector Strv) FilterFunc(fn func(string) bool) Strv","Funname":"FilterFunc","Returntype":"Strv","Args":"fn func(string) bool"},{"Uniquefunname":"func (vector Strv) Uniq() Strv","Funname":"Uniq","Returntype":"Strv","Args":""},{"Uniquefunname":"func (vector Strv) Add(str string) (Strv, bool)","Funname":"strv.Strv.Add","Returntype":"(Strv, bool)","Args":"str string"},{"Uniquefunname":"func (vector Strv) Contains(str string) bool","Funname":"strv.Strv.Contains","Returntype":"bool","Args":"str string"},{"Uniquefunname":"func (vector Strv) Delete(str string) (Strv, bool)","Funname":"strv.Strv.Delete","Returntype":"(Strv, bool)","Args":"str string"},{"Uniquefunname":"func (v1 Strv) Equal(v2 Strv) bool","Funname":"strv.Strv.Equal","Returntype":"bool","Args":"v2 Strv"},{"Uniquefunname":"func (vector Strv) FilterEmpty() Strv","Funname":"strv.Strv.FilterEmpty","Returntype":"Strv","Args":""},{"Uniquefunname":"func (vector Strv) FilterFunc(fn func(string) bool) Strv","Funname":"strv.Strv.FilterFunc","Returntype":"Strv","Args":"fn func(string) bool"},{"Uniquefunname":"func (vector Strv) Uniq() Strv","Funname":"strv.Strv.Uniq","Returntype":"Strv","Args":""}],"Records":null} {"Filepath":"strv/strv_test.go","Functions":[{"Uniquefunname":"func TestAdd(t *testing.T)","Funname":"TestAdd","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestContains(t *testing.T)","Funname":"TestContains","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestDelete(t *testing.T)","Funname":"TestDelete","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestEqual(t *testing.T)","Funname":"TestEqual","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestFilterEmpty(t *testing.T)","Funname":"TestFilterEmpty","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestFilterFunc(t *testing.T)","Funname":"TestFilterFunc","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestUniq(t *testing.T)","Funname":"TestUniq","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestAdd(t *testing.T)","Funname":"strv.TestAdd","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestContains(t *testing.T)","Funname":"strv.TestContains","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestDelete(t *testing.T)","Funname":"strv.TestDelete","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestEqual(t *testing.T)","Funname":"strv.TestEqual","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestFilterEmpty(t *testing.T)","Funname":"strv.TestFilterEmpty","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestFilterFunc(t *testing.T)","Funname":"strv.TestFilterFunc","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestUniq(t *testing.T)","Funname":"strv.TestUniq","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"tasker/delay_task.go","Functions":[{"Uniquefunname":"func NewDelayTask(duration time.Duration, cb interface{})(*DelayTask, error)","Funname":"NewDelayTask","Returntype":"(*DelayTask, error)","Args":"duration time.Duration, cb interface{}"},{"Uniquefunname":"func (task *DelayTask) Start(args ...interface","Funname":"Start","Returntype":"error","Args":"args ...interface{}"},{"Uniquefunname":"func (task *DelayTask) Stop()","Funname":"Stop","Returntype":"","Args":""},{"Uniquefunname":"func (task *DelayTask) doStart(values []reflect.Value)","Funname":"doStart","Returntype":"","Args":"values []reflect.Value"},{"Uniquefunname":"func handleFuncSignature(f interface{})(*reflect.Value, []reflect.Type, error)","Funname":"handleFuncSignature","Returntype":"(*reflect.Value, []reflect.Type, error)","Args":"f interface{}"},{"Uniquefunname":"func (task *DelayTask) Start(args ...interface","Funname":"tasker.DelayTask.Start","Returntype":"error","Args":"args ...interface{}"},{"Uniquefunname":"func (task *DelayTask) Stop()","Funname":"tasker.DelayTask.Stop","Returntype":"","Args":""},{"Uniquefunname":"func (task *DelayTask) doStart(values []reflect.Value)","Funname":"tasker.DelayTask.doStart","Returntype":"","Args":"values []reflect.Value"},{"Uniquefunname":"func tasker.NewDelayTask(duration time.Duration, cb interface{})(*DelayTask, error)","Funname":"tasker.NewDelayTask","Returntype":"(*DelayTask, error)","Args":"duration time.Duration, cb interface{}"},{"Uniquefunname":"func tasker.handleFuncSignature(f interface{})(*reflect.Value, []reflect.Type, error)","Funname":"tasker.handleFuncSignature","Returntype":"(*reflect.Value, []reflect.Type, error)","Args":"f interface{}"}],"Records":[{"Name":"struct:tasker.DelayTask","Fields":["tasker.DelayTask.argsType []reflect.Type","tasker.DelayTask.duration time.Duration","tasker.DelayTask.handler reflect.Value","tasker.DelayTask.locker sync.Mutex","tasker.DelayTask.termination chan struct{}","tasker.DelayTask.timer *time.Timer"]}]} {"Filepath":"tasker/delay_task_manager.go","Functions":[{"Uniquefunname":"func (m *DelayTaskManager) AddTask(name string, duration time.Duration, cb interface","Funname":"AddTask","Returntype":"error","Args":"name string, duration time.Duration, cb interface{}"},{"Uniquefunname":"func (m *DelayTaskManager) DeleteTask(name string)","Funname":"DeleteTask","Returntype":"","Args":"name string"},{"Uniquefunname":"func (m *DelayTaskManager) Destroy()","Funname":"Destroy","Returntype":"","Args":""},{"Uniquefunname":"func (m *DelayTaskManager) GetTask(name string) (*DelayTask, error)","Funname":"GetTask","Returntype":"(*DelayTask, error)","Args":"name string"},{"Uniquefunname":"func NewDelayTaskManager() *DelayTaskManager","Funname":"NewDelayTaskManager","Returntype":"*DelayTaskManager","Args":""},{"Uniquefunname":"func (m *DelayTaskManager) AddTask(name string, duration time.Duration, cb interface","Funname":"tasker.DelayTaskManager.AddTask","Returntype":"error","Args":"name string, duration time.Duration, cb interface{}"},{"Uniquefunname":"func (m *DelayTaskManager) DeleteTask(name string)","Funname":"tasker.DelayTaskManager.DeleteTask","Returntype":"","Args":"name string"},{"Uniquefunname":"func (m *DelayTaskManager) Destroy()","Funname":"tasker.DelayTaskManager.Destroy","Returntype":"","Args":""},{"Uniquefunname":"func (m *DelayTaskManager) GetTask(name string) (*DelayTask, error)","Funname":"tasker.DelayTaskManager.GetTask","Returntype":"(*DelayTask, error)","Args":"name string"},{"Uniquefunname":"func NewDelayTaskManager() *DelayTaskManager","Funname":"tasker.NewDelayTaskManager","Returntype":"*DelayTaskManager","Args":""}],"Records":[{"Name":"struct:tasker.DelayTaskManager","Fields":["tasker.DelayTaskManager.locker sync.Mutex","tasker.DelayTaskManager.taskMap map[string]*DelayTask"]}]} {"Filepath":"tasker/tasker_test.go","Functions":[{"Uniquefunname":"func TestDelayTask(t *testing.T)","Funname":"TestDelayTask","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func handleTask(id int, name string)","Funname":"handleTask","Returntype":"","Args":"id int, name string"},{"Uniquefunname":"func TestDelayTask(t *testing.T)","Funname":"tasker.TestDelayTask","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func handleTask(id int, name string)","Funname":"tasker.handleTask","Returntype":"","Args":"id int, name string"}],"Records":null} {"Filepath":"timer/time.go","Functions":[{"Uniquefunname":"func GetMonotonicTime() TimeSpec","Funname":"GetMonotonicTime","Returntype":"TimeSpec","Args":""},{"Uniquefunname":"func (ts TimeSpec) MicroSeconds() int64","Funname":"MicroSeconds","Returntype":"int64","Args":""},{"Uniquefunname":"func (ts TimeSpec) Milliseconds() int64","Funname":"Milliseconds","Returntype":"int64","Args":""},{"Uniquefunname":"func (ts TimeSpec) NanoSeconds() int64","Funname":"NanoSeconds","Returntype":"int64","Args":""},{"Uniquefunname":"func (ts TimeSpec) Seconds() int64","Funname":"Seconds","Returntype":"int64","Args":""},{"Uniquefunname":"func (ts TimeSpec) String() string","Funname":"String","Returntype":"string","Args":""},{"Uniquefunname":"func GetMonotonicTime() TimeSpec","Funname":"timer.GetMonotonicTime","Returntype":"TimeSpec","Args":""},{"Uniquefunname":"func (ts TimeSpec) MicroSeconds() int64","Funname":"timer.TimeSpec.MicroSeconds","Returntype":"int64","Args":""},{"Uniquefunname":"func (ts TimeSpec) Milliseconds() int64","Funname":"timer.TimeSpec.Milliseconds","Returntype":"int64","Args":""},{"Uniquefunname":"func (ts TimeSpec) NanoSeconds() int64","Funname":"timer.TimeSpec.NanoSeconds","Returntype":"int64","Args":""},{"Uniquefunname":"func (ts TimeSpec) Seconds() int64","Funname":"timer.TimeSpec.Seconds","Returntype":"int64","Args":""},{"Uniquefunname":"func (ts TimeSpec) String() string","Funname":"timer.TimeSpec.String","Returntype":"string","Args":""}],"Records":[{"Name":"struct:timer.TimeSpec","Fields":["timer.TimeSpec.nanoSeconds int64","timer.TimeSpec.seconds int64"]}]} {"Filepath":"timer/timer.go","Functions":[{"Uniquefunname":"func (timer *Timer) Continue()","Funname":"Continue","Returntype":"","Args":""},{"Uniquefunname":"func (timer *Timer) Elapsed() time.Duration","Funname":"Elapsed","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func NewTimer() *Timer","Funname":"NewTimer","Returntype":"*Timer","Args":""},{"Uniquefunname":"func (timer *Timer) Reset()","Funname":"Reset","Returntype":"","Args":""},{"Uniquefunname":"func (timer *Timer) Start()","Funname":"Start","Returntype":"","Args":""},{"Uniquefunname":"func (timer *Timer) Stop()","Funname":"Stop","Returntype":"","Args":""},{"Uniquefunname":"func NewTimer() *Timer","Funname":"timer.NewTimer","Returntype":"*Timer","Args":""},{"Uniquefunname":"func (timer *Timer) Continue()","Funname":"timer.Timer.Continue","Returntype":"","Args":""},{"Uniquefunname":"func (timer *Timer) Elapsed() time.Duration","Funname":"timer.Timer.Elapsed","Returntype":"time.Duration","Args":""},{"Uniquefunname":"func (timer *Timer) Reset()","Funname":"timer.Timer.Reset","Returntype":"","Args":""},{"Uniquefunname":"func (timer *Timer) Start()","Funname":"timer.Timer.Start","Returntype":"","Args":""},{"Uniquefunname":"func (timer *Timer) Stop()","Funname":"timer.Timer.Stop","Returntype":"","Args":""}],"Records":[{"Name":"struct:timer.Timer","Fields":["timer.Timer.duration time.Duration","timer.Timer.lastDuration time.Duration","timer.Timer.state _TimerState","timer.Timer.timer time.Time"]},{"Name":"const:timer","Fields":["timer._TimerStateNotStarted","timer._TimerStateStarted","timer._TimerStateStopped"]}]} {"Filepath":"timer/timer_test.go","Functions":[{"Uniquefunname":"func TestTimer(t *testing.T)","Funname":"TestTimer","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestTimer(t *testing.T)","Funname":"timer_test.TestTimer","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"users/group/group.go","Functions":[{"Uniquefunname":"func (err *GroupNotFoundError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func GetGroupByGid(gid uint32) (*Group, error)","Funname":"GetGroupByGid","Returntype":"(*Group, error)","Args":"gid uint32"},{"Uniquefunname":"func GetGroupByName(name string) (*Group, error)","Funname":"GetGroupByName","Returntype":"(*Group, error)","Args":"name string"},{"Uniquefunname":"func GetGroupEntry() []*Group","Funname":"GetGroupEntry","Returntype":"[]*Group","Args":""},{"Uniquefunname":"func GetGroupByGid(gid uint32) (*Group, error)","Funname":"group.GetGroupByGid","Returntype":"(*Group, error)","Args":"gid uint32"},{"Uniquefunname":"func GetGroupByName(name string) (*Group, error)","Funname":"group.GetGroupByName","Returntype":"(*Group, error)","Args":"name string"},{"Uniquefunname":"func GetGroupEntry() []*Group","Funname":"group.GetGroupEntry","Returntype":"[]*Group","Args":""},{"Uniquefunname":"func (err *GroupNotFoundError) Error() string","Funname":"group.GroupNotFoundError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func groupC2Go(groupC *C.struct_group) *Group","Funname":"group.groupC2Go","Returntype":"*Group","Args":"groupC *C.struct_group"},{"Uniquefunname":"func stringArrayC2Go_2(strArrC **C.char) *[]string","Funname":"group.stringArrayC2Go_2","Returntype":"*[]string","Args":"strArrC **C.char"},{"Uniquefunname":"func groupC2Go(groupC *C.struct_group) *Group","Funname":"groupC2Go","Returntype":"*Group","Args":"groupC *C.struct_group"},{"Uniquefunname":"func stringArrayC2Go_2(strArrC **C.char) *[]string","Funname":"stringArrayC2Go_2","Returntype":"*[]string","Args":"strArrC **C.char"}],"Records":[{"Name":"struct:group.Group","Fields":["group.Group.Gid uint32","group.Group.Members *[]string","group.Group.Name string","group.Group.Passwd string"]},{"Name":"struct:group.GroupNotFoundError","Fields":["group.GroupNotFoundError.Gid uint32","group.GroupNotFoundError.Name string"]}]} {"Filepath":"users/group/group_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestGetGroupByGid(c *C.C)","Funname":"TestGetGroupByGid","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetGroupByName(c *C.C)","Funname":"TestGetGroupByName","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetGroupEntry(c *C.C)","Funname":"TestGetGroupEntry","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func Test(t *testing.T)","Funname":"group.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"group.init","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) TestGetGroupByGid(c *C.C)","Funname":"group.testWrapper.TestGetGroupByGid","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetGroupByName(c *C.C)","Funname":"group.testWrapper.TestGetGroupByName","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetGroupEntry(c *C.C)","Funname":"group.testWrapper.TestGetGroupEntry","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""}],"Records":null} {"Filepath":"users/passwd/passwd.go","Functions":[{"Uniquefunname":"func (err *UserNotFoundError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func GetPasswdByName(name string) (*Passwd, error)","Funname":"GetPasswdByName","Returntype":"(*Passwd, error)","Args":"name string"},{"Uniquefunname":"func GetPasswdByUid(uid uint32) (*Passwd, error)","Funname":"GetPasswdByUid","Returntype":"(*Passwd, error)","Args":"uid uint32"},{"Uniquefunname":"func GetPasswdEntry() []*Passwd","Funname":"GetPasswdEntry","Returntype":"[]*Passwd","Args":""},{"Uniquefunname":"func GetPasswdByName(name string) (*Passwd, error)","Funname":"passwd.GetPasswdByName","Returntype":"(*Passwd, error)","Args":"name string"},{"Uniquefunname":"func GetPasswdByUid(uid uint32) (*Passwd, error)","Funname":"passwd.GetPasswdByUid","Returntype":"(*Passwd, error)","Args":"uid uint32"},{"Uniquefunname":"func GetPasswdEntry() []*Passwd","Funname":"passwd.GetPasswdEntry","Returntype":"[]*Passwd","Args":""},{"Uniquefunname":"func (err *UserNotFoundError) Error() string","Funname":"passwd.UserNotFoundError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func passwdC2Go(passwdC *C.struct_passwd) *Passwd","Funname":"passwd.passwdC2Go","Returntype":"*Passwd","Args":"passwdC *C.struct_passwd"},{"Uniquefunname":"func passwdC2Go(passwdC *C.struct_passwd) *Passwd","Funname":"passwdC2Go","Returntype":"*Passwd","Args":"passwdC *C.struct_passwd"}],"Records":[{"Name":"struct:passwd.Passwd","Fields":["passwd.Passwd.Comment string","passwd.Passwd.Gid uint32","passwd.Passwd.Home string","passwd.Passwd.Name string","passwd.Passwd.Passwd string","passwd.Passwd.Shell string","passwd.Passwd.Uid uint32"]},{"Name":"struct:passwd.UserNotFoundError","Fields":["passwd.UserNotFoundError.Name string","passwd.UserNotFoundError.Uid uint32"]}]} {"Filepath":"users/passwd/passwd_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestGetPasswdByName(c *C.C)","Funname":"TestGetPasswdByName","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetPasswdByUid(c *C.C)","Funname":"TestGetPasswdByUid","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetPasswdEntry(c *C.C)","Funname":"TestGetPasswdEntry","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func Test(t *testing.T)","Funname":"passwd.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"passwd.init","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) TestGetPasswdByName(c *C.C)","Funname":"passwd.testWrapper.TestGetPasswdByName","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetPasswdByUid(c *C.C)","Funname":"passwd.testWrapper.TestGetPasswdByUid","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetPasswdEntry(c *C.C)","Funname":"passwd.testWrapper.TestGetPasswdEntry","Returntype":"","Args":"c *C.C"}],"Records":null} {"Filepath":"users/shadow/shadow.go","Functions":[{"Uniquefunname":"func (err *UserNotFoundError) Error() string","Funname":"Error","Returntype":"string","Args":""},{"Uniquefunname":"func GetShadowByName(name string) (*Shadow, error)","Funname":"GetShadowByName","Returntype":"(*Shadow, error)","Args":"name string"},{"Uniquefunname":"func GetShadowEntry() []*Shadow","Funname":"GetShadowEntry","Returntype":"[]*Shadow","Args":""},{"Uniquefunname":"func GetShadowByName(name string) (*Shadow, error)","Funname":"shadow.GetShadowByName","Returntype":"(*Shadow, error)","Args":"name string"},{"Uniquefunname":"func GetShadowEntry() []*Shadow","Funname":"shadow.GetShadowEntry","Returntype":"[]*Shadow","Args":""},{"Uniquefunname":"func (err *UserNotFoundError) Error() string","Funname":"shadow.UserNotFoundError.Error","Returntype":"string","Args":""},{"Uniquefunname":"func shadowC2Go(shadowC *C.struct_spwd) *Shadow","Funname":"shadow.shadowC2Go","Returntype":"*Shadow","Args":"shadowC *C.struct_spwd"},{"Uniquefunname":"func shadowC2Go(shadowC *C.struct_spwd) *Shadow","Funname":"shadowC2Go","Returntype":"*Shadow","Args":"shadowC *C.struct_spwd"}],"Records":[{"Name":"struct:shadow.Shadow","Fields":["shadow.Shadow.Expire int64","shadow.Shadow.Flag uint64","shadow.Shadow.Inactive int64","shadow.Shadow.LastChange int64","shadow.Shadow.MaxDays int64","shadow.Shadow.MinDays int64","shadow.Shadow.Name string","shadow.Shadow.Password string","shadow.Shadow.Warn int64"]},{"Name":"struct:shadow.UserNotFoundError","Fields":["shadow.UserNotFoundError.Name string","shadow.UserNotFoundError.Uid uint32"]}]} {"Filepath":"users/shadow/shadow_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestGetShadowByName(c *C.C)","Funname":"TestGetShadowByName","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetShadowEntry(c *C.C)","Funname":"TestGetShadowEntry","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func Test(t *testing.T)","Funname":"shadow.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"shadow.init","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) TestGetShadowByName(c *C.C)","Funname":"shadow.testWrapper.TestGetShadowByName","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetShadowEntry(c *C.C)","Funname":"shadow.testWrapper.TestGetShadowEntry","Returntype":"","Args":"c *C.C"}],"Records":null} {"Filepath":"utils/cache.go","Functions":[{"Uniquefunname":"func GenerateCacheFilePath(keyword string) (dstfile string)","Funname":"GenerateCacheFilePath","Returntype":"(dstfile string)","Args":"keyword string"},{"Uniquefunname":"func GenerateCacheFilePathWithPrefix(prefix, keyword string) (dstfile string)","Funname":"GenerateCacheFilePathWithPrefix","Returntype":"(dstfile string)","Args":"prefix, keyword string"},{"Uniquefunname":"func GenerateCacheFilePath(keyword string) (dstfile string)","Funname":"utils.GenerateCacheFilePath","Returntype":"(dstfile string)","Args":"keyword string"},{"Uniquefunname":"func GenerateCacheFilePathWithPrefix(prefix, keyword string) (dstfile string)","Funname":"utils.GenerateCacheFilePathWithPrefix","Returntype":"(dstfile string)","Args":"prefix, keyword string"}],"Records":[{"Name":"var:utils","Fields":["utils.DefaultCachePrefix"]}]} {"Filepath":"utils/config.go","Functions":[{"Uniquefunname":"func (c *Config) GetConfigFile() string","Funname":"GetConfigFile","Returntype":"string","Args":""},{"Uniquefunname":"func (c *Config) GetFileContentToSave(v interface","Funname":"GetFileContentToSave","Returntype":"(fileContent []byte, err error)","Args":"v interface{}"},{"Uniquefunname":"func (c *Config) IsConfigFileExists() bool","Funname":"IsConfigFileExists","Returntype":"bool","Args":""},{"Uniquefunname":"func (c *Config) Load(v interface","Funname":"Load","Returntype":"(err error)","Args":"v interface{}"},{"Uniquefunname":"func (c *Config) Lock()","Funname":"Lock","Returntype":"","Args":""},{"Uniquefunname":"func (c *Config) RemoveConfigFile() error","Funname":"RemoveConfigFile","Returntype":"error","Args":""},{"Uniquefunname":"func (c *Config) Save(v interface","Funname":"Save","Returntype":"(err error)","Args":"v interface{}"},{"Uniquefunname":"func (c *Config) SetConfigFile(file string)","Funname":"SetConfigFile","Returntype":"","Args":"file string"},{"Uniquefunname":"func (c *Config) SetConfigName(name string)","Funname":"SetConfigName","Returntype":"","Args":"name string"},{"Uniquefunname":"func (c *Config) SetSystemConfigName(name string)","Funname":"SetSystemConfigName","Returntype":"","Args":"name string"},{"Uniquefunname":"func (c *Config) Unlock()","Funname":"Unlock","Returntype":"","Args":""},{"Uniquefunname":"func (c *Config) GetConfigFile() string","Funname":"utils.Config.GetConfigFile","Returntype":"string","Args":""},{"Uniquefunname":"func (c *Config) GetFileContentToSave(v interface","Funname":"utils.Config.GetFileContentToSave","Returntype":"(fileContent []byte, err error)","Args":"v interface{}"},{"Uniquefunname":"func (c *Config) IsConfigFileExists() bool","Funname":"utils.Config.IsConfigFileExists","Returntype":"bool","Args":""},{"Uniquefunname":"func (c *Config) Load(v interface","Funname":"utils.Config.Load","Returntype":"(err error)","Args":"v interface{}"},{"Uniquefunname":"func (c *Config) Lock()","Funname":"utils.Config.Lock","Returntype":"","Args":""},{"Uniquefunname":"func (c *Config) RemoveConfigFile() error","Funname":"utils.Config.RemoveConfigFile","Returntype":"error","Args":""},{"Uniquefunname":"func (c *Config) Save(v interface","Funname":"utils.Config.Save","Returntype":"(err error)","Args":"v interface{}"},{"Uniquefunname":"func (c *Config) SetConfigFile(file string)","Funname":"utils.Config.SetConfigFile","Returntype":"","Args":"file string"},{"Uniquefunname":"func (c *Config) SetConfigName(name string)","Funname":"utils.Config.SetConfigName","Returntype":"","Args":"name string"},{"Uniquefunname":"func (c *Config) SetSystemConfigName(name string)","Funname":"utils.Config.SetSystemConfigName","Returntype":"","Args":"name string"},{"Uniquefunname":"func (c *Config) Unlock()","Funname":"utils.Config.Unlock","Returntype":"","Args":""}],"Records":[{"Name":"struct:utils.Config","Fields":["utils.Config.configFile string","utils.Config.lock sync.Mutex"]},{"Name":"var:utils","Fields":["utils.DefaultConfigExt","utils.DefaultHomeConfigPrefix","utils.DefaultSystemConfigPrefix"]}]} {"Filepath":"utils/config_test.go","Functions":[{"Uniquefunname":"func (*testWrapper) TestConfig(c *C.C)","Funname":"TestConfig","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (c *testConfig) load()","Funname":"load","Returntype":"","Args":""},{"Uniquefunname":"func newTestConfig() (c *testConfig)","Funname":"newTestConfig","Returntype":"(c *testConfig)","Args":""},{"Uniquefunname":"func (c *testConfig) save() error","Funname":"save","Returntype":"error","Args":""},{"Uniquefunname":"func newTestConfig() (c *testConfig)","Funname":"utils.newTestConfig","Returntype":"(c *testConfig)","Args":""},{"Uniquefunname":"func (c *testConfig) load()","Funname":"utils.testConfig.load","Returntype":"","Args":""},{"Uniquefunname":"func (c *testConfig) save() error","Funname":"utils.testConfig.save","Returntype":"error","Args":""},{"Uniquefunname":"func (*testWrapper) TestConfig(c *C.C)","Funname":"utils.testWrapper.TestConfig","Returntype":"","Args":"c *C.C"}],"Records":[{"Name":"struct:utils.testConfig","Fields":["utils.testConfig.Data string","utils.testConfig.core Config"]}]} {"Filepath":"utils/file.go","Functions":[{"Uniquefunname":"func CopyDir(src, dest string) error","Funname":"CopyDir","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func CopyFile(src, dest string) (err error)","Funname":"CopyFile","Returntype":"(err error)","Args":"src, dest string"},{"Uniquefunname":"func CreateFile(filename string) error","Funname":"CreateFile","Returntype":"error","Args":"filename string"},{"Uniquefunname":"func EnsureDirExist(path string) error","Funname":"EnsureDirExist","Returntype":"error","Args":"path string"},{"Uniquefunname":"func EnsureDirExistWithPerm(path string, perm os.FileMode) error","Funname":"EnsureDirExistWithPerm","Returntype":"error","Args":"path string, perm os.FileMode"},{"Uniquefunname":"func GetFilesInDir(dir string) ([]string, error)","Funname":"GetFilesInDir","Returntype":"([]string, error)","Args":"dir string"},{"Uniquefunname":"func IsDir(path string) bool","Funname":"IsDir","Returntype":"bool","Args":"path string"},{"Uniquefunname":"func IsFileExist(path string) bool","Funname":"IsFileExist","Returntype":"bool","Args":"path string"},{"Uniquefunname":"func IsSymlink(path string) bool","Funname":"IsSymlink","Returntype":"bool","Args":"path string"},{"Uniquefunname":"func MoveDir(src, dest string) error","Funname":"MoveDir","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func MoveFile(src, dest string) error","Funname":"MoveFile","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func SymlinkFile(src, dest string) error","Funname":"SymlinkFile","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func iterCopyDir(src, dest string, mode os.FileMode) error","Funname":"iterCopyDir","Returntype":"error","Args":"src, dest string, mode os.FileMode"},{"Uniquefunname":"func symlinkIsDir(link string) bool","Funname":"symlinkIsDir","Returntype":"bool","Args":"link string"},{"Uniquefunname":"func CopyDir(src, dest string) error","Funname":"utils.CopyDir","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func CopyFile(src, dest string) (err error)","Funname":"utils.CopyFile","Returntype":"(err error)","Args":"src, dest string"},{"Uniquefunname":"func CreateFile(filename string) error","Funname":"utils.CreateFile","Returntype":"error","Args":"filename string"},{"Uniquefunname":"func EnsureDirExist(path string) error","Funname":"utils.EnsureDirExist","Returntype":"error","Args":"path string"},{"Uniquefunname":"func EnsureDirExistWithPerm(path string, perm os.FileMode) error","Funname":"utils.EnsureDirExistWithPerm","Returntype":"error","Args":"path string, perm os.FileMode"},{"Uniquefunname":"func GetFilesInDir(dir string) ([]string, error)","Funname":"utils.GetFilesInDir","Returntype":"([]string, error)","Args":"dir string"},{"Uniquefunname":"func IsDir(path string) bool","Funname":"utils.IsDir","Returntype":"bool","Args":"path string"},{"Uniquefunname":"func IsFileExist(path string) bool","Funname":"utils.IsFileExist","Returntype":"bool","Args":"path string"},{"Uniquefunname":"func IsSymlink(path string) bool","Funname":"utils.IsSymlink","Returntype":"bool","Args":"path string"},{"Uniquefunname":"func MoveDir(src, dest string) error","Funname":"utils.MoveDir","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func MoveFile(src, dest string) error","Funname":"utils.MoveFile","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func SymlinkFile(src, dest string) error","Funname":"utils.SymlinkFile","Returntype":"error","Args":"src, dest string"},{"Uniquefunname":"func iterCopyDir(src, dest string, mode os.FileMode) error","Funname":"utils.iterCopyDir","Returntype":"error","Args":"src, dest string, mode os.FileMode"},{"Uniquefunname":"func symlinkIsDir(link string) bool","Funname":"utils.symlinkIsDir","Returntype":"bool","Args":"link string"}],"Records":null} {"Filepath":"utils/file_test.go","Functions":[{"Uniquefunname":"func (*testWrapper) TestCopyDir(c *C.C)","Funname":"TestCopyDir","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestCreateFile(c *C.C)","Funname":"TestCreateFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetFiles(c *C.C)","Funname":"TestGetFiles","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestSymlinkFile(c *C.C)","Funname":"TestSymlinkFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestCopyDir(c *C.C)","Funname":"utils.testWrapper.TestCopyDir","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestCreateFile(c *C.C)","Funname":"utils.testWrapper.TestCreateFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetFiles(c *C.C)","Funname":"utils.testWrapper.TestGetFiles","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestSymlinkFile(c *C.C)","Funname":"utils.testWrapper.TestSymlinkFile","Returntype":"","Args":"c *C.C"}],"Records":null} {"Filepath":"utils/filesystem.go","Functions":[{"Uniquefunname":"func QueryFilesytemInfo(path string) (*FilesystemInfo, error)","Funname":"QueryFilesytemInfo","Returntype":"(*FilesystemInfo, error)","Args":"path string"},{"Uniquefunname":"func QueryFilesytemInfo(path string) (*FilesystemInfo, error)","Funname":"utils.QueryFilesytemInfo","Returntype":"(*FilesystemInfo, error)","Args":"path string"}],"Records":[{"Name":"struct:utils.FilesystemInfo","Fields":["utils.FilesystemInfo.AvailSize uint64","utils.FilesystemInfo.FreeSize uint64","utils.FilesystemInfo.TotalSize uint64","utils.FilesystemInfo.UsedSize uint64"]}]} {"Filepath":"utils/keyfile.go","Functions":[{"Uniquefunname":"func NewKeyFileFromFile(file string) (*glib.KeyFile, error)","Funname":"NewKeyFileFromFile","Returntype":"(*glib.KeyFile, error)","Args":"file string"},{"Uniquefunname":"func ReadKeyFromKeyFile(filename, group, key string, t interface","Funname":"ReadKeyFromKeyFile","Returntype":"(interface{}, bool)","Args":"filename, group, key string, t interface{}"},{"Uniquefunname":"func WriteKeyToKeyFile(filename, group, key string, value interface","Funname":"WriteKeyToKeyFile","Returntype":"bool","Args":"filename, group, key string, value interface{}"},{"Uniquefunname":"func WriteStringToFile(filename, content string) error","Funname":"WriteStringToFile","Returntype":"error","Args":"filename, content string"},{"Uniquefunname":"func WriteStringToKeyFile(filename, content string) bool","Funname":"WriteStringToKeyFile","Returntype":"bool","Args":"filename, content string"},{"Uniquefunname":"func NewKeyFileFromFile(file string) (*glib.KeyFile, error)","Funname":"utils.NewKeyFileFromFile","Returntype":"(*glib.KeyFile, error)","Args":"file string"},{"Uniquefunname":"func ReadKeyFromKeyFile(filename, group, key string, t interface","Funname":"utils.ReadKeyFromKeyFile","Returntype":"(interface{}, bool)","Args":"filename, group, key string, t interface{}"},{"Uniquefunname":"func WriteKeyToKeyFile(filename, group, key string, value interface","Funname":"utils.WriteKeyToKeyFile","Returntype":"bool","Args":"filename, group, key string, value interface{}"},{"Uniquefunname":"func WriteStringToFile(filename, content string) error","Funname":"utils.WriteStringToFile","Returntype":"error","Args":"filename, content string"},{"Uniquefunname":"func WriteStringToKeyFile(filename, content string) bool","Funname":"utils.WriteStringToKeyFile","Returntype":"bool","Args":"filename, content string"}],"Records":[{"Name":"var:utils","Fields":["utils.kfLocker"]}]} {"Filepath":"utils/keyfile_test.go","Functions":[{"Uniquefunname":"func (*testWrapper) TestKeyFile(c *C.C)","Funname":"TestKeyFile","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestKeyFile(c *C.C)","Funname":"utils.testWrapper.TestKeyFile","Returntype":"","Args":"c *C.C"}],"Records":null} {"Filepath":"utils/md5.go","Functions":[{"Uniquefunname":"func SumFileMd5(filename string) (string, bool)","Funname":"SumFileMd5","Returntype":"(string, bool)","Args":"filename string"},{"Uniquefunname":"func SumStrMd5(str string) (string, bool)","Funname":"SumStrMd5","Returntype":"(string, bool)","Args":"str string"},{"Uniquefunname":"func SumFileMd5(filename string) (string, bool)","Funname":"utils.SumFileMd5","Returntype":"(string, bool)","Args":"filename string"},{"Uniquefunname":"func SumStrMd5(str string) (string, bool)","Funname":"utils.SumStrMd5","Returntype":"(string, bool)","Args":"str string"}],"Records":null} {"Filepath":"utils/md5_test.go","Functions":[{"Uniquefunname":"func (*testWrapper) TestMD5Sum(c *C.C)","Funname":"TestMD5Sum","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestMD5Sum(c *C.C)","Funname":"utils.testWrapper.TestMD5Sum","Returntype":"","Args":"c *C.C"}],"Records":null} {"Filepath":"utils/os.go","Functions":[{"Uniquefunname":"func ExecAndWait(timeout int, name string, arg ...string) (stdout, stderr string, err error)","Funname":"ExecAndWait","Returntype":"(stdout, stderr string, err error)","Args":"timeout int, name string, arg ...string"},{"Uniquefunname":"func GetUserName() string","Funname":"GetUserName","Returntype":"string","Args":""},{"Uniquefunname":"func IsEnvExists(envName string) (ok bool)","Funname":"IsEnvExists","Returntype":"(ok bool)","Args":"envName string"},{"Uniquefunname":"func UnsetEnv(envName string) (err error)","Funname":"UnsetEnv","Returntype":"(err error)","Args":"envName string"},{"Uniquefunname":"func doUnsetEnvC(envName string)","Funname":"doUnsetEnvC","Returntype":"","Args":"envName string"},{"Uniquefunname":"func ExecAndWait(timeout int, name string, arg ...string) (stdout, stderr string, err error)","Funname":"utils.ExecAndWait","Returntype":"(stdout, stderr string, err error)","Args":"timeout int, name string, arg ...string"},{"Uniquefunname":"func GetUserName() string","Funname":"utils.GetUserName","Returntype":"string","Args":""},{"Uniquefunname":"func IsEnvExists(envName string) (ok bool)","Funname":"utils.IsEnvExists","Returntype":"(ok bool)","Args":"envName string"},{"Uniquefunname":"func UnsetEnv(envName string) (err error)","Funname":"utils.UnsetEnv","Returntype":"(err error)","Args":"envName string"},{"Uniquefunname":"func doUnsetEnvC(envName string)","Funname":"utils.doUnsetEnvC","Returntype":"","Args":"envName string"}],"Records":null} {"Filepath":"utils/schemas.go","Functions":[{"Uniquefunname":"func CheckAndNewGSettings(schema string) (*gio.Settings, error)","Funname":"CheckAndNewGSettings","Returntype":"(*gio.Settings, error)","Args":"schema string"},{"Uniquefunname":"func IsGSchemaExist(schema string) bool","Funname":"IsGSchemaExist","Returntype":"bool","Args":"schema string"},{"Uniquefunname":"func isSchemaInList(schema string, list []string) bool","Funname":"isSchemaInList","Returntype":"bool","Args":"schema string, list []string"},{"Uniquefunname":"func CheckAndNewGSettings(schema string) (*gio.Settings, error)","Funname":"utils.CheckAndNewGSettings","Returntype":"(*gio.Settings, error)","Args":"schema string"},{"Uniquefunname":"func IsGSchemaExist(schema string) bool","Funname":"utils.IsGSchemaExist","Returntype":"bool","Args":"schema string"},{"Uniquefunname":"func isSchemaInList(schema string, list []string) bool","Funname":"utils.isSchemaInList","Returntype":"bool","Args":"schema string, list []string"}],"Records":null} {"Filepath":"utils/schemas_test.go","Functions":[{"Uniquefunname":"func (*testWrapper) TestGSchemaIsExist(c *C.C)","Funname":"TestGSchemaIsExist","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGSchemaIsExist(c *C.C)","Funname":"utils.testWrapper.TestGSchemaIsExist","Returntype":"","Args":"c *C.C"}],"Records":[{"Name":"struct:utils.schemaTest","Fields":["utils.schemaTest.exist bool","utils.schemaTest.schema string"]}]} {"Filepath":"utils/uri.go","Functions":[{"Uniquefunname":"func DecodeURI(uri string) (content string)","Funname":"DecodeURI","Returntype":"(content string)","Args":"uri string"},{"Uniquefunname":"func EncodeURI(content, scheme string) (uri string)","Funname":"EncodeURI","Returntype":"(uri string)","Args":"content, scheme string"},{"Uniquefunname":"func GetURIContent(uri string) (content string)","Funname":"GetURIContent","Returntype":"(content string)","Args":"uri string"},{"Uniquefunname":"func GetURIScheme(uri string) (scheme string)","Funname":"GetURIScheme","Returntype":"(scheme string)","Args":"uri string"},{"Uniquefunname":"func IsURI(s string) (ok bool)","Funname":"IsURI","Returntype":"(ok bool)","Args":"s string"},{"Uniquefunname":"func PathToURI(filepath, scheme string) string","Funname":"PathToURI","Returntype":"string","Args":"filepath, scheme string"},{"Uniquefunname":"func URIToPath(uri string) string","Funname":"URIToPath","Returntype":"string","Args":"uri string"},{"Uniquefunname":"func deleteStartSpace(str string) string","Funname":"deleteStartSpace","Returntype":"string","Args":"str string"},{"Uniquefunname":"func isBeginWithStr(str, substr string) bool","Funname":"isBeginWithStr","Returntype":"bool","Args":"str, substr string"},{"Uniquefunname":"func pathToFileURI(filepath string) string","Funname":"pathToFileURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func pathToFtpURI(filepath string) string","Funname":"pathToFtpURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func pathToHttpURI(filepath string) string","Funname":"pathToHttpURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func pathToHttpsURI(filepath string) string","Funname":"pathToHttpsURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func pathToSmbURI(filepath string) string","Funname":"pathToSmbURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func DecodeURI(uri string) (content string)","Funname":"utils.DecodeURI","Returntype":"(content string)","Args":"uri string"},{"Uniquefunname":"func EncodeURI(content, scheme string) (uri string)","Funname":"utils.EncodeURI","Returntype":"(uri string)","Args":"content, scheme string"},{"Uniquefunname":"func GetURIContent(uri string) (content string)","Funname":"utils.GetURIContent","Returntype":"(content string)","Args":"uri string"},{"Uniquefunname":"func GetURIScheme(uri string) (scheme string)","Funname":"utils.GetURIScheme","Returntype":"(scheme string)","Args":"uri string"},{"Uniquefunname":"func IsURI(s string) (ok bool)","Funname":"utils.IsURI","Returntype":"(ok bool)","Args":"s string"},{"Uniquefunname":"func PathToURI(filepath, scheme string) string","Funname":"utils.PathToURI","Returntype":"string","Args":"filepath, scheme string"},{"Uniquefunname":"func URIToPath(uri string) string","Funname":"utils.URIToPath","Returntype":"string","Args":"uri string"},{"Uniquefunname":"func deleteStartSpace(str string) string","Funname":"utils.deleteStartSpace","Returntype":"string","Args":"str string"},{"Uniquefunname":"func isBeginWithStr(str, substr string) bool","Funname":"utils.isBeginWithStr","Returntype":"bool","Args":"str, substr string"},{"Uniquefunname":"func pathToFileURI(filepath string) string","Funname":"utils.pathToFileURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func pathToFtpURI(filepath string) string","Funname":"utils.pathToFtpURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func pathToHttpURI(filepath string) string","Funname":"utils.pathToHttpURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func pathToHttpsURI(filepath string) string","Funname":"utils.pathToHttpsURI","Returntype":"string","Args":"filepath string"},{"Uniquefunname":"func pathToSmbURI(filepath string) string","Funname":"utils.pathToSmbURI","Returntype":"string","Args":"filepath string"}],"Records":[{"Name":"const:utils","Fields":["utils.SCHEME_FILE","utils.SCHEME_FTP","utils.SCHEME_HTTP","utils.SCHEME_HTTPS","utils.SCHEME_SMB"]}]} {"Filepath":"utils/user_special_dir.go","Functions":[{"Uniquefunname":"func GetCacheDir() string","Funname":"GetCacheDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetConfigDir() string","Funname":"GetConfigDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetHomeDir() string","Funname":"GetHomeDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetCacheDir() string","Funname":"utils.GetCacheDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetConfigDir() string","Funname":"utils.GetConfigDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetHomeDir() string","Funname":"utils.GetHomeDir","Returntype":"string","Args":""}],"Records":null} {"Filepath":"utils/utils.go","Functions":[{"Uniquefunname":"func GenUuid() string","Funname":"GenUuid","Returntype":"string","Args":""},{"Uniquefunname":"func IsElementEqual(e1, e2 interface","Funname":"IsElementEqual","Returntype":"bool","Args":"e1, e2 interface{}"},{"Uniquefunname":"func IsElementInList(e interface","Funname":"IsElementInList","Returntype":"bool","Args":"e interface{}, list interface{}"},{"Uniquefunname":"func IsInterfaceNil(v interface","Funname":"IsInterfaceNil","Returntype":"bool","Args":"v interface{}"},{"Uniquefunname":"func RandString(n int) string","Funname":"RandString","Returntype":"string","Args":"n int"},{"Uniquefunname":"func GenUuid() string","Funname":"utils.GenUuid","Returntype":"string","Args":""},{"Uniquefunname":"func IsElementEqual(e1, e2 interface","Funname":"utils.IsElementEqual","Returntype":"bool","Args":"e1, e2 interface{}"},{"Uniquefunname":"func IsElementInList(e interface","Funname":"utils.IsElementInList","Returntype":"bool","Args":"e interface{}, list interface{}"},{"Uniquefunname":"func IsInterfaceNil(v interface","Funname":"utils.IsInterfaceNil","Returntype":"bool","Args":"v interface{}"},{"Uniquefunname":"func RandString(n int) string","Funname":"utils.RandString","Returntype":"string","Args":"n int"}],"Records":null} {"Filepath":"utils/utils_test.go","Functions":[{"Uniquefunname":"func Test(t *testing.T)","Funname":"Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func (*testWrapper) TestDecodeURI(c *C.C)","Funname":"TestDecodeURI","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestEncodeURI(c *C.C)","Funname":"TestEncodeURI","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGenUuid(c *C.C)","Funname":"TestGenUuid","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetURIContent(c *C.C)","Funname":"TestGetURIContent","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetURIScheme(c *C.C)","Funname":"TestGetURIScheme","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsDir(c *C.C)","Funname":"TestIsDir","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsEnvExists(c *C.C)","Funname":"TestIsEnvExists","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsFileExist(c *C.C)","Funname":"TestIsFileExist","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsInterfaceNil(c *C.C)","Funname":"TestIsInterfaceNil","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsSymlink(c *C.C)","Funname":"TestIsSymlink","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsURI(c *C.C)","Funname":"TestIsURI","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestPathToURI(c *C.C)","Funname":"TestPathToURI","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestRandString(c *C.C)","Funname":"TestRandString","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestURIToPath(c *C.C)","Funname":"TestURIToPath","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestUnsetEnv(c *C.C)","Funname":"TestUnsetEnv","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func init()","Funname":"init","Returntype":"","Args":""},{"Uniquefunname":"func utils.Test(t *testing.T)","Funname":"utils.Test","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func init()","Funname":"utils.init","Returntype":"","Args":""},{"Uniquefunname":"func (*testWrapper) TestDecodeURI(c *C.C)","Funname":"utils.testWrapper.TestDecodeURI","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestEncodeURI(c *C.C)","Funname":"utils.testWrapper.TestEncodeURI","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGenUuid(c *C.C)","Funname":"utils.testWrapper.TestGenUuid","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetURIContent(c *C.C)","Funname":"utils.testWrapper.TestGetURIContent","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestGetURIScheme(c *C.C)","Funname":"utils.testWrapper.TestGetURIScheme","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsDir(c *C.C)","Funname":"utils.testWrapper.TestIsDir","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsEnvExists(c *C.C)","Funname":"utils.testWrapper.TestIsEnvExists","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsFileExist(c *C.C)","Funname":"utils.testWrapper.TestIsFileExist","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsInterfaceNil(c *C.C)","Funname":"utils.testWrapper.TestIsInterfaceNil","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsSymlink(c *C.C)","Funname":"utils.testWrapper.TestIsSymlink","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestIsURI(c *C.C)","Funname":"utils.testWrapper.TestIsURI","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestPathToURI(c *C.C)","Funname":"utils.testWrapper.TestPathToURI","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestRandString(c *C.C)","Funname":"utils.testWrapper.TestRandString","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestURIToPath(c *C.C)","Funname":"utils.testWrapper.TestURIToPath","Returntype":"","Args":"c *C.C"},{"Uniquefunname":"func (*testWrapper) TestUnsetEnv(c *C.C)","Funname":"utils.testWrapper.TestUnsetEnv","Returntype":"","Args":"c *C.C"}],"Records":null} {"Filepath":"utils/watch_proxy.go","Functions":[{"Uniquefunname":"func (w *WatchProxy) EndWatch()","Funname":"EndWatch","Returntype":"","Args":""},{"Uniquefunname":"func NewWatchProxy() *WatchProxy","Funname":"NewWatchProxy","Returntype":"*WatchProxy","Args":""},{"Uniquefunname":"func (w *WatchProxy) ResetFileListWatch()","Funname":"ResetFileListWatch","Returntype":"","Args":""},{"Uniquefunname":"func (w *WatchProxy) SetErrorHandler(f func(error))","Funname":"SetErrorHandler","Returntype":"","Args":"f func(error)"},{"Uniquefunname":"func (w *WatchProxy) SetEventHandler(f func(fsnotify.Event))","Funname":"SetEventHandler","Returntype":"","Args":"f func(fsnotify.Event)"},{"Uniquefunname":"func (w *WatchProxy) SetFileList(fileList []string)","Funname":"SetFileList","Returntype":"","Args":"fileList []string"},{"Uniquefunname":"func (w *WatchProxy) StartWatch()","Funname":"StartWatch","Returntype":"","Args":""},{"Uniquefunname":"func (w *WatchProxy) removeFileListWatch()","Funname":"removeFileListWatch","Returntype":"","Args":""},{"Uniquefunname":"func (w *WatchProxy) setEndFlag(value bool)","Funname":"setEndFlag","Returntype":"","Args":"value bool"},{"Uniquefunname":"func (w *WatchProxy) setFileListWatch()","Funname":"setFileListWatch","Returntype":"","Args":""},{"Uniquefunname":"func NewWatchProxy() *WatchProxy","Funname":"utils.NewWatchProxy","Returntype":"*WatchProxy","Args":""},{"Uniquefunname":"func (w *WatchProxy) EndWatch()","Funname":"utils.WatchProxy.EndWatch","Returntype":"","Args":""},{"Uniquefunname":"func (w *WatchProxy) ResetFileListWatch()","Funname":"utils.WatchProxy.ResetFileListWatch","Returntype":"","Args":""},{"Uniquefunname":"func (w *WatchProxy) SetErrorHandler(f func(error))","Funname":"utils.WatchProxy.SetErrorHandler","Returntype":"","Args":"f func(error)"},{"Uniquefunname":"func (w *WatchProxy) SetEventHandler(f func(fsnotify.Event))","Funname":"utils.WatchProxy.SetEventHandler","Returntype":"","Args":"f func(fsnotify.Event)"},{"Uniquefunname":"func (w *WatchProxy) SetFileList(fileList []string)","Funname":"utils.WatchProxy.SetFileList","Returntype":"","Args":"fileList []string"},{"Uniquefunname":"func (w *WatchProxy) StartWatch()","Funname":"utils.WatchProxy.StartWatch","Returntype":"","Args":""},{"Uniquefunname":"func (w *WatchProxy) removeFileListWatch()","Funname":"utils.WatchProxy.removeFileListWatch","Returntype":"","Args":""},{"Uniquefunname":"func (w *WatchProxy) setEndFlag(value bool)","Funname":"utils.WatchProxy.setEndFlag","Returntype":"","Args":"value bool"},{"Uniquefunname":"func (w *WatchProxy) setFileListWatch()","Funname":"utils.WatchProxy.setFileListWatch","Returntype":"","Args":""}],"Records":[{"Name":"struct:utils.WatchProxy","Fields":["utils.WatchProxy.end chan bool","utils.WatchProxy.endFlag bool","utils.WatchProxy.errorHandler func(error)","utils.WatchProxy.eventHandler func(fsnotify.Event)","utils.WatchProxy.fileList []string","utils.WatchProxy.lock sync.Mutex","utils.WatchProxy.watcher *fsnotify.Watcher"]}]} {"Filepath":"xdg/basedir/basedir.go","Functions":[{"Uniquefunname":"func GetSystemConfigDirs() []string","Funname":"GetSystemConfigDirs","Returntype":"[]string","Args":""},{"Uniquefunname":"func GetSystemDataDirs() []string","Funname":"GetSystemDataDirs","Returntype":"[]string","Args":""},{"Uniquefunname":"func GetUserCacheDir() string","Funname":"GetUserCacheDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetUserConfigDir() string","Funname":"GetUserConfigDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetUserDataDir() string","Funname":"GetUserDataDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetUserHomeDir() string","Funname":"GetUserHomeDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetUserRuntimeDir(strict bool) (string, error)","Funname":"GetUserRuntimeDir","Returntype":"(string, error)","Args":"strict bool"},{"Uniquefunname":"func GetSystemConfigDirs() []string","Funname":"basedir.GetSystemConfigDirs","Returntype":"[]string","Args":""},{"Uniquefunname":"func GetSystemDataDirs() []string","Funname":"basedir.GetSystemDataDirs","Returntype":"[]string","Args":""},{"Uniquefunname":"func GetUserCacheDir() string","Funname":"basedir.GetUserCacheDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetUserConfigDir() string","Funname":"basedir.GetUserConfigDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetUserDataDir() string","Funname":"basedir.GetUserDataDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetUserHomeDir() string","Funname":"basedir.GetUserHomeDir","Returntype":"string","Args":""},{"Uniquefunname":"func GetUserRuntimeDir(strict bool) (string, error)","Funname":"basedir.GetUserRuntimeDir","Returntype":"(string, error)","Args":"strict bool"},{"Uniquefunname":"func filterNotAbs(slice []string) []string","Funname":"basedir.filterNotAbs","Returntype":"[]string","Args":"slice []string"},{"Uniquefunname":"func getFileInfoUid(fi os.FileInfo) int","Funname":"basedir.getFileInfoUid","Returntype":"int","Args":"fi os.FileInfo"},{"Uniquefunname":"func getSystemDirs(envVarName string, defaultDirs []string) []string","Funname":"basedir.getSystemDirs","Returntype":"[]string","Args":"envVarName string, defaultDirs []string"},{"Uniquefunname":"func getUserDir(envVarName string, defaultDir string) string","Funname":"basedir.getUserDir","Returntype":"string","Args":"envVarName string, defaultDir string"},{"Uniquefunname":"func filterNotAbs(slice []string) []string","Funname":"filterNotAbs","Returntype":"[]string","Args":"slice []string"},{"Uniquefunname":"func getFileInfoUid(fi os.FileInfo) int","Funname":"getFileInfoUid","Returntype":"int","Args":"fi os.FileInfo"},{"Uniquefunname":"func getSystemDirs(envVarName string, defaultDirs []string) []string","Funname":"getSystemDirs","Returntype":"[]string","Args":"envVarName string, defaultDirs []string"},{"Uniquefunname":"func getUserDir(envVarName string, defaultDir string) string","Funname":"getUserDir","Returntype":"string","Args":"envVarName string, defaultDir string"}],"Records":null} {"Filepath":"xdg/basedir/basedir_test.go","Functions":[{"Uniquefunname":"func TestFilterNotAbs(t *testing.T)","Funname":"TestFilterNotAbs","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetSystemConfigDirs(t *testing.T)","Funname":"TestGetSystemConfigDirs","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetSystemDataDirs(t *testing.T)","Funname":"TestGetSystemDataDirs","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserCacheDir(t *testing.T)","Funname":"TestGetUserCacheDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserConfigDir(t *testing.T)","Funname":"TestGetUserConfigDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserDataDir(t *testing.T)","Funname":"TestGetUserDataDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserHomeDir(t *testing.T)","Funname":"TestGetUserHomeDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserRuntimeDir(t *testing.T)","Funname":"TestGetUserRuntimeDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestFilterNotAbs(t *testing.T)","Funname":"basedir.TestFilterNotAbs","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetSystemConfigDirs(t *testing.T)","Funname":"basedir.TestGetSystemConfigDirs","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetSystemDataDirs(t *testing.T)","Funname":"basedir.TestGetSystemDataDirs","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserCacheDir(t *testing.T)","Funname":"basedir.TestGetUserCacheDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserConfigDir(t *testing.T)","Funname":"basedir.TestGetUserConfigDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserDataDir(t *testing.T)","Funname":"basedir.TestGetUserDataDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserHomeDir(t *testing.T)","Funname":"basedir.TestGetUserHomeDir","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGetUserRuntimeDir(t *testing.T)","Funname":"basedir.TestGetUserRuntimeDir","Returntype":"","Args":"t *testing.T"}],"Records":null} {"Filepath":"xdg/userdir/userdir.go","Functions":[{"Uniquefunname":"func Get(dir string) string","Funname":"Get","Returntype":"string","Args":"dir string"},{"Uniquefunname":"func ReloadCache() error","Funname":"ReloadCache","Returntype":"error","Args":""},{"Uniquefunname":"func getUserDirsConfigFile() string","Funname":"getUserDirsConfigFile","Returntype":"string","Args":""},{"Uniquefunname":"func parseUserDirsConfig(file string) (map[string]string, error)","Funname":"parseUserDirsConfig","Returntype":"(map[string]string, error)","Args":"file string"},{"Uniquefunname":"func parseValue(val []byte, homeDir string) (string, error)","Funname":"parseValue","Returntype":"(string, error)","Args":"val []byte, homeDir string"},{"Uniquefunname":"func Get(dir string) string","Funname":"userdir.Get","Returntype":"string","Args":"dir string"},{"Uniquefunname":"func ReloadCache() error","Funname":"userdir.ReloadCache","Returntype":"error","Args":""},{"Uniquefunname":"func getUserDirsConfigFile() string","Funname":"userdir.getUserDirsConfigFile","Returntype":"string","Args":""},{"Uniquefunname":"func parseUserDirsConfig(file string) (map[string]string, error)","Funname":"userdir.parseUserDirsConfig","Returntype":"(map[string]string, error)","Args":"file string"},{"Uniquefunname":"func parseValue(val []byte, homeDir string) (string, error)","Funname":"userdir.parseValue","Returntype":"(string, error)","Args":"val []byte, homeDir string"}],"Records":[{"Name":"const:userdir","Fields":["userdir.Desktop","userdir.Documents","userdir.Download","userdir.Music","userdir.Pictures","userdir.PublicShare","userdir.Templates","userdir.Videos"]},{"Name":"var:userdir","Fields":["userdir.errBadValueFormat","userdir.mutex","userdir.userDirsCache"]}]} {"Filepath":"xdg/userdir/userdir_test.go","Functions":[{"Uniquefunname":"func TestGet(t *testing.T)","Funname":"TestGet","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestParseUserDirsConfig(t *testing.T)","Funname":"TestParseUserDirsConfig","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestParseValue(t *testing.T)","Funname":"TestParseValue","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestReloadCache(t *testing.T)","Funname":"TestReloadCache","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestGet(t *testing.T)","Funname":"userdir.TestGet","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestParseUserDirsConfig(t *testing.T)","Funname":"userdir.TestParseUserDirsConfig","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestParseValue(t *testing.T)","Funname":"userdir.TestParseValue","Returntype":"","Args":"t *testing.T"},{"Uniquefunname":"func TestReloadCache(t *testing.T)","Funname":"userdir.TestReloadCache","Returntype":"","Args":"t *testing.T"}],"Records":null} go-lib-5.6.0.9/debian/changelog000664 000000 000000 00000006361 13753517240 016133 0ustar00rootroot000000 000000 go-dlib (0.4.11-1) unstable; urgency=low * Autobuild Tag 0.4.11 -- TagBuilder Fri, 22 Jul 2016 07:45:33 +0000 go-dlib (0.4.10-1) unstable; urgency=low * Autobuild Tag 0.4.10 -- TagBuilder Mon, 23 May 2016 09:38:12 +0000 go-dlib (0.4.8-3) stable; urgency=low * Rebuild Version 0.4.8 -- TagBuilder Thu, 21 Apr 2016 16:09:31 +0000 go-dlib (0.4.8-2) stable; urgency=low * Rebuild Version 0.4.8 -- TagBuilder Mon, 22 Feb 2016 16:12:00 +0000 go-dlib (0.4.8-1) stable; urgency=low * Autobuild Tag 0.4.8 -- TagBuilder Mon, 22 Feb 2016 16:04:08 +0000 go-dlib (0.4.7-1) stable; urgency=low * Autobuild Tag 0.4.7 -- TagBuilder Mon, 22 Feb 2016 09:10:35 +0000 go-dlib (0.4.6-5) stable; urgency=low * Rebuild Version 0.4.6 -- TagBuilder Tue, 26 Jan 2016 15:48:11 +0000 go-dlib (0.4.6-4) stable; urgency=low * Rebuild Version 0.4.6 -- TagBuilder Mon, 25 Jan 2016 17:09:01 +0000 go-dlib (0.4.6-3) stable; urgency=low * Rebuild Version 0.4.6 -- TagBuilder Mon, 25 Jan 2016 16:52:37 +0000 go-dlib (0.4.6-2) stable; urgency=low * Rebuild Version 0.4.6 -- TagBuilder Mon, 25 Jan 2016 16:50:01 +0000 go-dlib (0.4.6-1) stable; urgency=low * Autobuild Tag 0.4.6 -- TagBuilder Tue, 29 Dec 2015 21:08:51 +0000 go-dlib (0.4.5-1) stable; urgency=low * Autobuild Tag 0.4.5 -- TagBuilder Mon, 28 Dec 2015 20:21:44 +0000 go-dlib (0.4.4-2) stable; urgency=low * Rebuild Version 0.4.4 -- TagBuilder Sat, 19 Dec 2015 15:37:43 +0000 go-dlib (0.4.4-1) stable; urgency=low * Autobuild Tag 0.4.4 -- TagBuilder Sat, 19 Dec 2015 13:56:01 +0000 go-dlib (0.4.3-1) stable; urgency=low * Autobuild Tag 0.4.3 -- TagBuilder Wed, 09 Dec 2015 21:44:16 +0000 go-dlib (0.4.2-2) stable; urgency=low * Rebuild Version 0.4.2 -- TagBuilder Wed, 09 Dec 2015 07:04:48 +0000 go-dlib (0.4.2-1) stable; urgency=low * Autobuild Tag 0.4.2 -- TagBuilder Fri, 20 Nov 2015 08:52:33 +0000 go-dlib (0.4.1-2) stable; urgency=low * Rebuild Version 0.4.1 -- TagBuilder Fri, 20 Nov 2015 08:30:12 +0000 go-dlib (0.4.1-1) stable; urgency=low * Autobuild Tag 0.4.1 -- TagBuilder Thu, 06 Aug 2015 10:03:13 +0000 go-dlib (0.4.0-1) stable; urgency=low * Autobuild Tag 0.4.0 -- TagBuilder Thu, 06 Aug 2015 09:16:11 +0000 go-dlib (0.3.0-1) stable; urgency=low * Autobuild Tag 0.3.0-1 -- TagBuilder Wed, 01 Jul 2015 13:49:48 +0000 go-dlib (2014.2-1) stable; urgency=low * Autobuild Tag 2014.2-1 -- TagBuilder Tue, 30 Jun 2015 08:26:15 +0000 go-dlib (0.0.0) unstable; urgency=medium * Unstable release. -- 宋文武 Wed, 12 Nov 2014 13:46:21 +0800 go-lib-5.6.0.9/debian/compat000664 000000 000000 00000000002 13753517240 015451 0ustar00rootroot000000 000000 9 go-lib-5.6.0.9/debian/control000664 000000 000000 00000003023 13753517240 015654 0ustar00rootroot000000 000000 Source: go-dlib Section: devel Priority: extra Maintainer: Deepin Packages Builder Build-Depends: debhelper (>= 9), dh-golang, golang-go, golang-github-linuxdeepin-go-x11-client-dev, golang-gopkg-check.v1-dev, golang-github-smartystreets-goconvey-dev, golang-golang-x-image-dev, golang-gir-gobject-2.0-dev (>> 1.2.0+), golang-gir-gio-2.0-dev (>> 1.2.0+), golang-gir-glib-2.0-dev (>> 1.2.0+), golang-github-cryptix-wav-dev, golang-github-fsnotify-fsnotify-dev, golang-github-mozillazg-go-pinyin-dev, golang-dbus-dev, libpulse-dev, libgtk-3-dev, libcanberra-dev, golang-gopkg-alecthomas-kingpin.v2-dev, mobile-broadband-provider-info, iso-codes, dbus-x11, libasound2-dev, libpam0g-dev, golang-golang-x-net-dev, golang-github-stretchr-testify-dev Standards-Version: 3.9.8 Homepage: http://www.deepin.org Package: golang-dlib-dev Architecture: all Depends: ${misc:Depends}, golang-github-linuxdeepin-go-x11-client-dev, golang-github-cryptix-wav-dev, golang-github-fsnotify-fsnotify-dev, golang-github-mozillazg-go-pinyin-dev, golang-golang-x-image-dev, golang-gir-gobject-2.0-dev (>> 1.2.0+), golang-gir-gio-2.0-dev (>> 1.2.0+), golang-gir-glib-2.0-dev (>> 1.2.0+), golang-dbus-dev, libpulse-dev, libgtk-3-dev, libasound2-dev, libpam0g-dev, golang-golang-x-net-dev Built-Using: ${misc:Built-Using} Provides: go-dlib Description: Go bindings for Deepin Desktop Environment development DLib is a set of Go bindings/libraries for DDE development. Containing dbus (forking from guelfey), glib, gdkpixbuf, pulse and more. go-lib-5.6.0.9/debian/copyright000664 000000 000000 00000001717 13753517240 016214 0ustar00rootroot000000 000000 Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: go-dlib Source: https://gitcafe.com/Deepin/go-lib.git Files: * Copyright: 2017 Deepin Technology Co., Ltd. License: GPL-3+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. . This package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. . You should have received a copy of the GNU General Public License along with this program. If not, see . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". go-lib-5.6.0.9/debian/rules000775 000000 000000 00000000610 13753517240 015330 0ustar00rootroot000000 000000 #!/usr/bin/make -f export DH_GOPKG := pkg.deepin.io/lib export DH_GOLANG_INSTALL_ALL := 1 %: dh $@ --buildsystem=golang --with=golang override_dh_auto_install: dh_auto_install find ${CURDIR}/debian/golang-dlib-dev -regex '.*\.git\|.*testdata\|.*LICENSE\|.*\.gitignore' | xargs rm -rf override_dh_fixperms: dh_fixperms find debian -name 'build_test_locale_data' -exec chmod 755 {} \; go-lib-5.6.0.9/debian/source/000775 000000 000000 00000000000 13753517240 015553 5ustar00rootroot000000 000000 go-lib-5.6.0.9/debian/source/format000664 000000 000000 00000000015 13753517240 016762 0ustar00rootroot000000 000000 3.0 (native) go-lib-5.6.0.9/doc/000775 000000 000000 00000000000 13753517240 013576 5ustar00rootroot000000 000000 go-lib-5.6.0.9/doc/dbusutil.md000664 000000 000000 00000016370 13753517240 015762 0ustar00rootroot000000 000000 # dbusutil [包文档](https://godoc.org/github.com/linuxdeepin/go-lib/dbusutil) ## 一般用法 首先创建 Service。 用 NewSessionService 创建 session 服务; 用 NewSystemService 创建 system 服务。 ```go service := dbusutil.NewSessionServer() ``` 然后导出对象 用 Export 。 ```go e := &Exportable1{} service.Export(e) ``` e 要实现 dbusutil.Exportable 接口,并且必须类型必须是 struct 指针。 ``` func (e *Exportable1) GetDBusExportInfo() dbusutil.ExportInfo { return dbusutil.ExportInfo{ Path: "/the/object/path" Interface: "the.interface.Name" } } ``` 之后申请服务名,调用 service 的 RequestName 方法, 如果服务名已被其他连接申请了,就会返回错误。 ``` service.RequestName("the.service.Name") ``` ## 临时服务 服务在运行一段时间内没有接到其他调用请求,就去自动退出。 ``` service.SetAutoQuitHanlder(1*time.Minute, func() bool { // 这个函数叫 canQuit 回调 if canQuit { // 满足条件退出 return true } // 不满足条件,不退出 return false }) // 等待退出信号 service.Wait() ``` 由于没有修改 dbus 库,所有必须在每个导出方法的实现内加上调用 Service.DelayAutoQuit 的方法,如: ``` type Exportable1 struct{ service *dbusutil.Service } func (e Exportable1) Method1() *dbus.Error { e.service.DelayAutoQuit() return nil } ``` 这样,每次有其他程序通过 dbus 调用了 Method1,就会延长本服务的存活时间。 目前的实现是 2 倍于 SetAutoQuitHandler 第一个参数的值的时间段内没有接到调用请求就会退出。 ## 自省 dbusutil 包使用了 go 语言的反射机制自动生成导出对象的 introspection xml。 ### 方法 由于反射机制不能获取方法的参数名,只能通过添加额外信息的方式提供方法的参数名,要求必须提供,否则就崩溃。 在结构体里面增加字段,名为 methods, 类型为结构体指针,具体字段立即定义,无需命名结构。 ``` type Exportable1 { methods *struct{ Method1 func() `in:"a,b" out:"result"` Method2 func() `in:"a,b"` Method3 func() `out:"result"` } } ``` 结构中每一个字段的名与导出的方法名对应,类型可为任意类型,但一般写成 func() 即函数指针,字段可以使用 in、out tag, in tag 内容为传入参数名列表,out tag 内容为返回参数名列表,参数名列表用逗号(,) 分割。 注意 in tag 和 out tag 之间要用空格分割。 如果导出方法没有输入和输出参数,则可以省略掉该字段。 ### 信号 在结构图里面增加字段,名为 signals, 类型为结构体指针,具体字段立即定义,无需命名结构。 ``` type Exportable1 struct { signals *struct{ Signal1 struct{} Signal2 struct{ name string } Signal3 struct{ name string value uint32 } } } ``` 这个匿名结构的每个字段,表示一个信号,类型必须为 struct, 这个更内层的 struct 内每个字段表示信号的参数。 为什么不用 func() 表示信号,是因为 go 的反射机制是不能获取方法的参数名,只能获取参数类型,虽然 d-feet 不能显示出信号的每个参数名是什么,但 D-Bus Introspection 规范是允许的。 ### 属性 结构体内每个大写字母开头的字段只要同时满足如下所有条件都可以成为属性。 0. 不是 PropsMaster 1. 不是前一个字段的锁字段 2. 不带 prop tag 不为 "-" 3. 不带空结构,空结构在 dbus 中是非法的。 比如: ``` type Exportable1 struct{ PropsMaster dbusutil.PropsMaster Prop1 string Prop1Mu sync.RWMutex Prop2 uint32 Prop3 struct{} Prop4 string `prop:"-"` } ``` 最后导出的属性只有 Prop1 和 Prop2。(目前还有 Prop3,但是不能用) * PropsMaster 是一个特殊的字段 * Prop1Mu 是 Prop1 的锁字段,它紧跟 Prop1 字段,并且名称是前一个字段名 Prop1 + Mu,并且类型是 sync.RWMutex。 * Prop3 的类型是空结构 * Prop4 使用了 prop tag 来明确忽略它。 属性字段可以使用 prop tag, 内容的格式是: ``` 选项1:选项值1,选项2:选项值2 ``` 如 access:rw,emit:false 支持的选项有 access 和 emit。 access 选项值可以为 r, read, w, write, rw, readwrite 之一,默认为 read。 * r 或 read 表示 只读 * w 或 write 表示 只写 * rw 或 readwrite 表示 可读可写 emit 选项值可以为 true, false, invaliates 之一,默认为 true。 * true 表示属性被修改后,发送属性改变信号时带上改变的具体值; * false 表示属性被修改后,不发送属性改变信号; * invalidates 表示属性被修改后,发送属性改变信号是不带上具体的值; #### 属性锁 org.freedestkop.DBus.Properties interface 下的 Get、GetAll 和Set 方法如果有可用的锁,那么就都会自动加锁。Get 与 GetAll 加读锁, Set 加写锁。 目前有三种锁: 全局锁 PropsMaster dbusutil.PropsMaster, 用于值类型的字段,比如 uint32,uint64, string 类型,没有局部锁或内部锁的属性都会使用全局锁。 局部锁 PropXXXMu sync.RWMutex, 用于引用类型的字段,比如 map 类型;要求局部锁字段的名为前一个字段名加 Mu,类型为 sync.RWMutex,作为前一个字段的局部锁。 内部锁, 实现了 dbusutil.Property 接口类型的字段,比如 dbusutil/gsprop 包内的各种类型, 要求 gsprop 包内部实现加锁。 ``` type Exportable1 struct { PropsMaster dbusutil.PropsMaster Prop1 uint32 Prop2 uint32 Prop3 map[string]string Prop3Mu sync.RWMutex Prop4 *gsprop.String } ``` Prop1 与 Prop2 使用 PropsMaster 加锁 Prop3 使用 Prop3Mu 加锁 Prop4 使用 gsprop.String 内部的锁,在 dbusutil 代码里就是不加锁。 #### dbusutil-gen 利用 go 语言的 generate 特性自动生成属性的 set 与 get 方法,比如操作属性 Name 的 setPropName 与 getPropName 方法,get 方法内实现了加读锁, set 方法内部实现了加写锁与发送改变信号。 先安装 dbusutil-gen 到 $GOPATH/bin 中,执行命令: ``` go install pkg.deepin.io/lib/dbusutil/_tool/dbusutil-gen ``` 在代码里写上特殊注释 ``` //go:generate dbusutil-gen -type Type1,Type2 file1.go file2.go ``` Type1,Type2 是在 dbus 上导出的类型,用逗号分割。 file1.go file2.go 是要扫描的 go 源代码文件, 其中就定义了 Type1 和 Type2。 然后进入go源码文件所在目录,执行命令 `go generate`, 将看到 dbusutil-gen 的输出信息,自动生成文件 包名 + _dbusutil.go, 如包 pkg1 生成文件名为 pkg1_dbusutil.go, 还可以用 -output 选项指定。 具体选项查看 dbusutil-gen 的帮助信息 可导出属性的字段的注释第一行可以写上 ``` // dbusutil-gen: XXXX ``` 作为 dbusutil-gen 工具的指导指令 支持的指导指令有 * ignore 忽略此字段 * ignore-below 忽略之后的所有字段 * equal=EQUAL 用于比较新旧值 EQUAL 可以为: * nil 不进行比较 * 任意,如 bytes.Equal,作为函数,比较是使用 bytes.Equal(old, new) * 以method: 开头,如 method:equal, 作为方法,比较时使用 old.equal(new) go-lib-5.6.0.9/encoding/000775 000000 000000 00000000000 13753517240 014617 5ustar00rootroot000000 000000 go-lib-5.6.0.9/encoding/kv/000775 000000 000000 00000000000 13753517240 015237 5ustar00rootroot000000 000000 go-lib-5.6.0.9/encoding/kv/reader.go000664 000000 000000 00000006405 13753517240 017035 0ustar00rootroot000000 000000 /* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // Package kv reads key value files. package kv import ( "bufio" "bytes" "errors" "io" "unicode" ) type Reader struct { // Delim is key value delimiter Delim byte // Comment, if not 0, is the comment character. Lines begin with the // Comment character are ignored. Comment byte // TrimSpace determines the behavior of trim space TrimSpace TrimSpaceFlag r *bufio.Reader } type TrimSpaceFlag uint const ( TrimLeadingSpace TrimSpaceFlag = 1 << iota TrimTailingSpace TrimDelimLeftSpace TrimDelimRightSpace ) const ( TrimAllSpace = TrimLeadingSpace | TrimTailingSpace | TrimDelimLeftSpace | TrimDelimRightSpace TrimLeadingTailingSpace = TrimLeadingSpace | TrimTailingSpace ) // NewReader returns a new Reader that reads from r. // The Delim field default to '=', the TrimSpace field default to TrimAllSpace. func NewReader(r io.Reader) *Reader { return &Reader{ Delim: '=', r: bufio.NewReader(r), TrimSpace: TrimAllSpace, } } type Pair struct { Key string Value string } // Read reads one pair from r. func (r *Reader) Read() (pair *Pair, err error) { for { pair, err = r.parseLine() if pair != nil { break } if err != nil { return nil, err } } return pair, nil } // ReadAll reads all the remaining pairs from r. // A successful call returns err == nil, not err == io.EOF. // Because ReadAll is defined to read until EOF, // it does not treat end of file as an error to be reported. func (r *Reader) ReadAll() (pairs []*Pair, err error) { for { pair, err := r.Read() if err == io.EOF { return pairs, nil } if err != nil { return nil, err } pairs = append(pairs, pair) } } var ErrBadLine = errors.New("bad line") func (r *Reader) parseLine() (*Pair, error) { line, err := r.r.ReadBytes('\n') if err != nil { return nil, err } if r.TrimSpace&TrimLeadingSpace != 0 { line = bytes.TrimLeftFunc(line, unicode.IsSpace) } if r.TrimSpace&TrimTailingSpace != 0 { line = bytes.TrimRightFunc(line, unicode.IsSpace) } // skip empty line if len(line) == 0 { return nil, nil } b1 := line[0] if r.Comment != 0 && b1 == r.Comment { // skip comment line return nil, nil } parts := bytes.SplitN(line, []byte{r.Delim}, 2) if len(parts) != 2 { return nil, ErrBadLine } key := parts[0] if r.TrimSpace&TrimDelimLeftSpace != 0 { key = bytes.TrimRightFunc(key, unicode.IsSpace) } value := parts[1] if r.TrimSpace&TrimDelimRightSpace != 0 { value = bytes.TrimLeftFunc(value, unicode.IsSpace) } return &Pair{ Key: string(key), Value: string(value), }, nil } go-lib-5.6.0.9/encoding/kv/reader_test.go000664 000000 000000 00000004447 13753517240 020100 0ustar00rootroot000000 000000 /* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package kv import ( . "github.com/smartystreets/goconvey/convey" "io" "os" "testing" ) func TestReader(t *testing.T) { Convey("Test Reader", t, func(c C) { f, err := os.Open("./testdata/a") c.So(err, ShouldBeNil) c.So(f, ShouldNotBeNil) defer f.Close() r := NewReader(f) r.Delim = ':' r.TrimSpace = TrimDelimRightSpace | TrimTailingSpace c.Convey("Get Pid", func(c C) { var resultPair *Pair for { pair, err := r.Read() if err != nil { break } if pair.Key == "Pid" { resultPair = pair break } } c.So(resultPair, ShouldNotBeNil) c.So(resultPair.Value, ShouldEqual, "21722") }) c.Convey("ReadAll", func(c C) { pairs, err := r.ReadAll() c.So(err, ShouldBeNil) c.So(len(pairs), ShouldEqual, 48) }) }) Convey("Test ReadAll error", t, func(c C) { f, err := os.Open("./testdata/b") c.So(err, ShouldBeNil) c.So(f, ShouldNotBeNil) defer f.Close() r := NewReader(f) pairs, err := r.ReadAll() c.So(err, ShouldEqual, ErrBadLine) c.So(pairs, ShouldBeNil) }) Convey("Test Read shell vars", t, func(c C) { f, err := os.Open("./testdata/c") c.So(err, ShouldBeNil) c.So(f, ShouldNotBeNil) defer f.Close() r := NewReader(f) r.TrimSpace = TrimLeadingTailingSpace r.Comment = '#' pair, err := r.Read() c.So(err, ShouldBeNil) c.So(pair, ShouldResemble, &Pair{"LANG", "zh_CN.UTF-8"}) pair, err = r.Read() c.So(err, ShouldBeNil) c.So(pair, ShouldResemble, &Pair{"LANGUAGE", "zh_CN"}) pair, err = r.Read() c.So(pair, ShouldBeNil) c.So(err, ShouldEqual, io.EOF) }) } go-lib-5.6.0.9/encoding/kv/testdata/000775 000000 000000 00000000000 13753517240 017050 5ustar00rootroot000000 000000 go-lib-5.6.0.9/encoding/kv/testdata/a000664 000000 000000 00000002040 13753517240 017207 0ustar00rootroot000000 000000 Name: cat State: R (running) Tgid: 21722 Ngid: 0 Pid: 21722 PPid: 20960 TracerPid: 0 Uid: 1000 1000 1000 1000 Gid: 1000 1000 1000 1000 FDSize: 64 Groups: 4 7 27 100 107 111 120 130 134 999 1000 NStgid: 21722 NSpid: 21722 NSpgid: 21722 NSsid: 20960 VmPeak: 8048 kB VmSize: 8048 kB VmLck: 0 kB VmPin: 0 kB VmHWM: 788 kB VmRSS: 788 kB VmData: 324 kB VmStk: 136 kB VmExe: 48 kB VmLib: 1772 kB VmPTE: 40 kB VmPMD: 12 kB VmSwap: 0 kB HugetlbPages: 0 kB Threads: 1 SigQ: 0/30759 SigPnd: 0000000000000000 ShdPnd: 0000000000000000 SigBlk: 0000000000000000 SigIgn: 0000000000000000 SigCgt: 0000000000000000 CapInh: 0000000000000000 CapPrm: 0000000000000000 CapEff: 0000000000000000 CapBnd: 0000003fffffffff CapAmb: 0000000000000000 Seccomp: 0 Cpus_allowed: ff Cpus_allowed_list: 0-7 Mems_allowed: 00000000,00000001 Mems_allowed_list: 0 voluntary_ctxt_switches: 0 nonvoluntary_ctxt_switches: 1 go-lib-5.6.0.9/encoding/kv/testdata/b000664 000000 000000 00000000042 13753517240 017210 0ustar00rootroot000000 000000 LANG=zh_CN.UTF-8 LANGUAGE=zh_CN X go-lib-5.6.0.9/encoding/kv/testdata/c000664 000000 000000 00000000065 13753517240 017216 0ustar00rootroot000000 000000 # comment # comment LANG=zh_CN.UTF-8 LANGUAGE=zh_CN go-lib-5.6.0.9/event/000775 000000 000000 00000000000 13753517240 014152 5ustar00rootroot000000 000000 go-lib-5.6.0.9/event/event.go000664 000000 000000 00000006242 13753517240 015626 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ // fork from https://github.com/pocke/goevent package event import ( "errors" "fmt" "reflect" "sync" ) type Event struct { listeners []reflect.Value lmu sync.RWMutex argTypes []reflect.Type } // New func New(f interface{}) *Event { fn := reflect.ValueOf(f) if fn.Kind() != reflect.Func { panic("not a function") } fnType := fn.Type() fnNum := fnType.NumIn() argTypes := make([]reflect.Type, fnNum) for i := 0; i < fnNum; i++ { argTypes[i] = fnType.In(i) } return &Event{ argTypes: argTypes, } } // On func (e *Event) On(f interface{}) error { fn, err := e.checkFuncSignature(f) if err != nil { return err } e.lmu.Lock() e.listeners = append(e.listeners, *fn) e.lmu.Unlock() return nil } // Off func (e *Event) Off(f interface{}) error { fn := reflect.ValueOf(f) e.lmu.Lock() l := len(e.listeners) m := l // for error check for i := 0; i < l; i++ { if fn == e.listeners[i] { // XXX: GC Ref: http://jxck.hatenablog.com/entry/golang-slice-internals e.listeners = append(e.listeners[:i], e.listeners[i+1:]...) l-- i-- } } e.lmu.Unlock() if l == m { return fmt.Errorf("Listener does't exists") } return nil } // Trigger func (e *Event) Trigger(args ...interface{}) error { // check args len if len(e.argTypes) != len(args) { return fmt.Errorf("argument length expected %d, but got %d", len(e.argTypes), len(args)) } // check each arg type for i, t := range e.argTypes { t0 := reflect.TypeOf(args[i]) if t != t0 { return fmt.Errorf("args[%d] type expected %s, but got %s", i, t, t0) } } arguments := make([]reflect.Value, len(args)) for i, v := range args { arguments[i] = reflect.ValueOf(v) } e.lmu.RLock() defer e.lmu.RUnlock() wg := sync.WaitGroup{} wg.Add(len(e.listeners)) for _, fn := range e.listeners { go func(f reflect.Value) { defer wg.Done() f.Call(arguments) }(fn) } wg.Wait() return nil } func (e *Event) checkFuncSignature(f interface{}) (*reflect.Value, error) { fn := reflect.ValueOf(f) if fn.Kind() != reflect.Func { return nil, errors.New("not a function") } fnType := fn.Type() fnNum := fnType.NumIn() // check args len if len(e.argTypes) != fnNum { return nil, fmt.Errorf("argument length expected %d, but got %d", len(e.argTypes), fnNum) } // check each arg type for i, t := range e.argTypes { t0 := fnType.In(i) if t != t0 { return nil, fmt.Errorf("args[%d] type expected %s, but got %s", i, t, t0) } } return &fn, nil } go-lib-5.6.0.9/gdkpixbuf/000775 000000 000000 00000000000 13753517240 015014 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gdkpixbuf/README.md000664 000000 000000 00000000770 13753517240 016277 0ustar00rootroot000000 000000 Go 图形处理库, 主要围绕 GdkPixbuf 库进行增强开发. 支持对图片进行 剪切, 翻转, 缩放, 混合, 模糊处理等操作. API 的命名风格与 pkg.deepin.io/lib/graphic 库相同, 以 Blur 操作为例: - **Blur** 对 C.GdkPixbuf 对象进行模糊处理 - **BlurImage** 对目标文件进行模糊处理 - **BlurImageCache** 对目标文件进行模糊处理, 同时将处理后的文件放到缓 存目录, 下次对同一文件进行相同操作时可以大大提高速度 go-lib-5.6.0.9/gdkpixbuf/blur.c000664 000000 000000 00000002440 13753517240 016124 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include "gaussianiir2d.h" int blur(GdkPixbuf *pixbuf, double sigma, double numsteps) { int width = gdk_pixbuf_get_width(pixbuf); int height = gdk_pixbuf_get_height(pixbuf); int rowstride = gdk_pixbuf_get_rowstride(pixbuf); int n_channels = gdk_pixbuf_get_n_channels(pixbuf); guchar *image_data = gdk_pixbuf_get_pixels(pixbuf); gaussianiir2d_pixbuf_c(image_data, width, height, rowstride, n_channels, sigma, numsteps); return TRUE; } go-lib-5.6.0.9/gdkpixbuf/blur.go000664 000000 000000 00000004124 13753517240 016310 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gdkpixbuf // #cgo pkg-config: gdk-pixbuf-2.0 // #cgo LDFLAGS: -lm // #include // #include "blur.h" import "C" import ( "fmt" "pkg.deepin.io/lib/utils" ) // BlurImage generate blur effect to an image file. func BlurImage(srcFile, dstFile string, sigma, numSteps float64, f Format) (err error) { srcPixbuf, err := NewPixbufFromFile(srcFile) defer FreePixbuf(srcPixbuf) if err != nil { return } err = Blur(srcPixbuf, sigma, numSteps) if err != nil { return } err = Save(srcPixbuf, dstFile, f) return } // BlurImageCache generate and save the blurred image file to cache // directory, if target file already exists, just return it. func BlurImageCache(srcFile string, sigma, numSteps float64, f Format) (dstFile string, useCache bool, err error) { dstFile = generateCacheFilePath(fmt.Sprintf("BlurImageCache%s%f%f%s", srcFile, sigma, numSteps, f)) if utils.IsFileExist(dstFile) { // return cache file useCache = true return } err = BlurImage(srcFile, dstFile, sigma, numSteps, f) return } // Blur generate blur effect to pixbuf object. func Blur(pixbuf *C.GdkPixbuf, sigma, numSteps float64) (err error) { defaultError := fmt.Errorf("blur gdkpixbuf failed, pixbuf=%v, sigma=%v, numSteps=%v", pixbuf, sigma, numSteps) ret := C.blur(pixbuf, C.double(sigma), C.double(numSteps)) if ret == 0 { err = defaultError return } return } go-lib-5.6.0.9/gdkpixbuf/blur.h000664 000000 000000 00000001613 13753517240 016132 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _BLUR_H #define _BLUR_H 1 #include int blur(GdkPixbuf *src_pixbuf, double sigma, double numsteps); #endif /* _BLUR_H */ go-lib-5.6.0.9/gdkpixbuf/constants.go000664 000000 000000 00000005611 13753517240 017362 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gdkpixbuf type GdkInterpType uint const ( GDK_INTERP_NEAREST GdkInterpType = iota GDK_INTERP_TILES GDK_INTERP_BILINEAR GDK_INTERP_HYPER ) type GdkPixbufRotation uint const ( GDK_PIXBUF_ROTATE_NONE GdkPixbufRotation = 0 GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE GdkPixbufRotation = 90 GDK_PIXBUF_ROTATE_UPSIDEDOWN GdkPixbufRotation = 180 GDK_PIXBUF_ROTATE_CLOCKWISE GdkPixbufRotation = 270 ) type GdkPixbufAlphaMode uint const ( GDK_PIXBUF_ALPHA_BILEVEL GdkPixbufAlphaMode = iota GDK_PIXBUF_ALPHA_FULL ) type GdkColorspace uint const ( GDK_COLORSPACE_RGB GdkColorspace = iota ) type GdkPixbufError uint const ( /* image data hosed */ GDK_PIXBUF_ERROR_CORRUPT_IMAGE GdkPixbufError = iota /* no mem to load image */ GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY /* bad option passed to save routine */ GDK_PIXBUF_ERROR_BAD_OPTION /* unsupported image type (sort of an ENOSYS) */ GDK_PIXBUF_ERROR_UNKNOWN_TYPE /* unsupported operation (load, save) for image type */ GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION GDK_PIXBUF_ERROR_FAILED ) type GdkPixdataType uint const ( /* colorspace + alpha */ GDK_PIXDATA_COLOR_TYPE_RGB GdkPixdataType = 0x01 GDK_PIXDATA_COLOR_TYPE_RGBA GdkPixdataType = 0x02 GDK_PIXDATA_COLOR_TYPE_MASK GdkPixdataType = 0xff /* width, support 8bits only currently */ GDK_PIXDATA_SAMPLE_WIDTH_8 GdkPixdataType = 0x01 << 16 GDK_PIXDATA_SAMPLE_WIDTH_MASK GdkPixdataType = 0x0f << 16 /* encoding */ GDK_PIXDATA_ENCODING_RAW GdkPixdataType = 0x01 << 24 GDK_PIXDATA_ENCODING_RLE GdkPixdataType = 0x02 << 24 GDK_PIXDATA_ENCODING_MASK GdkPixdataType = 0x0f << 24 ) type GdkPixdataDumpType uint const ( /* type of source to save */ GDK_PIXDATA_DUMP_PIXDATA_STREAM GdkPixdataDumpType = 0 GDK_PIXDATA_DUMP_PIXDATA_STRUCT GdkPixdataDumpType = 1 GDK_PIXDATA_DUMP_MACROS GdkPixdataDumpType = 2 /* type of variables to use */ GDK_PIXDATA_DUMP_GTYPES GdkPixdataDumpType = 0 GDK_PIXDATA_DUMP_CTYPES GdkPixdataDumpType = 1 << 8 GDK_PIXDATA_DUMP_STATIC GdkPixdataDumpType = 1 << 9 GDK_PIXDATA_DUMP_CONST GdkPixdataDumpType = 1 << 10 /* save RLE decoder macro? */ GDK_PIXDATA_DUMP_RLE_DECODER GdkPixdataDumpType = 1 << 16 ) go-lib-5.6.0.9/gdkpixbuf/gaussianiir2d.c000664 000000 000000 00000014673 13753517240 017737 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "gaussianiir2d.h" /** * Fast 2D Gaussian convolution IIR approximation * @image the image data, modified in-place * @width, height image dimensions * @sigma the standard deviation of the Gaussian in pixels * @numsteps number of timesteps, more steps implies better accuracy * * Implements the fast Gaussian convolution algorithm of Alvarez and Mazorra, * where the Gaussian is approximated by a cascade of first-order infinite * impulsive response (IIR) filters. Boundaries are handled with half-sample * symmetric extension. * * Gaussian convolution is approached as approximating the heat equation and * each timestep is performed with an efficient recursive computation. Using * more steps yields a more accurate approximation of the Gaussian. A * reasonable default value for \c numsteps is 4. * * The data is assumed to be ordered such that * image[x + width*y] = pixel value at (x,y). * * Reference: * Alvarez, Mazorra, "Signal and Image Restoration using Shock Filters and * Anisotropic Diffusion," SIAM J. on Numerical Analysis, vol. 31, no. 2, * pp. 590-605, 1994. */ void gaussianiir2d_f (double *image, long width, long height, double sigma, long numsteps) { const long numpixels = width*height; double lambda, dnu; double nu, boundaryscale, postscale; double *ptr; long i, x, y; long step; if(sigma <= 0 || numsteps < 0) return; lambda = (sigma * sigma)/(2.0 * numsteps); dnu = (1.0 + 2.0 * lambda - sqrt (1.0 + 4.0 * lambda)) / (2.0 * lambda); nu = (double)dnu; boundaryscale = (double)(1.0 / (1.0 - dnu)); postscale = (double)(pow (dnu / lambda, 2 * numsteps)); /* Filter horizontally along each row */ for(y = 0; y < height; y++) { for(step = 0; step < numsteps; step++) { ptr = image + width*y; ptr[0] *= boundaryscale; /* Filter rightwards */ for(x = 1; x < width; x++) ptr[x] += nu * ptr[x - 1]; ptr[x = width - 1] *= boundaryscale; /* Filter leftwards */ for(; x > 0; x--) ptr[x - 1] += nu * ptr[x]; } } /* Filter vertically along each column */ for(x = 0; x < width; x++) { for(step = 0; step < numsteps; step++) { ptr = image + x; ptr[0] *= boundaryscale; /* Filter downwards */ for(i = width; i < numpixels; i += width) ptr[i] += nu * ptr[i - width]; ptr[i = numpixels - width] *= boundaryscale; /* Filter upwards */ for(; i > 0; i -= width) ptr[i - width] += nu*ptr[i]; } } for(i = 0; i < numpixels; i++) image[i] *= postscale; return; } void gaussianiir2d_pixbuf_c(unsigned char* image_data, int width, int height, int rowstride, int n_channels, double sigma, double numsteps) { //1. unsigned char* ----> float* double* _image_f_red = g_new0 (double, width * height); double* _image_f_green = g_new0 (double, width * height); double* _image_f_blue = g_new0 (double, width * height); int i = 0; int j = 0; for (i = 0; i < width; i++) { for (j = 0; j < height; j++) { _image_f_red[i + width * j] = (double) (image_data[j*rowstride +i*n_channels + 0]); _image_f_green[i + width * j] = (double) (image_data[j*rowstride +i*n_channels + 1]); _image_f_blue[i + width * j] = (double) (image_data[j*rowstride +i*n_channels + 2]); } } //2. gaussianiir2d_f(_image_f_red, width, height, sigma, numsteps); gaussianiir2d_f(_image_f_green, width, height, sigma, numsteps); gaussianiir2d_f(_image_f_blue, width, height, sigma, numsteps); //test: dump data //3. float* ----> unsigned char* i = 0; j = 0; for (i = 0; i < width; i++) { for (j = 0; j < height; j++) { image_data[j*rowstride +i*n_channels + 0] = _image_f_red[i+width*j]; image_data[j*rowstride +i*n_channels + 1] = _image_f_green[i+width*j]; image_data[j*rowstride +i*n_channels + 2] = _image_f_blue[i+width*j]; } } g_free (_image_f_red); g_free (_image_f_green); g_free (_image_f_blue); } #if 0 void gaussianiir2d_c(unsigned char* image_c, long width, long height, double sigma, long numsteps) { guint32* _image_i = (guint32*)image_c; //1. unsigned char* ----> float* double* _image_f_red = g_new0 (double, width * height); double* _image_f_green = g_new0 (double, width * height); double* _image_f_blue = g_new0 (double, width * height); int i = 0; int j = 0; for (i = 0; i < width; i++) { for (j = 0; j < height; j++) { _image_f_red[i + width * j] = (double) ((_image_i[i + width * j]&0x00ff0000)>>16); _image_f_green[i + width * j] = (double) ((_image_i[i + width * j]&0x0000ff00)>>8); _image_f_blue[i + width * j] = (double) (_image_i[i + width * j]&0x000000ff); } } //2. gaussianiir2d_f(_image_f_red, width, height, sigma, numsteps); gaussianiir2d_f(_image_f_green, width, height, sigma, numsteps); gaussianiir2d_f(_image_f_blue, width, height, sigma, numsteps); //test: dump data //3. float* ----> unsigned char* i = 0; j = 0; guint32 sum; for (i = 0; i < width; i++) { for (j = 0; j < height; j++) { #define CLAMP_COLOR(x) (guint32)((x)>255 ? 255 : (x)>=0 ? x : 0) sum = 0; sum += (CLAMP_COLOR(_image_f_red[i + width * j]) << 16); sum += (CLAMP_COLOR(_image_f_green[i + width * j]) << 8); sum += (CLAMP_COLOR(_image_f_blue[i + width * j])); _image_i[i + width * j] = sum ; } } g_free (_image_f_red); g_free (_image_f_green); g_free (_image_f_blue); } #endif go-lib-5.6.0.9/gdkpixbuf/gaussianiir2d.h000664 000000 000000 00000002610 13753517240 017730 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _GAUSSIANIIR2D_H_ #define _GAUSSIANIIR2D_H_ #include void gaussianiir2d_f(double* image_f, long width, long height, double sigma, long numsteps); /* * image data format * * 1. _pixbuf_c: use GdkPixbuf format. * p = pixels + y * rowstride + x* n_channels * * 2. gaussianiir2d_c: use cairo image data */ void gaussianiir2d_pixbuf_c(unsigned char* image_data, int width, int height, int rowstride, int n_channels, double sigma, double numsteps); #if 0 void gaussianiir2d_c(unsigned char* image_c, long width, long height, double sigma, long numsteps); #endif #endif /* _GAUSSIANIIR2D_H_ */ go-lib-5.6.0.9/gdkpixbuf/gdk_pixbuf_utils.c000664 000000 000000 00000011723 13753517240 020526 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include #include #include "gdk_pixbuf_utils.h" int init_gdk_xlib() { XInitThreads(); /* should be called before gdk_init() */ if (!init_gdk()) { return FALSE; } gdk_pixbuf_xlib_init(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), 0); return TRUE; } int init_gdk() { return gdk_init_check(NULL, NULL); } const char *get_image_format(const char *img_file) { GdkPixbufFormat *format = gdk_pixbuf_get_file_info(img_file, NULL, NULL); if (format) { return (char *)gdk_pixbuf_format_get_name(format); } return NULL; } int get_image_size(const char *img_file, int *width, int *height) { GdkPixbufFormat *format = gdk_pixbuf_get_file_info(img_file, width, height); if (format) { return TRUE; } return FALSE; } int get_dominant_color(const GdkPixbuf *pixbuf, double *r, double *g, double *b) { if (pixbuf == NULL) { g_warning("pixbuf is NULL\n"); return FALSE; } guint length = 0; guchar *pixels = gdk_pixbuf_get_pixels_with_length(pixbuf, &length); if (length == 0) { g_warning("zero length of pixbuf\n"); return FALSE; } // calculate dominant color of pixbuf long long sum_r = 0; long long sum_g = 0; long long sum_b = 0; long count = 0; int skip = gdk_pixbuf_get_n_channels(pixbuf); guint i = 0; for (i=0; imessage); g_error_free(err); return FALSE; } return TRUE; } GdkPixbuf *new_pixbuf_from_file(const char *img_file) { GError *err = NULL; GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(img_file, &err); if (err) { g_debug("new gdk pixbuf from file failed: %s", err->message); g_error_free(err); return NULL; } return pixbuf; } Pixmap convert_pixbuf_to_xpixmap(GdkPixbuf *pixbuf) { Pixmap xpixmap = 0; gdk_pixbuf_xlib_render_pixmap_and_mask(pixbuf, &xpixmap, NULL, 0); return xpixmap; } GdkPixbuf *convert_xpixmap_to_pixbuf(const Pixmap xpixmap, int width, int height) { return gdk_pixbuf_xlib_get_from_drawable(NULL, (Drawable)xpixmap, xlib_rgb_get_cmap(), xlib_rgb_get_visual(), 0, 0, 0, 0, width, height); } GdkPixbuf *copy_area_simple(const GdkPixbuf *src_pixbuf, int src_x, int src_y, int width, int height) { GdkPixbuf *dest_pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, gdk_pixbuf_get_has_alpha(src_pixbuf), 8, width, height); gdk_pixbuf_copy_area(src_pixbuf, src_x, src_y, width, height, dest_pixbuf, 0, 0); return dest_pixbuf; } GdkPixbuf *screenshot() { GdkWindow *root; GdkPixbuf *pixbuf; root = gdk_get_default_root_window(); int width = gdk_window_get_width(root); int height = gdk_window_get_height(root); pixbuf = gdk_pixbuf_get_from_window(root, 0, 0, width, height); return pixbuf; } go-lib-5.6.0.9/gdkpixbuf/gdk_pixbuf_utils.h000664 000000 000000 00000003017 13753517240 020530 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #ifndef _GDK_PIXBUF_UTILS_H #define _GDK_PIXBUF_UTILS_H 1 #include #include #include int init_gdk_xlib(); int init_gdk(); const char *get_image_format(const char *img_file); int get_image_size(const char *img_file, int *width, int *height); int get_dominant_color(const GdkPixbuf *pixbuf, double *r, double *g, double *b); int save(GdkPixbuf *pixbuf, const char *dest_file, const char *format); GdkPixbuf *new_pixbuf_from_file(const char *img_file); Pixmap convert_pixbuf_to_xpixmap(GdkPixbuf *pixbuf); GdkPixbuf *convert_xpixmap_to_pixbuf(const Pixmap xpixmap, int width, int height); GdkPixbuf *copy_area_simple(const GdkPixbuf *src_pixbuf, int src_x, int src_y, int width, int height); GdkPixbuf *screenshot(); #endif /* _GDK_PIXBUF_UTILS_H */ go-lib-5.6.0.9/gdkpixbuf/gdkpixbuf.go000664 000000 000000 00000034073 13753517240 017335 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gdkpixbuf // #cgo pkg-config: gdk-3.0 gdk-pixbuf-xlib-2.0 gdk-x11-3.0 x11 // #cgo LDFLAGS: -lm // #include // #include "gdk_pixbuf_utils.h" import "C" import ( "errors" "fmt" "image" "unsafe" x "github.com/linuxdeepin/go-x11-client" "pkg.deepin.io/lib/utils" ) // Format defines the type of image format. type Format string // Registered image format. const ( FormatPng Format = "png" FormatJpeg Format = "jpeg" FormatBmp Format = "bmp" FormatIco Format = "ico" FormatTiff Format = "tiff" // TODO // FormatGif Format = "gif" // FormatXpm Format = "xpm" ) // InitGdkXlib initialize gdk and xlib, should not be used with InitGdk(). func InitGdkXlib() (err error) { ret := C.init_gdk_xlib() if ret == 0 { err = fmt.Errorf("initialize gdk xlib failed %v", ret) } return } // InitGdk initialize gdk. func InitGdk() (err error) { ret := C.init_gdk() if ret == 0 { err = fmt.Errorf("initialize gdk failed %v", ret) } return } func FreePixbuf(pixbuf *C.GdkPixbuf) { if pixbuf != nil { C.g_object_unref(C.gpointer(pixbuf)) } } // Save and Load func Save(pixbuf *C.GdkPixbuf, destFile string, f Format) (err error) { defaultError := fmt.Errorf("save image to xpixmap failed, %s", destFile) cDestFile := C.CString(destFile) defer C.free(unsafe.Pointer(cDestFile)) cFormat := C.CString(string(f)) defer C.free(unsafe.Pointer(cFormat)) ret := C.save(pixbuf, cDestFile, cFormat) if ret == 0 { err = defaultError return } return } func NewPixbufFromFile(imgFile string) (pixbuf *C.GdkPixbuf, err error) { defaultError := fmt.Errorf("render image to xpixmap failed, %s", imgFile) cImgFile := C.CString(imgFile) defer C.free(unsafe.Pointer(cImgFile)) // new gdk pixbuf from file pixbuf = C.new_pixbuf_from_file(cImgFile) if pixbuf == nil { err = defaultError return } return } func GetPixels(pixbuf *C.GdkPixbuf) []byte { var cLength C.guint ptr := C.gdk_pixbuf_get_pixels_with_length(pixbuf, &cLength) return C.GoBytes(unsafe.Pointer(ptr), C.int(cLength)) } func ToImage(pixbuf *C.GdkPixbuf) (image.Image, error) { width, height, err := GetSize(pixbuf) if err != nil { return nil, err } colorspace := C.gdk_pixbuf_get_colorspace(pixbuf) if colorspace != C.GDK_COLORSPACE_RGB { return nil, errors.New("colorspace is not RGB") } nChannels := C.gdk_pixbuf_get_n_channels(pixbuf) if nChannels != 4 { return nil, errors.New("n channels != 4") } bitsPerSample := C.gdk_pixbuf_get_bits_per_sample(pixbuf) if bitsPerSample != 8 { return nil, errors.New("bits per sample != 8") } stride := C.gdk_pixbuf_get_rowstride(pixbuf) pixels := GetPixels(pixbuf) img := &image.RGBA{ Pix: pixels, Stride: int(stride), Rect: image.Rect(0, 0, width, height), } return img, nil } // Info // GetImageSize return image file's width and height. func GetImageSize(imgFile string) (w, h int, err error) { defaultError := fmt.Errorf("get image size failed, %s", imgFile) cImgFile := C.CString(imgFile) defer C.free(unsafe.Pointer(cImgFile)) w = 0 h = 0 ret := C.get_image_size(cImgFile, (*C.int)(unsafe.Pointer(&w)), (*C.int)(unsafe.Pointer(&h))) if ret == 0 { err = defaultError return } return } // GetSize return pixbuf's width and height. func GetSize(pixbuf *C.GdkPixbuf) (w, h int, err error) { defaultError := fmt.Errorf("get GdkPixbuf size failed, %v", pixbuf) if pixbuf == nil { err = defaultError return } w = int(C.gdk_pixbuf_get_width(pixbuf)) h = int(C.gdk_pixbuf_get_height(pixbuf)) return } // GetImageFormat return image file's format, such as "png", "jpeg". func GetImageFormat(imgFile string) (f Format, err error) { defaultError := fmt.Errorf("get image format failed, %s", imgFile) cImgFile := C.CString(imgFile) defer C.free(unsafe.Pointer(cImgFile)) f = Format(C.GoString(C.get_image_format(cImgFile))) if len(f) == 0 { err = defaultError return } return } // IsSupportedImage check if image file is supported. func IsSupportedImage(imgFile string) bool { _, err := GetImageFormat(imgFile) return err == nil } // Clip func ClipImage(srcFile, destFile string, srcX, srcY, width, height int, f Format) (err error) { srcPixbuf, err := NewPixbufFromFile(srcFile) defer FreePixbuf(srcPixbuf) if err != nil { return } destPixbuf, err := CopyAreaSimple(srcPixbuf, srcX, srcY, width, height) defer FreePixbuf(destPixbuf) if err != nil { return } err = Save(destPixbuf, destFile, f) return } func CopyArea(srcPixbuf, destPixbuf *C.GdkPixbuf, srcX, srcY, width, height, destX, destY int) (err error) { defaultError := fmt.Errorf("copy pixbuf area failed, %v, %v", srcPixbuf, destPixbuf) if srcPixbuf == nil || destPixbuf == nil { err = defaultError return } C.gdk_pixbuf_copy_area(srcPixbuf, C.int(srcX), C.int(srcY), C.int(width), C.int(height), destPixbuf, C.int(destX), C.int(destY)) return } func CopyAreaSimple(srcPixbuf *C.GdkPixbuf, srcX, srcY, width, height int) (destPixbuf *C.GdkPixbuf, err error) { defaultError := fmt.Errorf("copy pixbuf area simple failed, %v", srcPixbuf) if srcPixbuf == nil { err = defaultError return } destPixbuf = C.copy_area_simple(srcPixbuf, C.int(srcX), C.int(srcY), C.int(width), C.int(height)) if destPixbuf == nil { err = defaultError return } return } // Dominant color // GetDominantColorOfImage return the dominant hsv color of an image. func GetDominantColorOfImage(imgFile string) (h, s, v float64, err error) { pixbuf, err := NewPixbufFromFile(imgFile) defer FreePixbuf(pixbuf) if err != nil { return } return GetDominantColor(pixbuf) } func GetDominantColor(pixbuf *C.GdkPixbuf) (h, s, v float64, err error) { defaultError := fmt.Errorf("get dominant color of pixbuf failed, %v", pixbuf) var r, g, b float64 ret := C.get_dominant_color(pixbuf, (*C.double)(&r), (*C.double)(&g), (*C.double)(&b)) if ret == 0 { err = defaultError return } h, s, v = Rgb2Hsv(uint8(r), uint8(g), uint8(b)) return } // Convert func ConvertImage(srcFile, destFile string, f Format) (err error) { srcPixbuf, err := NewPixbufFromFile(srcFile) defer FreePixbuf(srcPixbuf) if err != nil { return } err = Save(srcPixbuf, destFile, f) return } // Flip func FlipImageHorizontal(srcFile, destFile string, f Format) (err error) { return doFlipImage(srcFile, destFile, true, f) } func FlipImageVertical(srcFile, destFile string, f Format) (err error) { return doFlipImage(srcFile, destFile, false, f) } func doFlipImage(srcFile, destFile string, horizontal bool, f Format) (err error) { srcPixbuf, err := NewPixbufFromFile(srcFile) defer FreePixbuf(srcPixbuf) if err != nil { return } destPixbuf, err := Flip(srcPixbuf, horizontal) defer FreePixbuf(destPixbuf) if err != nil { return } err = Save(destPixbuf, destFile, f) return } func Flip(srcPixbuf *C.GdkPixbuf, horizontal bool) (destPixbuf *C.GdkPixbuf, err error) { defaultError := fmt.Errorf("flip pixbuf failed, %v, %v", srcPixbuf, horizontal) if horizontal { destPixbuf = C.gdk_pixbuf_flip(srcPixbuf, C.TRUE) } else { destPixbuf = C.gdk_pixbuf_flip(srcPixbuf, C.FALSE) } if destPixbuf == nil { err = defaultError return } return } // Scale and Thumbnail // ScaleImage returns a new image file with the given width and // height created by resizing the given image. func ScaleImage(srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format) (err error) { srcPixbuf, err := NewPixbufFromFile(srcFile) defer FreePixbuf(srcPixbuf) if err != nil { return } destPixbuf, err := ScaleSimple(srcPixbuf, newWidth, newHeght, interpType) defer FreePixbuf(destPixbuf) if err != nil { return } err = Save(destPixbuf, destFile, f) return } // ScaleImagePrefer resize image file to new width and heigh, and // maintain the original proportions unchanged. func ScaleImagePrefer(srcFile, destFile string, newWidth, newHeght int, interpType GdkInterpType, f Format) (err error) { srcPixbuf, err := NewPixbufFromFile(srcFile) defer FreePixbuf(srcPixbuf) if err != nil { return } destPixbuf, err := ScalePrefer(srcPixbuf, newWidth, newHeght, interpType) defer FreePixbuf(destPixbuf) if err != nil { return } err = Save(destPixbuf, destFile, f) return } // ThumbnailImage resize target image file with limited maximum width and height. func ThumbnailImage(srcFile, destFile string, maxWidth, maxHeight int, interpType GdkInterpType, f Format) (err error) { srcPixbuf, err := NewPixbufFromFile(srcFile) defer FreePixbuf(srcPixbuf) if err != nil { return } destPixbuf, err := Thumbnail(srcPixbuf, maxWidth, maxHeight, interpType) defer FreePixbuf(destPixbuf) if err != nil { return } err = Save(destPixbuf, destFile, f) return } func ScaleImageCache(srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format) (destFile string, useCache bool, err error) { destFile = generateCacheFilePath(fmt.Sprintf("ScaleImageCache%s%d%d%d%s", srcFile, newWidth, newHeght, interpType, f)) if utils.IsFileExist(destFile) { // return cache file useCache = true return } err = ScaleImage(srcFile, destFile, newWidth, newHeght, interpType, f) return } func ScaleImagePreferCache(srcFile string, newWidth, newHeght int, interpType GdkInterpType, f Format) (destFile string, useCache bool, err error) { destFile = generateCacheFilePath(fmt.Sprintf("ScaleImageCache%s%d%d%d%s", srcFile, newWidth, newHeght, interpType, f)) if utils.IsFileExist(destFile) { // return cache file useCache = true return } err = ScaleImagePrefer(srcFile, destFile, newWidth, newHeght, interpType, f) return } func ScaleSimple(srcPixbuf *C.GdkPixbuf, newWidth, newHeght int, interpType GdkInterpType) (destPixbuf *C.GdkPixbuf, err error) { defaultError := fmt.Errorf("scale pixbuf failed, %v, %v, %v, %v", srcPixbuf, newWidth, newHeght, interpType) destPixbuf = C.gdk_pixbuf_scale_simple(srcPixbuf, C.int(newWidth), C.int(newHeght), C.GdkInterpType(interpType)) if destPixbuf == nil { err = defaultError return } return } // ScalePrefer resize pixbuf to new width and heigh, and maintain the // original proportions unchanged. func ScalePrefer(srcPixbuf *C.GdkPixbuf, newWidth, newHeight int, interpType GdkInterpType) (destPixbuf *C.GdkPixbuf, err error) { iw, ih, err := GetSize(srcPixbuf) if err != nil { return } x, y, w, h, err := GetPreferScaleClipRect(newWidth, newHeight, iw, ih) if err != nil { return } clipPixbuf, err := CopyAreaSimple(srcPixbuf, x, y, w, h) defer FreePixbuf(clipPixbuf) if err != nil { return } destPixbuf, err = ScaleSimple(clipPixbuf, newWidth, newHeight, interpType) return } // Thumbnail resize pixbuf with limited maximum width and height. func Thumbnail(srcPixbuf *C.GdkPixbuf, maxWidth, maxHeight int, interpType GdkInterpType) (destPixbuf *C.GdkPixbuf, err error) { // get new width and heigh var newWidth, newHeight int w, h, err := GetSize(srcPixbuf) if err != nil { return } scale := float32(w) / float32(h) newWidth = maxWidth newHeight = int(float32(newWidth) / scale) if newHeight > maxHeight { newHeight = maxHeight newWidth = int(float32(newHeight) * scale) } return ScaleSimple(srcPixbuf, newWidth, newHeight, interpType) } // Rotate func RotateImageLeft(srcFile, destFile string, f Format) (err error) { err = doRotateImage(srcFile, destFile, GDK_PIXBUF_ROTATE_COUNTERCLOCKWISE, f) return } func RotateImageRight(srcFile, destFile string, f Format) (err error) { err = doRotateImage(srcFile, destFile, GDK_PIXBUF_ROTATE_CLOCKWISE, f) return } func RotateImageUpsizedown(srcFile, destFile string, f Format) (err error) { err = doRotateImage(srcFile, destFile, GDK_PIXBUF_ROTATE_UPSIDEDOWN, f) return } func doRotateImage(srcFile, destFile string, angle GdkPixbufRotation, f Format) (err error) { srcPixbuf, err := NewPixbufFromFile(srcFile) defer FreePixbuf(srcPixbuf) if err != nil { return } destPixbuf, err := RotateSimple(srcPixbuf, angle) defer FreePixbuf(destPixbuf) if err != nil { return } err = Save(destPixbuf, destFile, f) return } func RotateSimple(srcPixbuf *C.GdkPixbuf, angle GdkPixbufRotation) (destPixbuf *C.GdkPixbuf, err error) { defaultError := fmt.Errorf("rotate pixbuf failed, %v, %v", srcPixbuf, angle) destPixbuf = C.gdk_pixbuf_rotate_simple(srcPixbuf, C.GdkPixbufRotation(angle)) if destPixbuf == nil { err = defaultError return } return } // XLib // ConvertImageToXpixmap convert image file to x pixmap. func ConvertImageToXpixmap(imgFile string) (xpixmap x.Pixmap, err error) { pixbuf, err := NewPixbufFromFile(imgFile) defer FreePixbuf(pixbuf) if err != nil { return } xpixmap, err = ConvertPixbufToXpixmap(pixbuf) return } func ConvertPixbufToXpixmap(pixbuf *C.GdkPixbuf) (xpixmap x.Pixmap, err error) { defaultError := fmt.Errorf("convert pixbuf to xpixmap failed, %v", pixbuf) xpixmap = x.Pixmap(C.convert_pixbuf_to_xpixmap(pixbuf)) if xpixmap == 0 { err = defaultError return } return } func ConvertXpixmapToPixbuf(xpixmap x.Pixmap, width, height int) (pixbuf *C.GdkPixbuf, err error) { defaultError := fmt.Errorf("convert xpixmap to pixbuf failed, %v", xpixmap) pixbuf = C.convert_xpixmap_to_pixbuf(C.Pixmap(xpixmap), C.int(width), C.int(height)) if pixbuf == nil { err = defaultError return } return } func ScreenshotImage(file string, f Format) (err error) { pixbuf, err := Screenshot() defer FreePixbuf(pixbuf) if err != nil { return } err = Save(pixbuf, file, f) return } func Screenshot() (pixbuf *C.GdkPixbuf, err error) { defaultError := fmt.Errorf("take a screenshot failed") pixbuf = C.screenshot() if pixbuf == nil { err = defaultError return } return } go-lib-5.6.0.9/gdkpixbuf/gdkpixbuf_test.go000664 000000 000000 00000024277 13753517240 020401 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gdkpixbuf import ( "fmt" C "gopkg.in/check.v1" "os" "testing" ) // Hook up gocheck into the "go test" runner. func Test(t *testing.T) { C.TestingT(t) } type testWrapper struct{} var _ = C.Suite(&testWrapper{}) const ( originImg = "testdata/origin_1920x1080.jpg" originImgWidth = 1920 originImgHeight = 1080 originImgDominantColorH = 198.6 originImgDominantColorS = 0.40 originImgDominantColorV = 0.43 originImgIconBmp = "testdata/origin_icon_48x48.bmp" originImgIconGif = "testdata/origin_icon_48x48.gif" originImgIconTxt = "testdata/origin_icon_48x48.txt" originImgPngSmall = "testdata/origin_small_200x200.png" originImgIconPng1 = "testdata/origin_icon_1_48x48.png" originImgNotImage = "testdata/origin_not_image" ) func (*testWrapper) TestGetImageSize(c *C.C) { w, h, _ := GetImageSize(originImg) c.Check(w, C.Equals, originImgWidth) c.Check(h, C.Equals, originImgHeight) } func (*testWrapper) TestGetImageFormat(c *C.C) { var f Format f, _ = GetImageFormat(originImgIconPng1) c.Check(f, C.Equals, FormatPng) f, _ = GetImageFormat(originImgIconBmp) c.Check(f, C.Equals, FormatBmp) _, err := GetImageFormat(originImgIconTxt) c.Check(err, C.NotNil) } func (*testWrapper) TestIsSupportedImage(c *C.C) { c.Check(IsSupportedImage(originImgIconPng1), C.Equals, true) c.Check(IsSupportedImage(originImgIconBmp), C.Equals, true) c.Check(IsSupportedImage(originImgIconGif), C.Equals, true) c.Check(IsSupportedImage(originImgIconTxt), C.Equals, false) c.Check(IsSupportedImage(originImgNotImage), C.Equals, false) c.Check(IsSupportedImage(""), C.Equals, false) } func (*testWrapper) TestGetDominantColor(c *C.C) { h, s, v, err := GetDominantColorOfImage(originImg) if err != nil { c.Error(err) } if delta(h, originImgDominantColorH) > 1 || delta(s, originImgDominantColorS) > 0.1 || delta(v, originImgDominantColorV) > 0.1 { c.Error("h, s, v = ", h, s, v) } } func delta(x, y float64) float64 { if x >= y { return x - y } return y - x } func (*testWrapper) TestBlurImage(c *C.C) { resultFile := "testdata/test_blurimage.png" err := BlurImage(originImg, resultFile, 50, 1, FormatPng) if err != nil { c.Error(err) } //c.Check(sumFileMd5(resultFile), C.Equals, "1b6781963a66148aed343325d08cfec0") } func (*testWrapper) TestBlurImageCache(c *C.C) { err := InitGdk() if err != nil { c.Skip(err.Error()) return } _, _, err = BlurImageCache(originImg, 50, 1, FormatPng) if err != nil { c.Error(err) } resultFile, useCache, err := BlurImageCache(originImg, 50, 1, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, true) _ = os.Remove(resultFile) _, useCache, err = BlurImageCache(originImg, 50, 1, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, false) } func (*testWrapper) BenchmarkBlurImage(c *C.C) { for i := 0; i < c.N; i++ { resultFile := fmt.Sprintf("testdata/test_blurimage_%d.png", i) err := BlurImage(originImg, resultFile, 50, 1, FormatPng) if err != nil { c.Error(err) } } } func (*testWrapper) TestClipImage(c *C.C) { resultFile := "testdata/test_clipimage_100x200.png" err := ClipImage(originImg, resultFile, 0, 0, 100, 200, FormatPng) if err != nil { c.Error(err) } w, h, err := GetImageSize(resultFile) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, 100) c.Check(int(h), C.Equals, 200) // c.Check(sumFileMd5(resultFile), C.Equals, "0b31f921d5e9478e83eb98eda6b4252d") resultFile = "testdata/test_clipimage_160x160.png" err = ClipImage(originImg, resultFile, 40, 40, 160, 160, FormatPng) if err != nil { c.Error(err) } w, h, err = GetImageSize(resultFile) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, 160) c.Check(int(h), C.Equals, 160) // c.Check(sumFileMd5(resultFile), C.Equals, "ee9530add4ccf8cf77763fdb8e1d7394") } func (*testWrapper) TestConvertImage(c *C.C) { var f Format resultFilePng := "testdata/test_convertimage.png" _ = ConvertImage(originImgPngSmall, resultFilePng, FormatPng) f, _ = GetImageFormat(resultFilePng) c.Check(f, C.Equals, FormatPng) // c.Check(sumFileMd5(resultFilePng), C.Equals, "597e22ed7a9633950908d50e9309be21") resultFileJpg := "testdata/test_convertimage.jpg" _ = ConvertImage(originImgPngSmall, resultFileJpg, FormatJpeg) f, _ = GetImageFormat(resultFileJpg) c.Check(f, C.Equals, FormatJpeg) // c.Check(sumFileMd5(resultFileJpg), C.Equals, "00c7c47613c39e0321cf4df6ab87fd45") resultFileBmp := "testdata/test_convertimage.bmp" _ = ConvertImage(originImgPngSmall, resultFileBmp, FormatBmp) f, _ = GetImageFormat(resultFileBmp) c.Check(f, C.Equals, FormatBmp) // c.Check(sumFileMd5(resultFileBmp), C.Equals, "aef8c2806dfa927f996b18785e58650c") resultFileIco := "testdata/test_convertimage.ico" _ = ConvertImage(originImgPngSmall, resultFileIco, FormatIco) f, _ = GetImageFormat(resultFileIco) c.Check(f, C.Equals, FormatIco) // c.Check(sumFileMd5(resultFileIco), C.Equals, "530442dfd38b9118e944d30d82a9cd37") resultFileTiff := "testdata/test_convertimage.tiff" _ = ConvertImage(originImgPngSmall, resultFileTiff, FormatTiff) f, _ = GetImageFormat(resultFileTiff) c.Check(f, C.Equals, FormatTiff) // FIXME: this hash won't be the same on different arch. // c.Check(sumFileMd5(resultFileTiff), C.Equals, "2d28a01653464896e02c14de58e7487c") } func (*testWrapper) TestFlipImageHorizontal(c *C.C) { resultFileHorizontal := "testdata/test_flipimage_horizontal.png" err := FlipImageHorizontal(originImg, resultFileHorizontal, FormatPng) if err != nil { c.Error(err) } //c.Check(sumFileMd5(resultFileHorizontal), C.Equals, "c6cb10065fea5865c2151b012ebe426c") } func (*testWrapper) TestFlipImageVertical(c *C.C) { resultFileVertical := "testdata/test_flipimage_vertical.png" err := FlipImageVertical(originImg, resultFileVertical, FormatPng) if err != nil { c.Error(err) } // c.Check(sumFileMd5(resultFileVertical), C.Equals, "9683192bfd772e024e8f9ece58aa0035") } func (*testWrapper) TestScaleImage(c *C.C) { resultFile := "testdata/test_scaleimage_500x600.png" err := ScaleImage(originImg, resultFile, 500, 600, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } w, h, err := GetImageSize(resultFile) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, 500) c.Check(int(h), C.Equals, 600) // c.Check(sumFileMd5(resultFile), C.Equals, "14b8e27e743b6eb66e1c98745dbbd5cf") } func (*testWrapper) TestScaleImagePrefer(c *C.C) { resultFile := "testdata/test_scaleimageprefer_500x600.png" err := ScaleImagePrefer(originImg, resultFile, 500, 600, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } w, h, err := GetImageSize(resultFile) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, 500) c.Check(int(h), C.Equals, 600) // c.Check(sumFileMd5(resultFile), C.Equals, "066950b89d6296e7860ae811d41f47e1") } func (*testWrapper) TestThumbnailImage(c *C.C) { resultFile := "testdata/test_thumbnail.png" maxWidth, maxHeight := 200, 200 err := ThumbnailImage(originImg, resultFile, maxWidth, maxHeight, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } w, h, _ := GetImageSize(resultFile) c.Check(int(w) <= maxWidth, C.Equals, true) c.Check(int(h) <= maxHeight, C.Equals, true) // c.Check(sumFileMd5(resultFile), C.Equals, "ee26f7cafacecb95ae6fa4e4333a0ba1") } func (*testWrapper) TestScaleImageCache(c *C.C) { err := InitGdk() if err != nil { c.Skip(err.Error()) return } _, _, err = ScaleImageCache(originImg, 500, 600, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } resultFile, useCache, err := ScaleImageCache(originImg, 500, 600, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, true) _ = os.Remove(resultFile) _, useCache, err = ScaleImageCache(originImg, 500, 600, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, false) } func (*testWrapper) TestScaleImagePreferCache(c *C.C) { err := InitGdk() if err != nil { c.Skip(err.Error()) return } _, _, err = ScaleImagePreferCache(originImg, 500, 600, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } resultFile, useCache, err := ScaleImagePreferCache(originImg, 500, 600, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, true) _ = os.Remove(resultFile) _, useCache, err = ScaleImagePreferCache(originImg, 500, 600, GDK_INTERP_HYPER, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, false) } func (*testWrapper) TestRotateImageLeft(c *C.C) { resultFile := "testdata/test_rotateimageleft.png" err := RotateImageLeft(originImg, resultFile, FormatPng) if err != nil { c.Error(err) } // c.Check(sumFileMd5(resultFile), C.Equals, "e07d7c97138985843ffab23e26d4bc8d") } func (*testWrapper) TestRotateImageRight(c *C.C) { resultFile := "testdata/test_rotateimageright.png" err := RotateImageRight(originImg, resultFile, FormatPng) if err != nil { c.Error(err) } // c.Check(sumFileMd5(resultFile), C.Equals, "04032dac2648bdd03e07b2b8d38c5848") } func (*testWrapper) TestRotateImageUpsizedown(c *C.C) { resultFile := "testdata/test_rotateimageupsidedown.png" err := RotateImageUpsizedown(originImg, resultFile, FormatPng) if err != nil { c.Error(err) } // c.Check(sumFileMd5(resultFile), C.Equals, "6fb1ca20243db7769ba9bb9521e95012") } func (*testWrapper) ManualTestScreenshotImage(c *C.C) { err := InitGdk() if err != nil { c.Skip(err.Error()) return } resultFile := "testdata/test_screenshot.png" err = ScreenshotImage(resultFile, FormatPng) if err != nil { c.Error(err) } } go-lib-5.6.0.9/gdkpixbuf/testdata/000775 000000 000000 00000000000 13753517240 016625 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gdkpixbuf/testdata/origin_icon_1_48x48.png000664 000000 000000 00000006246 13753517240 022741 0ustar00rootroot000000 000000 PNG  IHDR00WgAMA asRGB cHRMz&u0`:pQ<bKGD pHYs   vIDATh]lu~)Dꃢ胖]+G6 җ&[}OnA~p"Mj;H+UAZeٖDIQIK{0%_rgϹށGkΧc5F>8u|ELJ;;)KȪG>85S=a\z|McjR|8K)Pk!u,)VHڱZ<jbt\y3^t}>݆-=!e?:'B@@2w(jh;&p:r)/$>(w T/A9nÿd7lн'xyPFWC˖!J*4G!@?u j;ehO}}}z{|nٽ#<2|cV*?$\T.Dj}a jWW,mwT 68vlXbn׿z5 6~ g»p:Z1ع=&sfm`kǙPY^xW\O"~ ;\2hD1|rnqCiP&a{_pUplv/s+6o 2??[Taw!rIɧQyKHٱɑo5\'(@P'?yMg3t-M#0~.;t.'u!ݛG滖LA yxD%R, M%4k,3gQ~*џGK ǜ *d?'U^ƒ'\: 6ReWե\FQ*UlQEߢK%3yeρΞYMHqU-͜.iKTTrmL:B|TQiCXx3Sxϳ/xJ)k&PZ#8YNEW0^B9JJG.ۇ7,S>-$(VĀxGq*nsGϩ*+x0;ȑDN JŌ^4mP.CE(u};|=^=Mo+]NGo?m׋] n.s9AC l{PyoR=ZZ?ӖbZȜrϐarț;Rk!PK+}*OX۹ =F 3W54R#8PGNlx WdcFb)Ѵ ׈"|'# TB6!=hQ|uA@=uTCZEFEP[mԜul+=cvĉSrdIpu{A%=y~L gcTcƨVƨQI0crZgbL.ɁT;O>wo_Ȑ/$V*V6u[*1+N_ [PgXTDOnXIʥIpR //^p5%"|hc (%DgO[A+7&Ou/IzLps&ftBȴ Ƨ<߱| 񃿱/ \GNB*b9-m. S>I#R-$i2`҉J@c߱pաw.Cd%p>iRK)gxl` W|%٥U8ξ!hI,T+ UDz ⁊`] +8B7K[xx{H% ""X;ɉWyŕ-p xFѺuǡ#YJ T;i4B&7(N8yɧmqNm[عo@_@úNHZԢ rUA%iJEWBO_ҙKl٨LO SSMWΝɧL5ZBj+~E ݉9J9*o3~1b|Ni(4Z]o[ hshXVkA%IB '] );/ܸ1?eN6 x  >eu$avN~#x0yޓD!Nb~Zff +\YYù" KGςo=A^^{k߽r]+۞T?O~/_±sue35*P~mkzn vXr=!>lu?}z~"pt߃WI<9(xWqhq}y 26Yh6;Z] A\(%T҈{/<=C%F!k{?'6AF9|hqs:V~jūz[t[t}.~V:pώ'D@ltiu|L_|?>+K{t}Og4=:>[[>Tƽ!n{Zd,'O+ʕMpEtx>tz-q1~OQV[|a.|q| n8enfxQJPJDP  !2Og~<fk?rcB 2B%F5*mw;=Gk}?ww}3kZ|X8w Y!!x@{ xp.[u(yp^_Z|FV7Wd&BY cv)e4M'y}΋/lp\ٜsJ{D {: c47X\\/}bJ,?+hXYnL TAFإ@KdyZI9vb?+ rr.hse0X貱dmMy\+<.xE GyUĻ  r,g8zl+MZ@THe;)R健U~辰;o♧_e: C²@C!/;¼sg!BzMZ.DG@BpM@$Js9 Z}ur8h^_D6\)ݣ )W/E [F~oQk K@ G0e _@lJ)h.+c\Gln"FS FSV)- U@LFC+5C*ZMɜczn J(2d/E{Ԧ3%VFU (AT@| ˅zpbKVJ#ZEi h=ƞW:Ul =m!4Ң ٢CR' Z)B!`5ԫHQ!85T*zk qkwM J !8$ٹw}VQla!^ .J֦ULT x"v\)y.\LMBAeJSUc<#Mg ]d5*"]OAbػM{sjv+ʶYZ}@| rs1(6ĐNT)i¡%1I'1 bHl sIl $ #YJk!B%ջк(i"x牬 9>C_4`!I\K:[CmF} DiLZMLUi@%UU,QGG[҉ PI!]VȨy3DVu8|l^;Z!IlETiJ^efviԦ$=T"TqT.K%ɪT(HDF{(h#OYՂ1ĩ>FdaznLMIk)q%:UƖpyBo4Vh-t$<"1LĪU1V PT--^wgd$0W"* $F^&]:Byd޽8d&-KVPCHkX~"V}'Qm5#K ou8i譓&nwjAAJ 2^ *)Ch0r ޘ1]oOr'a**h~εk57h//GŪT#Hц Rt-A@D#bv:Ab˸Ԫ0/bmq`ijH*XEB)"eʢ&c"C;J#z|f5щŚZ+/%R_:U$c FVD$RS#FѦlȜ Q|*^NA١<,gZ?ܿ*%xYlTRCQKC2tt>JTآCf 2|]|)Nyh<45qxTg؄+WTq+..7+8r0oeZހ,Of/]d22o m8!bI88ɽ犫we/\"T7̲,Z5[=ӏƹ@6~*2LҸBd"yrpy P9RJu{9+,,,ED).Ny^xXJ z>t+\^@^'֙qsr;'ʋ|ɳVj啫?Nh0LR~^^ަWRPT1QHq42BOݦjm ƀ#1fۻGldV%ѶevǾXD[j Z Qbߒ:5VؽBH[6Ȳ}z5%mhN w}wsfCsfhm&7Fi67b`(ö?w?p}Y.QpsnxW@ d$@{;N~~ !dt;/^*/f(W-{wѺpJy?~sޡ&b676yɧ{/}s/?`}O?zD!|.-ڕE` lL*0WRR$MM\㟴mѶ|t?i47qZ>q̀,>T`xRƗ a؛a;I$p$||lH2y8><4)˘͞ΟϠϠϠϠϠϠӡhO###, j2j2j2j2j2 |Ffffffea [ {R 66y;HE?EA`I̛ΟΟϠϠϠϠϠϠѠ x####O*j2j2j2j2j2 |Fffffec^ Vi* ľ7 yAROL! r͝ΟϠϠϠϠϠϠϠРء;.###, f1j2j2j2j2j2v? Yfffda Z oF L\YV?%!7+ϜΞΟϠϠϠϠϠϠϠϠӡ p####>%j2j2j2j2j2j2j2s< I L K zFi6X)m1^fc`XEA  lϞΟϠϠϠϠϠϠϠϠϠРءF6####>%j2j2j2j2j2j2j2j2j2j2g1c/[+]8.Hmkh|B4ѝΟΟϠϠϠϠϠϠϠϠϠϠҠ/%####>%j2j2j2j2j2j2j2j2j2h1e0_-U(,%nnE#+#ϞΟϠϠϠϠϠϠϠϠϠϠϠϠӡ p#####0!].j2j2j2j2j2j2j2i2g0a.Y*v]5_neb j͝ΟϠϠϠϠϠϠϠϠϠϠϠϠϠРԡ p######>%T+j2j2j2j2j2j2h1d/I&/0%=Z,) f˚͞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠРա p#######'5"G(G(G(G(4"&  ='N }]Óɛ͞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРӡ;.############"!97>$8 lɜΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠӠΙ `############" $30 ė˝ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠѠա‘ _:.#########"7+ tW 60Ț̞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРҠա p _Q>Q>Q>Q> _ oϝǘƙ˝ΟΟϠϠϠϠϠϠϠ`ϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРѠҠӠӠӠӠҠѠϟ͞˜țǚǚț˝͟ΟϠϠϠϠϠϠϠ`ϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠΟΟΟ͞͞ΟΟΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠΟΟΟΟϠϠϠϠϠϠϠϠϠϠ`ϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠ`Ϡgo-lib-5.6.0.9/gdkpixbuf/testdata/origin_icon_48x48.gif000664 000000 000000 00000004223 13753517240 022473 0ustar00rootroot000000 000000 GIF89a00 "!"$% (&(,&-0"/#48 702 *6(6;0:98'>A8<%B9= D0A /E&H4D!K&NAE >G*R0Q%U7R=Q+YMO.\)_GW7]>[+a/d2fAa V\Db,iIa.k6j 0l Ch Qg=oGl8rMkOl`fJnEp[kJt @xYrNw[wL| F~ R{ Z|Vc}^ryTOwy[] ZkcbnYy`ljz_fcieqy o}unn tq}v ~ |+qy{x  } } 4$ #()+ !N!8Y'4# @ .&L'F>GHP+)8;e>GQ8KEVFfW*zkC:VN_fo!Created with GIMP! ,00 H*\ȰB[#JHE3jőVƃCN+VNjENŲ%K[%]t5G)U Q)*-VZb5cE"y~bիW LP5HhޜU#XS:@@*oAb:VbYU]yQغRՆo "x`@1ᮑ0+8m Sk)$b[#2V۠2V0-?"MVJDb U/Z BҩAgOL! NzA8aN찂N? 1]E^,@oA|Ƈj}m0p7樣OL1q@%9tb^jAH!K-JtA\ϑb`jVc^HSL#5 ;0 &K XfZ,ȕg &p1ش@]ij<#HD ( ;yd)WFChD+O!M0y?Ђ 'L# A׫F 4!<"QJ00QDa`]CMU EYT!qOLA._o\aR_0E&ٰ9$GHq2QaXn \|,#0 *CO>ӏ:ds:Z{ ,U]0dhCO<0~i ?A?3 ?CX0AĀ0 HS8 <JH, n L|‰h4EM (i P?x l  @F3h$( MDiqc,c($ PKJhL" RV,$ 0@'S@ WӘ<&,:! iHMP+)C1J$ !:Al@B * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gdkpixbuf import ( "pkg.deepin.io/lib/graphic" "pkg.deepin.io/lib/utils" ) // function links to lib/graphic func generateCacheFilePath(keyword string) string { return utils.GenerateCacheFilePathWithPrefix("graphic", keyword) } // Rgb2Hsv convert color format from RGB(r, g, b=[0..255]) to HSV(h=[0..360), s,v=[0..1]). func Rgb2Hsv(r, g, b uint8) (h, s, v float64) { return graphic.Rgb2Hsv(r, g, b) } // Hsv2Rgb convert color format from HSV(h=[0..360), s,v=[0..1]) to RGB(r, g, b=[0..255]). func Hsv2Rgb(h, s, v float64) (r, g, b uint8) { return graphic.Hsv2Rgb(h, s, v) } // GetPreferScaleClipRect get the maximum rectangle in center of // image which with the same scale to reference width/heigh. func GetPreferScaleClipRect(refWidth, refHeight, imgWidth, imgHeight int) (x, y, w, h int, err error) { x, y, w, h, err = graphic.GetPreferScaleClipRect(refWidth, refHeight, imgWidth, imgHeight) return } go-lib-5.6.0.9/gettext/000775 000000 000000 00000000000 13753517240 014515 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/build_test_locale_data000775 000000 000000 00000021501 13753517240 021110 0ustar00rootroot000000 000000 #!/bin/bash -ex OUTDIR=testdata/locale_def function gen() { name=$1 charset=$2 localedef -f $charset -i ${name%.${charset}} $OUTDIR/$name } mkdir -p $OUTDIR || true gen en_US.UTF-8 UTF-8 #set LOCPATH=`pwd`/$OUTDIR/ to use this locale def. # aa_ER UTF-8 # aa_ER@saaho UTF-8 # aa_ET UTF-8 # af_ZA ISO-8859-1 # af_ZA.UTF-8 UTF-8 # ak_GH UTF-8 # am_ET UTF-8 # an_ES ISO-8859-15 # an_ES.UTF-8 UTF-8 # anp_IN UTF-8 # ar_AE ISO-8859-6 # ar_AE.UTF-8 UTF-8 # ar_BH ISO-8859-6 # ar_BH.UTF-8 UTF-8 # ar_DZ ISO-8859-6 # ar_DZ.UTF-8 UTF-8 # ar_EG ISO-8859-6 # ar_EG.UTF-8 UTF-8 # ar_IN UTF-8 # ar_IQ ISO-8859-6 # ar_IQ.UTF-8 UTF-8 # ar_JO ISO-8859-6 # ar_JO.UTF-8 UTF-8 # ar_KW ISO-8859-6 # ar_KW.UTF-8 UTF-8 # ar_LB ISO-8859-6 # ar_LB.UTF-8 UTF-8 # ar_LY ISO-8859-6 # ar_LY.UTF-8 UTF-8 # ar_MA ISO-8859-6 # ar_MA.UTF-8 UTF-8 # ar_OM ISO-8859-6 # ar_OM.UTF-8 UTF-8 # ar_QA ISO-8859-6 # ar_QA.UTF-8 UTF-8 # ar_SA ISO-8859-6 # ar_SA.UTF-8 UTF-8 # ar_SD ISO-8859-6 # ar_SD.UTF-8 UTF-8 # ar_SS UTF-8 # ar_SY ISO-8859-6 # ar_SY.UTF-8 UTF-8 # ar_TN ISO-8859-6 # ar_TN.UTF-8 UTF-8 # ar_YE ISO-8859-6 # ar_YE.UTF-8 UTF-8 # as_IN UTF-8 # ast_ES ISO-8859-15 # ast_ES.UTF-8 UTF-8 # ayc_PE UTF-8 # az_AZ UTF-8 # be_BY CP1251 # be_BY.UTF-8 UTF-8 # be_BY@latin UTF-8 # bem_ZM UTF-8 # ber_DZ UTF-8 # ber_MA UTF-8 # bg_BG CP1251 # bg_BG.UTF-8 UTF-8 # bh_IN.UTF-8 UTF-8 # bho_IN UTF-8 # bn_BD UTF-8 # bn_IN UTF-8 # bo_CN UTF-8 # bo_IN UTF-8 # br_FR ISO-8859-1 # br_FR.UTF-8 UTF-8 # br_FR@euro ISO-8859-15 # brx_IN UTF-8 # bs_BA ISO-8859-2 # bs_BA.UTF-8 UTF-8 # byn_ER UTF-8 # ca_AD ISO-8859-15 # ca_AD.UTF-8 UTF-8 # ca_ES ISO-8859-1 # ca_ES.UTF-8 UTF-8 # ca_ES.UTF-8@valencia UTF-8 # ca_ES@euro ISO-8859-15 # ca_ES@valencia ISO-8859-15 # ca_FR ISO-8859-15 # ca_FR.UTF-8 UTF-8 # ca_IT ISO-8859-15 # ca_IT.UTF-8 UTF-8 # ce_RU UTF-8 # cmn_TW UTF-8 # crh_UA UTF-8 # cs_CZ ISO-8859-2 # cs_CZ.UTF-8 UTF-8 # csb_PL UTF-8 # cv_RU UTF-8 # cy_GB ISO-8859-14 # cy_GB.UTF-8 UTF-8 # da_DK ISO-8859-1 # da_DK.UTF-8 UTF-8 # de_AT ISO-8859-1 # de_AT.UTF-8 UTF-8 # de_AT@euro ISO-8859-15 # de_BE ISO-8859-1 # de_BE.UTF-8 UTF-8 # de_BE@euro ISO-8859-15 # de_CH ISO-8859-1 # de_CH.UTF-8 UTF-8 # de_DE ISO-8859-1 # de_DE.UTF-8 UTF-8 # de_DE@euro ISO-8859-15 # de_LI.UTF-8 UTF-8 # de_LU ISO-8859-1 # de_LU.UTF-8 UTF-8 # de_LU@euro ISO-8859-15 # doi_IN UTF-8 # dv_MV UTF-8 # dz_BT UTF-8 # el_CY ISO-8859-7 # el_CY.UTF-8 UTF-8 # el_GR ISO-8859-7 # el_GR.UTF-8 UTF-8 # en_AG UTF-8 # en_AU ISO-8859-1 # en_AU.UTF-8 UTF-8 # en_BW ISO-8859-1 # en_BW.UTF-8 UTF-8 # en_CA ISO-8859-1 # en_CA.UTF-8 UTF-8 # en_DK ISO-8859-1 # en_DK.ISO-8859-15 ISO-8859-15 # en_DK.UTF-8 UTF-8 # en_GB ISO-8859-1 # en_GB.ISO-8859-15 ISO-8859-15 # en_GB.UTF-8 UTF-8 # en_HK ISO-8859-1 # en_HK.UTF-8 UTF-8 # en_IE ISO-8859-1 # en_IE.UTF-8 UTF-8 # en_IE@euro ISO-8859-15 # en_IN UTF-8 # en_NG UTF-8 # en_NZ ISO-8859-1 # en_NZ.UTF-8 UTF-8 # en_PH ISO-8859-1 # en_PH.UTF-8 UTF-8 # en_SG ISO-8859-1 # en_SG.UTF-8 UTF-8 # en_US ISO-8859-1 # en_US.ISO-8859-15 ISO-8859-15 # en_ZA ISO-8859-1 # en_ZA.UTF-8 UTF-8 # en_ZM UTF-8 # en_ZW ISO-8859-1 # en_ZW.UTF-8 UTF-8 # eo ISO-8859-3 # eo.UTF-8 UTF-8 # es_AR ISO-8859-1 # es_AR.UTF-8 UTF-8 # es_BO ISO-8859-1 # es_BO.UTF-8 UTF-8 # es_CL ISO-8859-1 # es_CL.UTF-8 UTF-8 # es_CO ISO-8859-1 # es_CO.UTF-8 UTF-8 # es_CR ISO-8859-1 # es_CR.UTF-8 UTF-8 # es_CU UTF-8 # es_DO ISO-8859-1 # es_DO.UTF-8 UTF-8 # es_EC ISO-8859-1 # es_EC.UTF-8 UTF-8 # es_ES ISO-8859-1 # es_ES.UTF-8 UTF-8 # es_ES@euro ISO-8859-15 # es_GT ISO-8859-1 # es_GT.UTF-8 UTF-8 # es_HN ISO-8859-1 # es_HN.UTF-8 UTF-8 # es_MX ISO-8859-1 # es_MX.UTF-8 UTF-8 # es_NI ISO-8859-1 # es_NI.UTF-8 UTF-8 # es_PA ISO-8859-1 # es_PA.UTF-8 UTF-8 # es_PE ISO-8859-1 # es_PE.UTF-8 UTF-8 # es_PR ISO-8859-1 # es_PR.UTF-8 UTF-8 # es_PY ISO-8859-1 # es_PY.UTF-8 UTF-8 # es_SV ISO-8859-1 # es_SV.UTF-8 UTF-8 # es_US ISO-8859-1 # es_US.UTF-8 UTF-8 # es_UY ISO-8859-1 # es_UY.UTF-8 UTF-8 # es_VE ISO-8859-1 # es_VE.UTF-8 UTF-8 # et_EE ISO-8859-1 # et_EE.ISO-8859-15 ISO-8859-15 # et_EE.UTF-8 UTF-8 # eu_ES ISO-8859-1 # eu_ES.UTF-8 UTF-8 # eu_ES@euro ISO-8859-15 # eu_FR ISO-8859-1 # eu_FR.UTF-8 UTF-8 # eu_FR@euro ISO-8859-15 # fa_IR UTF-8 # ff_SN UTF-8 # fi_FI ISO-8859-1 # fi_FI.UTF-8 UTF-8 # fi_FI@euro ISO-8859-15 # fil_PH UTF-8 # fo_FO ISO-8859-1 # fo_FO.UTF-8 UTF-8 # fr_BE ISO-8859-1 # fr_BE.UTF-8 UTF-8 # fr_BE@euro ISO-8859-15 # fr_CA ISO-8859-1 # fr_CA.UTF-8 UTF-8 # fr_CH ISO-8859-1 # fr_CH.UTF-8 UTF-8 # fr_FR ISO-8859-1 # fr_FR.UTF-8 UTF-8 # fr_FR@euro ISO-8859-15 # fr_LU ISO-8859-1 # fr_LU.UTF-8 UTF-8 # fr_LU@euro ISO-8859-15 # fur_IT UTF-8 # fy_DE UTF-8 # fy_NL UTF-8 # ga_IE ISO-8859-1 # ga_IE.UTF-8 UTF-8 # ga_IE@euro ISO-8859-15 # gd_GB ISO-8859-15 # gd_GB.UTF-8 UTF-8 # gez_ER UTF-8 # gez_ER@abegede UTF-8 # gez_ET UTF-8 # gez_ET@abegede UTF-8 # gl_ES ISO-8859-1 # gl_ES.UTF-8 UTF-8 # gl_ES@euro ISO-8859-15 # gu_IN UTF-8 # gv_GB ISO-8859-1 # gv_GB.UTF-8 UTF-8 # ha_NG UTF-8 # hak_TW UTF-8 # he_IL ISO-8859-8 # he_IL.UTF-8 UTF-8 # hi_IN UTF-8 # hne_IN UTF-8 # hr_HR ISO-8859-2 # hr_HR.UTF-8 UTF-8 # hsb_DE ISO-8859-2 # hsb_DE.UTF-8 UTF-8 # ht_HT UTF-8 # hu_HU ISO-8859-2 # hu_HU.UTF-8 UTF-8 # hy_AM UTF-8 # hy_AM.ARMSCII-8 ARMSCII-8 # ia_FR UTF-8 # id_ID ISO-8859-1 # id_ID.UTF-8 UTF-8 # ig_NG UTF-8 # ik_CA UTF-8 # is_IS ISO-8859-1 # is_IS.UTF-8 UTF-8 # it_CH ISO-8859-1 # it_CH.UTF-8 UTF-8 # it_IT ISO-8859-1 # it_IT.UTF-8 UTF-8 # it_IT@euro ISO-8859-15 # iu_CA UTF-8 # iw_IL ISO-8859-8 # iw_IL.UTF-8 UTF-8 # ja_JP.EUC-JP EUC-JP # ja_JP.UTF-8 UTF-8 # ka_GE GEORGIAN-PS # ka_GE.UTF-8 UTF-8 # kk_KZ PT154 # kk_KZ RK1048 # kk_KZ.UTF-8 UTF-8 # kl_GL ISO-8859-1 # kl_GL.UTF-8 UTF-8 # km_KH UTF-8 # kn_IN UTF-8 # ko_KR.EUC-KR EUC-KR # ko_KR.UTF-8 UTF-8 # kok_IN UTF-8 # ks_IN UTF-8 # ks_IN@devanagari UTF-8 # ku_TR ISO-8859-9 # ku_TR.UTF-8 UTF-8 # kw_GB ISO-8859-1 # kw_GB.UTF-8 UTF-8 # ky_KG UTF-8 # lb_LU UTF-8 # lg_UG ISO-8859-10 # lg_UG.UTF-8 UTF-8 # li_BE UTF-8 # li_NL UTF-8 # lij_IT UTF-8 # lo_LA UTF-8 # lt_LT ISO-8859-13 # lt_LT.UTF-8 UTF-8 # lv_LV ISO-8859-13 # lv_LV.UTF-8 UTF-8 # lzh_TW UTF-8 # mag_IN UTF-8 # mai_IN UTF-8 # mg_MG ISO-8859-15 # mg_MG.UTF-8 UTF-8 # mhr_RU UTF-8 # mi_NZ ISO-8859-13 # mi_NZ.UTF-8 UTF-8 # mk_MK ISO-8859-5 # mk_MK.UTF-8 UTF-8 # ml_IN UTF-8 # mn_MN UTF-8 # mni_IN UTF-8 # mr_IN UTF-8 # ms_MY ISO-8859-1 # ms_MY.UTF-8 UTF-8 # mt_MT ISO-8859-3 # mt_MT.UTF-8 UTF-8 # my_MM UTF-8 # nan_TW UTF-8 # nan_TW@latin UTF-8 # nb_NO ISO-8859-1 # nb_NO.UTF-8 UTF-8 # nds_DE UTF-8 # nds_NL UTF-8 # ne_NP UTF-8 # nhn_MX UTF-8 # niu_NU UTF-8 # niu_NZ UTF-8 # nl_AW UTF-8 # nl_BE ISO-8859-1 # nl_BE.UTF-8 UTF-8 # nl_BE@euro ISO-8859-15 # nl_NL ISO-8859-1 # nl_NL.UTF-8 UTF-8 # nl_NL@euro ISO-8859-15 # nn_NO ISO-8859-1 # nn_NO.UTF-8 UTF-8 # nr_ZA UTF-8 # nso_ZA UTF-8 # oc_FR ISO-8859-1 # oc_FR.UTF-8 UTF-8 # om_ET UTF-8 # om_KE ISO-8859-1 # om_KE.UTF-8 UTF-8 # or_IN UTF-8 # os_RU UTF-8 # pa_IN UTF-8 # pa_PK UTF-8 # pap_AN UTF-8 # pap_AW UTF-8 # pap_CW UTF-8 # pl_PL ISO-8859-2 # pl_PL.UTF-8 UTF-8 # ps_AF UTF-8 # pt_BR ISO-8859-1 # pt_BR.UTF-8 UTF-8 # pt_PT ISO-8859-1 # pt_PT.UTF-8 UTF-8 # pt_PT@euro ISO-8859-15 # quz_PE UTF-8 # raj_IN UTF-8 # ro_RO ISO-8859-2 # ro_RO.UTF-8 UTF-8 # ru_RU ISO-8859-5 # ru_RU.CP1251 CP1251 # ru_RU.KOI8-R KOI8-R # ru_RU.UTF-8 UTF-8 # ru_UA KOI8-U # ru_UA.UTF-8 UTF-8 # rw_RW UTF-8 # sa_IN UTF-8 # sat_IN UTF-8 # sc_IT UTF-8 # sd_IN UTF-8 # sd_IN@devanagari UTF-8 # se_NO UTF-8 # shs_CA UTF-8 # si_LK UTF-8 # sid_ET UTF-8 # sk_SK ISO-8859-2 # sk_SK.UTF-8 UTF-8 # sl_SI ISO-8859-2 # sl_SI.UTF-8 UTF-8 # so_DJ ISO-8859-1 # so_DJ.UTF-8 UTF-8 # so_ET UTF-8 # so_KE ISO-8859-1 # so_KE.UTF-8 UTF-8 # so_SO ISO-8859-1 # so_SO.UTF-8 UTF-8 # sq_AL ISO-8859-1 # sq_AL.UTF-8 UTF-8 # sq_MK UTF-8 # sr_ME UTF-8 # sr_RS UTF-8 # sr_RS@latin UTF-8 # ss_ZA UTF-8 # st_ZA ISO-8859-1 # st_ZA.UTF-8 UTF-8 # sv_FI ISO-8859-1 # sv_FI.UTF-8 UTF-8 # sv_FI@euro ISO-8859-15 # sv_SE ISO-8859-1 # sv_SE.ISO-8859-15 ISO-8859-15 # sv_SE.UTF-8 UTF-8 # sw_KE UTF-8 # sw_TZ UTF-8 # szl_PL UTF-8 # ta_IN UTF-8 # ta_LK UTF-8 # te_IN UTF-8 # tg_TJ KOI8-T # tg_TJ.UTF-8 UTF-8 # th_TH TIS-620 # th_TH.UTF-8 UTF-8 # the_NP UTF-8 # ti_ER UTF-8 # ti_ET UTF-8 # tig_ER UTF-8 # tk_TM UTF-8 # tl_PH ISO-8859-1 # tl_PH.UTF-8 UTF-8 # tn_ZA UTF-8 # tr_CY ISO-8859-9 # tr_CY.UTF-8 UTF-8 # tr_TR ISO-8859-9 # tr_TR.UTF-8 UTF-8 # ts_ZA UTF-8 # tt_RU UTF-8 # tt_RU@iqtelif UTF-8 # tu_IN.UTF-8 UTF-8 # ug_CN UTF-8 # uk_UA KOI8-U # uk_UA.UTF-8 UTF-8 # unm_US UTF-8 # ur_IN UTF-8 # ur_PK UTF-8 # uz_UZ ISO-8859-1 # uz_UZ.UTF-8 UTF-8 # uz_UZ@cyrillic UTF-8 # ve_ZA UTF-8 # vi_VN UTF-8 # wa_BE ISO-8859-1 # wa_BE.UTF-8 UTF-8 # wa_BE@euro ISO-8859-15 # wae_CH UTF-8 # wal_ET UTF-8 # wo_SN UTF-8 # xh_ZA ISO-8859-1 # xh_ZA.UTF-8 UTF-8 # yi_US CP1255 # yi_US.UTF-8 UTF-8 # yo_NG UTF-8 # yue_HK UTF-8 # zh_CN GB2312 # zh_CN.GB18030 GB18030 # zh_CN.GBK GBK # zh_HK BIG5-HKSCS # zh_HK.UTF-8 UTF-8 # zh_SG GB2312 # zh_SG.GBK GBK # zh_SG.UTF-8 UTF-8 # zh_TW BIG5 # zh_TW.EUC-TW EUC-TW # zh_TW.UTF-8 UTF-8 # zu_ZA ISO-8859-1 # zu_ZA.UTF-8 UTF-8 # bhb_IN.UTF-8 UTF-8 # tcy_IN.UTF-8 UTF-8 go-lib-5.6.0.9/gettext/gettext.go000664 000000 000000 00000010000 13753517240 016517 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gettext /* #include #include #include void _init_i18n() { setlocale(LC_ALL, ""); } */ import "C" import ( "os" "strings" "unsafe" ) var ( // LcAll is for all of the locale. LcAll = int(C.LC_ALL) // LcCollate is for regular expression matching (it determines the meaning of // range expressions and equivalence classes) and string collation. LcCollate = int(C.LC_COLLATE) // LcCtype is for regular expression matching, character classification, // conversion, case-sensitive comparison, and wide character functions. LcCtype = int(C.LC_CTYPE) // LcMessages is for localizable natural-language messages. LcMessages = int(C.LC_MESSAGES) // LcMonetary is for monetary formatting. LcMonetary = int(C.LC_MONETARY) // LcNumeric is for number formatting (such as the decimal point and the // thousands separator). LcNumeric = int(C.LC_NUMERIC) // LcTime is for time and date formatting. LcTime = int(C.LC_TIME) ) func Tr(id string) string { _id := C.CString(id) defer C.free(unsafe.Pointer(_id)) return C.GoString(C.gettext(_id)) } func DGettext(domain, id string) string { _id := C.CString(id) _d := C.CString(domain) defer C.free(unsafe.Pointer(_id)) defer C.free(unsafe.Pointer(_d)) return C.GoString(C.dgettext(_d, _id)) } func Textdomain(domain string) { _domain := C.CString(domain) defer C.free(unsafe.Pointer(_domain)) C.textdomain(_domain) } func InitI18n() { C._init_i18n() } func SetLocale(category int, locale string) string { cLocale := C.CString(locale) defer C.free(unsafe.Pointer(cLocale)) return C.GoString(C.setlocale(C.int(category), cLocale)) } func Bindtextdomain(domain, dirname string) string { _domain := C.CString(domain) _dirname := C.CString(dirname) defer C.free(unsafe.Pointer(_domain)) defer C.free(unsafe.Pointer(_dirname)) return C.GoString(C.bindtextdomain(_domain, _dirname)) } func NTr(msgid, plural string, n int) string { cMsgid := C.CString(msgid) defer C.free(unsafe.Pointer(cMsgid)) cPlural := C.CString(plural) defer C.free(unsafe.Pointer(cPlural)) return C.GoString(C.ngettext(cMsgid, cPlural, C.ulong(n))) } func DNGettext(domain, msgid, plural string, n int) string { cDomain := C.CString(domain) defer C.free(unsafe.Pointer(cDomain)) cMsgid := C.CString(msgid) defer C.free(unsafe.Pointer(cMsgid)) cPlural := C.CString(plural) defer C.free(unsafe.Pointer(cPlural)) return C.GoString(C.dngettext(cDomain, cMsgid, cPlural, C.ulong(n))) } // QueryLang return user lang. // the rule is document at man gettext(3) func QueryLang() string { return QueryLangs()[0] } // QueryLangs return array of user lang, split by ":". // the rule is document at man gettext(3) func QueryLangs() []string { LC_ALL := os.Getenv("LC_ALL") LC_MESSAGE := os.Getenv("LC_MESSAGE") LANGUAGE := os.Getenv("LANGUAGE") LANG := os.Getenv("LANG") cutoff := func(s string) string { for i, c := range s { if c == '.' { return s[:i] } } return s } if LC_ALL != "C" && LANGUAGE != "" { var r []string for _, lang := range strings.Split(LANGUAGE, ":") { r = append(r, cutoff(lang)) } return r } if LC_ALL != "" { return []string{cutoff(LC_ALL)} } if LC_MESSAGE != "" { return []string{cutoff(LC_MESSAGE)} } if LANG != "" { return []string{cutoff(LANG)} } return []string{""} } go-lib-5.6.0.9/gettext/gettext_test.go000664 000000 000000 00000006665 13753517240 017604 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package gettext import ( "os" "os/exec" "testing" C "gopkg.in/check.v1" ) type gettext struct{} //nolint:golint,unused func Test(t *testing.T) { C.TestingT(t) } func init() { // use ./build_test_locale_data to update locale def if need _ = os.Setenv("LOCPATH", "testdata/locale_def/") _ = os.Setenv("LC_ALL", "en_US.UTF-8") cmd := exec.Command("/usr/bin/locale", "-a") cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr _ = cmd.Run() //C.Suite(&gettext{}) } func (*gettext) TestTr(c *C.C) { _ = os.Setenv("LC_ALL", "en_US.UTF-8") _ = os.Setenv("LANGUAGE", "ar") InitI18n() Bindtextdomain("test", "testdata/locale") Textdomain("test") c.Check(Tr("Back"), C.Equals, "الخلف") } func (*gettext) TestDGettext(c *C.C) { _ = os.Setenv("LC_ALL", "en_US.UTF-8") _ = os.Setenv("LANGUAGE", "zh_CN") InitI18n() Bindtextdomain("test", "testdata/locale") c.Check(DGettext("test", "Back"), C.Equals, "返回") } func (*gettext) TestFailed(c *C.C) { _ = os.Setenv("LC_ALL", "en_US.UTF-8") InitI18n() Bindtextdomain("test", "testdata/locale") c.Check(DGettext("test", "notfound"), C.Equals, "notfound") c.Check(DGettext("test", "未找到"), C.Equals, "未找到") } func (*gettext) TestNTr(c *C.C) { _ = os.Setenv("LC_ALL", "en_US.UTF-8") Bindtextdomain("test", "testdata/plural/locale") Textdomain("test") _ = os.Setenv("LANGUAGE", "es") InitI18n() c.Check(NTr("%d apple", "%d apples", 1), C.Equals, "%d manzana") c.Check(NTr("%d apple", "%d apples", 2), C.Equals, "%d manzanas") _ = os.Setenv("LANGUAGE", "zh_CN") InitI18n() c.Check(NTr("%d apple", "%d apples", 0), C.Equals, "%d苹果") c.Check(NTr("%d apple", "%d apples", 1), C.Equals, "%d苹果") c.Check(NTr("%d apple", "%d apples", 2), C.Equals, "%d苹果") } func (*gettext) TestDNGettext(c *C.C) { _ = os.Setenv("LC_ALL", "en_US.UTF-8") Bindtextdomain("test", "testdata/plural/locale") _ = os.Setenv("LANGUAGE", "es") InitI18n() c.Check(DNGettext("test", "%d person", "%d persons", 1), C.Equals, "%d persona") c.Check(DNGettext("test", "%d person", "%d persons", 2), C.Equals, "%d personas") _ = os.Setenv("LANGUAGE", "zh_CN") InitI18n() c.Check(DNGettext("test", "%d person", "%d persons", 0), C.Equals, "%d人") c.Check(DNGettext("test", "%d person", "%d persons", 1), C.Equals, "%d人") c.Check(DNGettext("test", "%d person", "%d persons", 2), C.Equals, "%d人") } func (*gettext) TestQueryLang(c *C.C) { _ = os.Setenv("LC_ALL", "zh_CN.UTF-8") _ = os.Setenv("LC_MESSAGE", "zh_TW.") _ = os.Setenv("LANGUAGE", "en_US.12") _ = os.Setenv("LANG", "it") c.Check(QueryLang(), C.Equals, "en_US") _ = os.Setenv("LANGUAGE", "") c.Check(QueryLang(), C.Equals, "zh_CN") _ = os.Setenv("LC_ALL", "") c.Check(QueryLang(), C.Equals, "zh_TW") } go-lib-5.6.0.9/gettext/testdata/000775 000000 000000 00000000000 13753517240 016326 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/ar.po000664 000000 000000 00000011064 13753517240 017272 0ustar00rootroot000000 000000 # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # mo-hd , 2014 # alkomeri , 2014 msgid "" msgstr "" "Project-Id-Version: Deepin UI\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-07-03 11:26+0800\n" "PO-Revision-Date: 2014-08-21 08:51+0000\n" "Last-Translator: cxbii \n" "Language-Team: Arabic (http://www.transifex.com/projects/p/deepin-ui/language/ar/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: ar\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" #: dtk/ui/skin.py:747 msgid "Add skin from file" msgstr "أضف سمة من ملف" #: dtk/ui/skin.py:308 msgid "Are you sure you want to delete this skin?" msgstr "هل أنت متأكد أنك تريد حذف هذه السمة ؟" #: dtk/ui/skin.py:885 msgid "Back" msgstr "الخلف" #: dtk/ui/color_selection.py:177 msgid "Blue: " msgstr "أزرق :" #: dtk/ui/color_selection.py:207 dtk/ui/dialog.py:459 dtk/ui/dialog.py:548 #: dtk/ui/tab_window.py:488 msgid "Cancel" msgstr "إلغاء" #: dtk/ui/titlebar.py:150 msgid "Change skin" msgstr "تغيير السمة" #: dtk/ui/titlebar.py:174 dtk/ui/dialog.py:718 dtk/ui/skin.py:130 #: dtk/ui/skin.py:152 msgid "Close" msgstr "إغلاق" #: dtk/ui/color_selection.py:150 msgid "Color value" msgstr "قيمة اللون" #: dtk/ui/file_manager.py:44 msgid "Computer" msgstr "الكمبيوتر" #: dtk/ui/entry.py:903 dtk/ui/net.py:131 dtk/ui/net.py:717 msgid "Copy" msgstr "نسخ" #: dtk/ui/entry.py:902 dtk/ui/net.py:130 dtk/ui/net.py:716 msgid "Cut" msgstr "قص" #: dtk/ui/skin.py:307 msgid "Delete skin" msgstr "حذف سمة" #: dtk/ui/file_manager.py:46 msgid "Desktop" msgstr "سطح المكتب" #: dtk/ui/gio_utils.py:255 #, python-format msgid "Desktop file not exists: %s" msgstr "لا يوجد ملف على سطح المكتب : %s" #: dtk/ui/gio_utils.py:259 #, python-format msgid "Desktop is not valid: %s" msgstr "سطح المكتب غير صالح : %s" #: dtk/ui/entry.py:1996 msgid "Disabled" msgstr "الغاء" #: dtk/ui/file_manager.py:47 msgid "Documents" msgstr "المستندات" #: dtk/ui/file_manager.py:48 msgid "Downloads" msgstr "‫التنزيلات" #: dtk/ui/resizable_label.py:87 msgid "Expand" msgstr "توسيع" #: dtk/ui/skin.py:864 dtk/ui/skin.py:937 msgid "Export" msgstr "تصدير" #: dtk/ui/skin.py:862 msgid "Flip horizontal" msgstr " تدوير أفقي" #: dtk/ui/skin.py:861 msgid "Flip vertical" msgstr " تدوير عمودي" #: dtk/ui/color_selection.py:170 msgid "Green: " msgstr "أخضر :" #: dtk/ui/file_manager.py:45 msgid "Home" msgstr "المنزل" #: dtk/ui/skin.py:270 msgid "Import skin version is mismatch with current one!" msgstr "إصدار السمة لا يطابق السمة الحالية !" #: dtk/ui/iconview.py:476 msgid "Loading..." msgstr "يتم التحميل..." #: dtk/ui/skin.py:863 msgid "Lock scaling" msgstr "قفل التدرج" #: dtk/ui/titlebar.py:156 msgid "Main menu" msgstr "القائمة الرئيسية" #: dtk/ui/titlebar.py:168 msgid "Maximize" msgstr "تكبير" #: dtk/ui/titlebar.py:162 msgid "Minimum" msgstr "تصغير" #: dtk/ui/file_manager.py:49 msgid "Music" msgstr "الصوتيات" #: dtk/ui/color_selection.py:206 dtk/ui/dialog.py:458 dtk/ui/dialog.py:547 #: dtk/ui/tab_window.py:487 msgid "OK" msgstr "موافق" #: dtk/ui/entry.py:904 dtk/ui/net.py:132 dtk/ui/net.py:718 msgid "Paste" msgstr "لصق" #: dtk/ui/file_manager.py:50 msgid "Pictures" msgstr "الصور" #: dtk/ui/entry.py:1956 msgid "Please input new shortcuts" msgstr "الرجاء أدخل اختصارات جديدة" #: dtk/ui/dialog.py:709 msgid "Preferences" msgstr "التفضيلات" #: dtk/ui/color_selection.py:163 msgid "Red: " msgstr "أحمر :" #: dtk/ui/skin.py:125 msgid "Select Skin" msgstr "اختيار سمة" #: dtk/ui/entry.py:905 msgid "Select all" msgstr "إختيار الكل" #: dtk/ui/color_selection.py:111 dtk/ui/skin.py:869 msgid "Select color" msgstr "أختر لون" #: dtk/ui/resizable_label.py:88 msgid "Shrink" msgstr "تقليص" #: dtk/ui/skin.py:269 msgid "Skin version mismatch" msgstr "إصدار السمة غير مطابق" #: dtk/ui/file_manager.py:52 msgid "Trash" msgstr "المهملات" #: dtk/ui/file_manager.py:51 msgid "Videos" msgstr "الفيديو" #: dtk/ui/skin.py:860 msgid "Zoom" msgstr "تكبير" go-lib-5.6.0.9/gettext/testdata/gen_mo000775 000000 000000 00000000216 13753517240 017517 0ustar00rootroot000000 000000 #!/bin/bash for p in *.po ;do name=${p%.po} mkdir -p locale/$name/LC_MESSAGES msgfmt $p -o locale/$name/LC_MESSAGES/test.mo done go-lib-5.6.0.9/gettext/testdata/locale/000775 000000 000000 00000000000 13753517240 017565 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/locale/ar/000775 000000 000000 00000000000 13753517240 020167 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/locale/ar/LC_MESSAGES/000775 000000 000000 00000000000 13753517240 021754 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/locale/ar/LC_MESSAGES/test.mo000664 000000 000000 00000005640 13753517240 023275 0ustar00rootroot000000 000000 .=*/4; BN T`in r~    1 C N [env|     B a l w  4)- W b u   A ' @ T t    1    2 B 'M u  ! -(' $.+ )& * %" ,#Add skin from fileAre you sure you want to delete this skin?BackBlue: CancelChange skinCloseColor valueComputerCopyCutDelete skinDesktopDesktop file not exists: %sDesktop is not valid: %sDisabledDocumentsDownloadsExpandExportFlip horizontalFlip verticalGreen: HomeImport skin version is mismatch with current one!Loading...Lock scalingMain menuMaximizeMinimumMusicOKPastePicturesPlease input new shortcutsPreferencesRed: Select SkinSelect allSelect colorShrinkSkin version mismatchTrashVideosZoomProject-Id-Version: Deepin UI Report-Msgid-Bugs-To: POT-Creation-Date: 2014-07-03 11:26+0800 PO-Revision-Date: 2014-08-21 08:51+0000 Last-Translator: cxbii Language-Team: Arabic (http://www.transifex.com/projects/p/deepin-ui/language/ar/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: ar Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5; أضف سمة من ملفهل أنت متأكد أنك تريد حذف هذه السمة ؟الخلفأزرق :إلغاءتغيير السمةإغلاققيمة اللونالكمبيوترنسخقصحذف سمةسطح المكتبلا يوجد ملف على سطح المكتب : %sسطح المكتب غير صالح : %sالغاءالمستندات‫التنزيلاتتوسيعتصدير تدوير أفقي تدوير عموديأخضر :المنزلإصدار السمة لا يطابق السمة الحالية !يتم التحميل...قفل التدرجالقائمة الرئيسيةتكبيرتصغيرالصوتياتموافقلصقالصورالرجاء أدخل اختصارات جديدةالتفضيلاتأحمر :اختيار سمةإختيار الكلأختر لونتقليصإصدار السمة غير مطابقالمهملاتالفيديوتكبيرgo-lib-5.6.0.9/gettext/testdata/locale/zh_CN/000775 000000 000000 00000000000 13753517240 020566 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/locale/zh_CN/LC_MESSAGES/000775 000000 000000 00000000000 13753517240 022353 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/locale/zh_CN/LC_MESSAGES/test.mo000664 000000 000000 00000004745 13753517240 023701 0ustar00rootroot000000 000000 .=*/4; BN T`in r~    1 C N [env|     !   !+2 9FMi    *   & 0 : D K R Y ` y      ! -(' $.+ )& * %" ,#Add skin from fileAre you sure you want to delete this skin?BackBlue: CancelChange skinCloseColor valueComputerCopyCutDelete skinDesktopDesktop file not exists: %sDesktop is not valid: %sDisabledDocumentsDownloadsExpandExportFlip horizontalFlip verticalGreen: HomeImport skin version is mismatch with current one!Loading...Lock scalingMain menuMaximizeMinimumMusicOKPastePicturesPlease input new shortcutsPreferencesRed: Select SkinSelect allSelect colorShrinkSkin version mismatchTrashVideosZoomProject-Id-Version: Deepin UI Report-Msgid-Bugs-To: POT-Creation-Date: 2014-07-03 11:26+0800 PO-Revision-Date: 2014-08-22 05:26+0000 Last-Translator: electricface Language-Team: Chinese (China) (http://www.transifex.com/projects/p/deepin-ui/language/zh_CN/) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Language: zh_CN Plural-Forms: nplurals=1; plural=0; 添加皮肤文件你确定要删除当前皮肤?返回蓝色: 取消换肤关闭颜色值计算机拷贝剪切删除皮肤桌面Desktop文件不存在:%s无效的Desktop文件:%s禁用文档下载展开导出皮肤横向翻转纵向翻转绿色: 家目录导入皮肤和当前皮肤版本不一致加载中...锁定缩放比例主菜单最大化最小化音乐确定粘贴图片请输入新的快捷键选项红色: 选择皮肤选择全部选择颜色收起皮肤版本不一致回收站视频缩放go-lib-5.6.0.9/gettext/testdata/plural/000775 000000 000000 00000000000 13753517240 017625 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/plural/es.po000664 000000 000000 00000001520 13753517240 020572 0ustar00rootroot000000 000000 # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-06-30 17:51+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;\n" #: t.go:4 #, c-format msgid "%d apple" msgid_plural "%d apples" msgstr[0] "%d manzana" msgstr[1] "%d manzanas" #: t.go:5 #, c-format msgid "%d person" msgid_plural "%d persons" msgstr[0] "%d persona" msgstr[1] "%d personas" go-lib-5.6.0.9/gettext/testdata/plural/gen_mo000775 000000 000000 00000000216 13753517240 021016 0ustar00rootroot000000 000000 #!/bin/bash for p in *.po ;do name=${p%.po} mkdir -p locale/$name/LC_MESSAGES msgfmt $p -o locale/$name/LC_MESSAGES/test.mo done go-lib-5.6.0.9/gettext/testdata/plural/locale/000775 000000 000000 00000000000 13753517240 021064 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/plural/locale/es/000775 000000 000000 00000000000 13753517240 021473 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/plural/locale/es/LC_MESSAGES/000775 000000 000000 00000000000 13753517240 023260 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/plural/locale/es/LC_MESSAGES/test.mo000664 000000 000000 00000001036 13753517240 024574 0ustar00rootroot000000 000000 4L`atf%d apple%d apples%d person%d personsProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2015-06-30 17:51+0800 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE Language: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n>1; %d manzana%d manzanas%d persona%d personasgo-lib-5.6.0.9/gettext/testdata/plural/locale/zh_CN/000775 000000 000000 00000000000 13753517240 022065 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/plural/locale/zh_CN/LC_MESSAGES/000775 000000 000000 00000000000 13753517240 023652 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gettext/testdata/plural/locale/zh_CN/LC_MESSAGES/test.mo000664 000000 000000 00000000775 13753517240 025177 0ustar00rootroot000000 000000 4L`atd%d apple%d apples%d person%d personsProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2015-06-30 17:51+0800 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE Language: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; %d苹果%d人go-lib-5.6.0.9/gettext/testdata/plural/plural.pot000664 000000 000000 00000001465 13753517240 021656 0ustar00rootroot000000 000000 # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-06-30 17:51+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: t.go:4 #, c-format msgid "%d apple" msgid_plural "%d apples" msgstr[0] "" msgstr[1] "" #: t.go:5 #, c-format msgid "%d person" msgid_plural "%d persons" msgstr[0] "" msgstr[1] "" go-lib-5.6.0.9/gettext/testdata/plural/t.go000664 000000 000000 00000001540 13753517240 020417 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package main func main() { NTr("%d apple", "%d apples", 0) DNGettext("domain", "%d person", "%d persons", 0) } go-lib-5.6.0.9/gettext/testdata/plural/update_pot000775 000000 000000 00000000127 13753517240 021717 0ustar00rootroot000000 000000 #!/bin/sh xgettext -L c --keyword=NTr:1,2 --keyword=DNGettext:2,3 -o plural.pot t.go go-lib-5.6.0.9/gettext/testdata/plural/zh_CN.po000664 000000 000000 00000001427 13753517240 021172 0ustar00rootroot000000 000000 # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-06-30 17:51+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: t.go:4 #, c-format msgid "%d apple" msgid_plural "%d apples" msgstr[0] "%d苹果" #: t.go:5 #, c-format msgid "%d person" msgid_plural "%d persons" msgstr[0] "%d人" go-lib-5.6.0.9/gettext/testdata/test.pot000664 000000 000000 00000006767 13753517240 020051 0ustar00rootroot000000 000000 # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-09-04 13:39+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #: ../ui/entry.py:902 ../ui/net.py:130 ../ui/net.py:716 msgid "Cut" msgstr "" #: ../ui/entry.py:903 ../ui/net.py:131 ../ui/net.py:717 msgid "Copy" msgstr "" #: ../ui/entry.py:904 ../ui/net.py:132 ../ui/net.py:718 msgid "Paste" msgstr "" #: ../ui/entry.py:905 msgid "Select all" msgstr "" #: ../ui/entry.py:1956 msgid "Please input new shortcuts" msgstr "" #: ../ui/entry.py:1996 msgid "Disabled" msgstr "" #: ../ui/gio_utils.py:255 #, python-format msgid "The desktop file doesn't exist: %s" msgstr "" #: ../ui/gio_utils.py:259 #, python-format msgid "The desktop file is not valid: %s" msgstr "" #: ../ui/file_manager.py:44 msgid "Computer" msgstr "" #: ../ui/file_manager.py:45 msgid "Home" msgstr "" #: ../ui/file_manager.py:46 msgid "Desktop" msgstr "" #: ../ui/file_manager.py:47 msgid "Documents" msgstr "" #: ../ui/file_manager.py:48 msgid "Downloads" msgstr "" #: ../ui/file_manager.py:49 msgid "Music" msgstr "" #: ../ui/file_manager.py:50 msgid "Pictures" msgstr "" #: ../ui/file_manager.py:51 msgid "Videos" msgstr "" #: ../ui/file_manager.py:52 msgid "Trash" msgstr "" #: ../ui/resizable_label.py:87 msgid "Expand" msgstr "" #: ../ui/resizable_label.py:88 msgid "Shrink" msgstr "" #: ../ui/iconview.py:476 msgid "Loading..." msgstr "" #: ../ui/skin.py:125 msgid "Select Skin" msgstr "" #: ../ui/skin.py:130 ../ui/skin.py:152 ../ui/titlebar.py:174 #: ../ui/dialog.py:718 msgid "Close" msgstr "" #: ../ui/skin.py:269 msgid "Skin Version Mismatch" msgstr "" #: ../ui/skin.py:270 msgid "Imported skin version mismatches with current one!" msgstr "" #: ../ui/skin.py:307 msgid "Delete skin" msgstr "" #: ../ui/skin.py:308 msgid "Are you sure you want to delete this skin?" msgstr "" #: ../ui/skin.py:747 msgid "Add Skin File" msgstr "" #: ../ui/skin.py:860 msgid "Zoom automatically" msgstr "" #: ../ui/skin.py:861 msgid "Flip vertically" msgstr "" #: ../ui/skin.py:862 msgid "Flip horizontally" msgstr "" #: ../ui/skin.py:863 msgid "Lock scaling" msgstr "" #: ../ui/skin.py:864 ../ui/skin.py:937 msgid "Export" msgstr "" #: ../ui/skin.py:869 ../ui/color_selection.py:111 msgid "Select color" msgstr "" #: ../ui/skin.py:885 msgid "Back" msgstr "" #: ../ui/color_selection.py:150 msgid "Color value" msgstr "" #: ../ui/color_selection.py:163 msgid "Red: " msgstr "" #: ../ui/color_selection.py:170 msgid "Green: " msgstr "" #: ../ui/color_selection.py:177 msgid "Blue: " msgstr "" #: ../ui/color_selection.py:206 ../ui/tab_window.py:487 ../ui/dialog.py:458 #: ../ui/dialog.py:547 msgid "OK" msgstr "" #: ../ui/color_selection.py:207 ../ui/tab_window.py:488 ../ui/dialog.py:459 #: ../ui/dialog.py:548 msgid "Cancel" msgstr "" #: ../ui/titlebar.py:150 msgid "Change skin" msgstr "" #: ../ui/titlebar.py:156 msgid "Main menu" msgstr "" #: ../ui/titlebar.py:162 msgid "Minimize" msgstr "" #: ../ui/titlebar.py:168 msgid "Maximize" msgstr "" #: ../ui/dialog.py:709 msgid "Preferences" msgstr "" msgid "%d test" msgid_plural "%d tests" msgstr "" go-lib-5.6.0.9/gettext/testdata/zh_CN.po000664 000000 000000 00000010314 13753517240 017666 0ustar00rootroot000000 000000 # SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # # Translators: # Automatically generated, 2012 # iceleaf , 2013 # iceleaf , 2013 # 李洪武 , 2013-2014 msgid "" msgstr "" "Project-Id-Version: Deepin UI\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-07-03 11:26+0800\n" "PO-Revision-Date: 2014-08-22 05:26+0000\n" "Last-Translator: electricface \n" "Language-Team: Chinese (China) (http://www.transifex.com/projects/p/deepin-ui/language/zh_CN/)\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: zh_CN\n" "Plural-Forms: nplurals=1; plural=0;\n" #: dtk/ui/skin.py:747 msgid "Add skin from file" msgstr "添加皮肤文件" #: dtk/ui/skin.py:308 msgid "Are you sure you want to delete this skin?" msgstr "你确定要删除当前皮肤?" #: dtk/ui/skin.py:885 msgid "Back" msgstr "返回" #: dtk/ui/color_selection.py:177 msgid "Blue: " msgstr "蓝色: " #: dtk/ui/color_selection.py:207 dtk/ui/dialog.py:459 dtk/ui/dialog.py:548 #: dtk/ui/tab_window.py:488 msgid "Cancel" msgstr "取消" #: dtk/ui/titlebar.py:150 msgid "Change skin" msgstr "换肤" #: dtk/ui/titlebar.py:174 dtk/ui/dialog.py:718 dtk/ui/skin.py:130 #: dtk/ui/skin.py:152 msgid "Close" msgstr "关闭" #: dtk/ui/color_selection.py:150 msgid "Color value" msgstr "颜色值" #: dtk/ui/file_manager.py:44 msgid "Computer" msgstr "计算机" #: dtk/ui/entry.py:903 dtk/ui/net.py:131 dtk/ui/net.py:717 msgid "Copy" msgstr "拷贝" #: dtk/ui/entry.py:902 dtk/ui/net.py:130 dtk/ui/net.py:716 msgid "Cut" msgstr "剪切" #: dtk/ui/skin.py:307 msgid "Delete skin" msgstr "删除皮肤" #: dtk/ui/file_manager.py:46 msgid "Desktop" msgstr "桌面" #: dtk/ui/gio_utils.py:255 #, python-format msgid "Desktop file not exists: %s" msgstr "Desktop文件不存在:%s" #: dtk/ui/gio_utils.py:259 #, python-format msgid "Desktop is not valid: %s" msgstr "无效的Desktop文件:%s" #: dtk/ui/entry.py:1996 msgid "Disabled" msgstr "禁用" #: dtk/ui/file_manager.py:47 msgid "Documents" msgstr "文档" #: dtk/ui/file_manager.py:48 msgid "Downloads" msgstr "下载" #: dtk/ui/resizable_label.py:87 msgid "Expand" msgstr "展开" #: dtk/ui/skin.py:864 dtk/ui/skin.py:937 msgid "Export" msgstr "导出皮肤" #: dtk/ui/skin.py:862 msgid "Flip horizontal" msgstr "横向翻转" #: dtk/ui/skin.py:861 msgid "Flip vertical" msgstr "纵向翻转" #: dtk/ui/color_selection.py:170 msgid "Green: " msgstr "绿色: " #: dtk/ui/file_manager.py:45 msgid "Home" msgstr "家目录" #: dtk/ui/skin.py:270 msgid "Import skin version is mismatch with current one!" msgstr "导入皮肤和当前皮肤版本不一致" #: dtk/ui/iconview.py:476 msgid "Loading..." msgstr "加载中..." #: dtk/ui/skin.py:863 msgid "Lock scaling" msgstr "锁定缩放比例" #: dtk/ui/titlebar.py:156 msgid "Main menu" msgstr "主菜单" #: dtk/ui/titlebar.py:168 msgid "Maximize" msgstr "最大化" #: dtk/ui/titlebar.py:162 msgid "Minimum" msgstr "最小化" #: dtk/ui/file_manager.py:49 msgid "Music" msgstr "音乐" #: dtk/ui/color_selection.py:206 dtk/ui/dialog.py:458 dtk/ui/dialog.py:547 #: dtk/ui/tab_window.py:487 msgid "OK" msgstr "确定" #: dtk/ui/entry.py:904 dtk/ui/net.py:132 dtk/ui/net.py:718 msgid "Paste" msgstr "粘贴" #: dtk/ui/file_manager.py:50 msgid "Pictures" msgstr "图片" #: dtk/ui/entry.py:1956 msgid "Please input new shortcuts" msgstr "请输入新的快捷键" #: dtk/ui/dialog.py:709 msgid "Preferences" msgstr "选项" #: dtk/ui/color_selection.py:163 msgid "Red: " msgstr "红色: " #: dtk/ui/skin.py:125 msgid "Select Skin" msgstr "选择皮肤" #: dtk/ui/entry.py:905 msgid "Select all" msgstr "选择全部" #: dtk/ui/color_selection.py:111 dtk/ui/skin.py:869 msgid "Select color" msgstr "选择颜色" #: dtk/ui/resizable_label.py:88 msgid "Shrink" msgstr "收起" #: dtk/ui/skin.py:269 msgid "Skin version mismatch" msgstr "皮肤版本不一致" #: dtk/ui/file_manager.py:52 msgid "Trash" msgstr "回收站" #: dtk/ui/file_manager.py:51 msgid "Videos" msgstr "视频" #: dtk/ui/skin.py:860 msgid "Zoom" msgstr "缩放" go-lib-5.6.0.9/graphic/000775 000000 000000 00000000000 13753517240 014446 5ustar00rootroot000000 000000 go-lib-5.6.0.9/graphic/README.md000664 000000 000000 00000000723 13753517240 015727 0ustar00rootroot000000 000000 Go 图形处理库, 主要围绕 Go 自身的 image 库进行增强开发. 支持对图片进行 剪切, 翻转, 缩放, 混合等操作. 关于 API 的命名风格, 以 Clip 操作为例: - **Clip** 对 image.Image 对象进行剪切操作 - **ClipImage** 对目标文件进行剪切操作 - **ClipImageCache** 对目标文件进行剪切操作, 同时将处理后的文件放到缓 存目录, 下次对同一文件进行相同操作时可以大大提高速度 go-lib-5.6.0.9/graphic/clip.go000664 000000 000000 00000003432 13753517240 015726 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "fmt" "image" "image/draw" ) // ClipImage clip image file that format is recognized and save it with target format. func ClipImage(srcfile, dstfile string, x, y, w, h int, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return } dstimg := Clip(srcimg, x, y, w, h) err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // ClipImageCache clip any recognized format image and save to cache // directory, if already exists, just return it. func ClipImageCache(srcfile string, x, y, w, h int, f Format) (dstfile string, useCache bool, err error) { dstfile = generateCacheFilePath(fmt.Sprintf("ClipImageCache%s%d%d%d%d%s", srcfile, x, y, w, h, f)) if isFileExists(dstfile) { useCache = true return } err = ClipImage(srcfile, dstfile, x, y, w, h, f) return } // ClipImage clip image object. func Clip(srcimg image.Image, x, y, w, h int) (dstimg *image.RGBA) { dstimg = image.NewRGBA(image.Rect(0, 0, w, h)) draw.Draw(dstimg, dstimg.Bounds(), srcimg, image.Point{x, y}, draw.Src) return } go-lib-5.6.0.9/graphic/composite.go000664 000000 000000 00000005376 13753517240 017012 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "image" "image/draw" "sort" ) type compositeInfoSorter []CompositeInfo func (a compositeInfoSorter) Len() int { return len(a) } func (a compositeInfoSorter) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a compositeInfoSorter) Less(i, j int) bool { return a[i].Z < a[j].Z } type CompositeInfo struct { File string X, Y, Z int } // CompositeImageSet composite a set of image files. func CompositeImageSet(srcfile string, compinfos []CompositeInfo, dstfile string, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return } dstimg := convertToRGBA(srcimg) sort.Sort(compositeInfoSorter(compinfos)) for _, compinfo := range compinfos { var compimg image.Image compimg, err = LoadImage(compinfo.File) if err != nil { return } Composite(dstimg, compimg, compinfo.X, compinfo.Y) } err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // CompositeImage composite two image files. func CompositeImage(srcfile, compfile, dstfile string, x, y int, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return } compimg, err := LoadImage(compfile) if err != nil { return } dstimg := convertToRGBA(srcimg) Composite(dstimg, compimg, x, y) err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // CompositeImageUri composite two images which format in data uri. func CompositeImageUri(srcDatauri, compDataUri string, x, y int, f Format) (dstDataUri string, err error) { srcimg, err := LoadImageFromDataUri(srcDatauri) if err != nil { return } compimg, err := LoadImageFromDataUri(compDataUri) if err != nil { return } dstimg := convertToRGBA(srcimg) Composite(dstimg, compimg, x, y) dstDataUri, err = ConvertImageObjectToDataUri(dstimg, f) dstimg.Pix = nil return } // CompositeImage composite two image objects. func Composite(dstimg draw.Image, compimg image.Image, x, y int) { w, h := GetSize(compimg) r := image.Rect(x, y, x+w, y+h) draw.Draw(dstimg, r, compimg, image.Point{0, 0}, draw.Over) } go-lib-5.6.0.9/graphic/convert.go000664 000000 000000 00000002633 13753517240 016461 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "fmt" ) // ConvertImage converts from any recognized format to target format image. func ConvertImage(srcfile, dstfile string, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return } return SaveImage(dstfile, srcimg, f) } // ConvertImageCache converts from any recognized format to cache // directory, if already exists, just return it. func ConvertImageCache(srcfile string, f Format) (dstfile string, useCache bool, err error) { dstfile = generateCacheFilePath(fmt.Sprintf("ConvertImageCache%s%s", srcfile, f)) if isFileExists(dstfile) { useCache = true return } err = ConvertImage(srcfile, dstfile, f) return } go-lib-5.6.0.9/graphic/data_uri.go000664 000000 000000 00000004720 13753517240 016570 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "bytes" "encoding/base64" "fmt" "image" "io/ioutil" "strings" ) // ConvertImageToDataUri convert image file to data uri. func ConvertImageToDataUri(imgfile string) (dataUri string, err error) { data, err := ioutil.ReadFile(imgfile) if err != nil { return } f, err := GetImageFormat(imgfile) if err != nil { return } contentType := imageFormatToDataUriContentType(f) dataUri = fmt.Sprintf("data:%s;base64,%s", contentType, base64.StdEncoding.EncodeToString(data)) return } // ConvertImageToDataUri convert image.Image object to data uri. func ConvertImageObjectToDataUri(img image.Image, f Format) (dataUri string, err error) { byteBuf := new(bytes.Buffer) err = doSaveImage(byteBuf, img, f) if err != nil { return } data := byteBuf.Bytes() contentType := imageFormatToDataUriContentType(f) dataUri = fmt.Sprintf("data:%s;base64,%s", contentType, base64.StdEncoding.EncodeToString(data)) byteBuf.Reset() return } // ConvertDataUriToImage convert data uri to image file. func ConvertDataUriToImage(dataUri string, dstfile string, f Format) (err error) { img, err := LoadImageFromDataUri(dataUri) if err != nil { return } return SaveImage(dstfile, img, f) } // LoadImageFromDataUri convert data uri to image object. func LoadImageFromDataUri(dataUri string) (img image.Image, err error) { strs := strings.Split(dataUri, ",") // ;base64, if len(strs) != 2 { err = fmt.Errorf("invalid data uri: %s", dataUri) return } data, err := base64.StdEncoding.DecodeString(strs[1]) if err != nil { return } r := bytes.NewReader(data) img, _, err = image.Decode(r) return } func imageFormatToDataUriContentType(f Format) (contentType string) { contentType = fmt.Sprintf("image/%s", f) return } go-lib-5.6.0.9/graphic/dominant_color.go000664 000000 000000 00000003133 13753517240 020004 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "fmt" "image" ) // GetDominantColorOfImage return the dominant hsv color of an image. func GetDominantColorOfImage(imgfile string) (h, s, v float64, err error) { img, err := LoadImage(imgfile) if err != nil { return } return doGetDominantColorOfImage(img) } func doGetDominantColorOfImage(img image.Image) (h, s, v float64, err error) { // loop all points in image var sumR, sumG, sumB, count uint64 mx := img.Bounds().Max.X my := img.Bounds().Max.Y count = uint64(mx * my) if count == 0 { err = fmt.Errorf("image is empty") return } for x := 0; x < mx; x++ { for y := 0; y < my; y++ { c := img.At(x, y) rr, gg, bb, _ := c.RGBA() r, g, b := rr>>8, gg>>8, bb>>8 sumR += uint64(r) sumG += uint64(g) sumB += uint64(b) } } h, s, v = Rgb2Hsv(uint8(sumR/count), uint8(sumG/count), uint8(sumB/count)) return } go-lib-5.6.0.9/graphic/fill.go000664 000000 000000 00000006725 13753517240 015735 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "fmt" "image" "image/draw" ) // TODO: is FillXXX() still necessary? // FillStyle define the type to fill image. type FillStyle string const ( FillTile FillStyle = "tile" // 平铺 FillCenter FillStyle = "center" // 居中 ) // FillImage generate a new image file in target width and height through // source image file, there are many fill sytles to choice from. func FillImage(srcfile, dstfile string, width, height int, style FillStyle, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return } dstimg, err := Fill(srcimg, width, height, style) if err != nil { return } err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // FillImageCache generate a new image in target width and height through // source image, and save it to cache directory, if already exists, // just return it. func FillImageCache(srcfile string, width, height int, style FillStyle, f Format) (dstfile string, useCache bool, err error) { dstfile = generateCacheFilePath(fmt.Sprintf("FillImageCache%s%d%d%s%s", srcfile, width, height, style, f)) if isFileExists(dstfile) { // return cache file useCache = true return } err = FillImage(srcfile, dstfile, width, height, style, f) return } // FillImage generate a new image in target width and height through // source image, there are many fill sytles to choice from. func Fill(srcimg image.Image, width, height int, style FillStyle) (dstimg *image.RGBA, err error) { switch style { case FillTile: dstimg = doFillImageInTileStyle(srcimg, width, height) case FillCenter: dstimg = doFillImageInCenterStyle(srcimg, width, height) default: err = fmt.Errorf("unknown fill style %v", style) return } return } func doFillImageInTileStyle(srcimg image.Image, width, height int) (dstimg *image.RGBA) { dstimg = image.NewRGBA(image.Rect(0, 0, int(width), int(height))) iw, ih := GetSize(srcimg) endx := width - 1 endy := height - 1 for x := 0; x <= endx; x += iw { for y := 0; y <= endy; y += ih { draw.Draw(dstimg, image.Rect(x, y, x+iw, y+ih), srcimg, image.Point{0, 0}, draw.Src) } } return } func doFillImageInCenterStyle(srcimg image.Image, width, height int) (dstimg *image.RGBA) { dstimg = image.NewRGBA(image.Rect(0, 0, int(width), int(height))) iw, ih := GetSize(srcimg) var srcX, srcY, dstX, dstY, clipWidth, clipHeight int if width > iw { srcX = 0 clipWidth = iw dstX = width/2 - iw/2 } else { dstX = 0 clipWidth = width srcX = iw/2 - width/2 } if height > ih { srcY = 0 clipHeight = ih dstY = height/2 - ih/2 } else { dstY = 0 clipHeight = height srcY = ih/2 - height/2 } draw.Draw(dstimg, image.Rect(dstX, dstY, dstX+clipWidth, dstY+clipHeight), srcimg, image.Point{srcX, srcY}, draw.Src) return } go-lib-5.6.0.9/graphic/flip.go000664 000000 000000 00000003663 13753517240 015737 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "image" ) // FlipImageHorizontal flip image in horizontal direction, and save as // target format. func FlipImageHorizontal(srcfile, dstfile string, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return err } dstimg := doFlipImageHorizontal(srcimg) err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // FlipImageVertical flip image in vertical direction, and save as // target format. func FlipImageVertical(srcfile, dstfile string, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return err } dstimg := doFlipImageVertical(srcimg) err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } func doFlipImageHorizontal(srcimg image.Image) (dstimg *image.RGBA) { w, h := GetSize(srcimg) dstimg = image.NewRGBA(image.Rect(0, 0, w, h)) for x := 0; x < w; x++ { for y := 0; y < h; y++ { dstimg.Set(w-x-1, y, srcimg.At(x, y)) } } return } func doFlipImageVertical(srcimg image.Image) (dstimg *image.RGBA) { w, h := GetSize(srcimg) dstimg = image.NewRGBA(image.Rect(0, 0, w, h)) for x := 0; x < w; x++ { for y := 0; y < h; y++ { dstimg.Set(x, h-y-1, srcimg.At(x, y)) } } return } go-lib-5.6.0.9/graphic/format_sniff.go000664 000000 000000 00000003361 13753517240 017455 0ustar00rootroot000000 000000 /* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "bufio" "os" ) type format struct { name, magic string } // image formats: var formats = []format{ {"jpeg", "\xff\xd8"}, {"bmp", "BM????\x00\x00\x00\x00"}, {"png", "\x89PNG\r\n\x1a\n"}, {"tiff", "MM\x00\x2A"}, // little-endian {"tiff", "II\x2A\x00"}, // big-endian {"gif", "GIF8?a"}, } // Sniff determines the format of r's data. func sniff(r *bufio.Reader) format { for _, f := range formats { b, err := r.Peek(len(f.magic)) if err == nil && match(f.magic, b) { return f } } return format{} } // Match reports whether magic matches b. Magic may contain "?" wildcards. func match(magic string, b []byte) bool { if len(magic) != len(b) { return false } for i, c := range b { if magic[i] != c && magic[i] != '?' { return false } } return true } func SniffImageFormat(file string) (string, error) { fh, err := os.Open(file) if err != nil { return "", err } defer fh.Close() reader := bufio.NewReader(fh) format := sniff(reader) return format.name, nil } go-lib-5.6.0.9/graphic/graphic.go000664 000000 000000 00000001723 13753517240 016415 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic // Format defines the type of image format. type Format string // Registered image format. const ( FormatPng Format = "png" FormatJpeg Format = "jpeg" FormatBmp Format = "bmp" FormatTiff Format = "tiff" ) go-lib-5.6.0.9/graphic/graphic_test.go000664 000000 000000 00000043550 13753517240 017460 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "testing" C "gopkg.in/check.v1" ) const ( originImg = "testdata/origin_1920x1080.jpg" originImgWidth = 1920 originImgHeight = 1080 originImgDominantColorH = 198.6 originImgDominantColorS = 0.40 originImgDominantColorV = 0.43 originImgPngSmall = "testdata/origin_small_200x200.png" originImgPngIcon1 = "testdata/origin_icon_1_48x48.png" originImgPngIcon2 = "testdata/origin_icon_2_48x48.png" originIconWidth = 48 originIconHeight = 48 originImgNotImage = "testdata/origin_not_image" ) // data uri for originImgPngIcon2 const testDataUri = `data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAgY0hSTQAAeiUAAICDAAD5/wAAgOkAAHUwAADqYAAAOpgAABdvkl/FRgAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAADpJJREFUaN7VmeuPXddZxn/vuuzLuczN8SW2YztJm8QhbZo6bQoVDU2qglSQWgQFJFCFVKn9WiSgEn9AK0SRKCAhoFKD2oigFgmqpqJBbRq3SQglSePEk4vjGXuc8djjmTlz7nP2XmvxYe9zmYtTlQYVlvRq77Nm9j7P8z7vZa11JITA/+dhdk4c3ffg7QcP7f/C737iIx+659TJeDDIefaH87z73pNEkSFOYn7wxPO0Wh3uvOsWZmbqCMLFCytcWVnDuQACIoIgxUtHl8nPgsjOb5c9QV5evtZ78cxr371y+dofnF342ivbnphU4Oi+Bz/xyU/9xt9+5o9/L4qsHc1fvLDCseOH8MFzdWUD7wMzszUqlYRQfm1/a8DGeotup7cLzHZYcj2c1yEQCD7QbHX48pe+0T/9+H99en7h6w/tInB034O3f/hX3v/8F//ms0nuPM45gg8opXj+2VdxztPYaHHoxn3cedfNDLYyGo02WebY6g9oNju0Wl36/QwZQZGRt4EdHpfx/1zf+QAoJVTSiOm5Gn/xhYd7Lzz36j1DJUYh9Gsfe/8XP/snnzaDQUaeOXwIaK1xznP50jqtVo8HfvkU1WrCxcWr9HpbdLpbdNt92s0uvX5W4t0ROsNwGc+OmYwn3kSzQMDTbHRpdfp89NcfTF984fU/Bz6yjcAr80un+v2BiZMYl3u01nTaff7160/R72fc8vYbEYT5l5botvs0mz06zT5bWxk+lIFUxr2oIW4Ze1pkLIYIJ0/eyMvzK7uAixYOHpzmypVNcEV0eAI+5HR6Ld5x9zHefsfx+4ZPjAjEUbLvysoG11Zb3HzrYZrNLo985XHufMcJbrn1EOA49+plrq1ustno0utmeO9RSlBKoURQqiCBB9EKESEbuDJPwgi8AGd+tDzh7KECgcMHZvnYx+/jaw8/zfJyY0IJjc8yCEISJftG4TUSKsBtdxzjO489R2uzy8MPfZeTP3ecd9x9M2vXWnz70RdYOHeFq5cLAlnmIQgEIXjBuUCee7wLeB9wLhBbw/79daIownlwXvAOnAdfWvAQfOADD9xGAFaWN/naV59k5fImQhhZCCDBAIVjdimQZZ40Tbj3vSd56O8e49R9t/Ge993Oi88v0mz1cA6uXNmc8LbHBY1zAREPStAC3ntECdp7Op0MYzQ3H5+iv+VYXFwvfa2GYqBKLD/4zitogOBYWW5MFIIJoVRBRuHYpUDuHIHA5UvrZHmgWkk5dmI/ohQryxsMtnJyF/Au4DxkeSDLPFnuyXOPGwSyrPC8ywK5Czjn6PUyeu0tDt5Y5e53HkIIaBxaeZR4JHgUHh08Go8pTePRUtpoPqAIaPG7FfDec/61ZRYWrvL7n/ow//jQ91jf6LKx1mRttU2WeZQWXAiIKzwueBBFIKC0R3lVxLsKEAQJgs9y8ixn0M84emwfqytN1tZaQKGYjKpUmEj+7WX01jsP8frZFYIHKYntUsDlgaWlVX71o++lsd7m9jtv4pmnX2Xpwjr9rQznAt5DnofCskCeF8RD8OADBAchLwLbO4TCvHP4PMdlOe99/9swIlgJGAkYApGBI8fqRBq0CmgpTRW2OH8ZLQGjPcF7YiO7CSilufVth7GR4cLCKq1mn3otpdfPyAYB5wM+Z5SkIYRCejxaAioU4UAIiC/mQx7I8pxeL8flnhACtWrKbXcdwCqPVh6tPYeO1vjIb32QA0dqWPFEqjQprfxsJSDBEUfsDiFEMRjktJsDWu0+q6tNWu0BLg+IEkQER0CrQnBNQBMQBAWIBCSABLBKAIVzOaIMWgWsGbeyuX11lvVy6ThoXt3k21//Du2rm0Q2XLcp+xAQHLHdowopgVfmLxFFCVu9nMZGl35vgKBRoYhroQCoxBUNS0CHgowKgkcwZSDnA1/8nUBsBaUVShWLvJmZKbT2aBku6BytK+vjnNhjuRQYllxHbNVuAiKKxkaH+RfPU6ultNsZwQtGU1aDovgpAS2CgeILVUCpsgMHiEyRG0ZDEiuqNUOUKga5o1pNyZxjem4KqwKiA0ooFR6Dlr0yuewF+JxkLwUQRZ57lpca1KYztBKMFhQBJYJWoEbJVYSUCqoog0GjVEB8IMuFeqJwHmJLsbxWikoSI1oRRRYTaYwNaD0EHsaeH4JXARGhOlWj02wTHAz6PbSEbSE00qIICaHd2aK12UMFj1Kl95Un0gqjAloptBK0EpCAQgghYDXUq4pIg1GBqbohspo4NVQqEbV6FWsMcRLRa3ewBqwFG4FNIEogjiGKhTiBJILZuRp3/+J9zMxWUWxhtMcaIYnVXgoULtBKEfKM1qanmhqCVfhMiFQgeI+RInZcKXkuggZcH0xNExvB5UKWQWW6SqUeU6tVqNVjPKAjTWelgZYMXfZkNSoEpSLlu123watP/oCsuUFi4di73017c5NqqnYroMq2HlnBWoXVEILjffefQHyOHrINnuAcyhfK4HK8c6QxKBw21tjEkE7FVOspabXCoRv3ESUxSRoRJzHd9Q1iG0hsILaexPric+RJbCC1gSQKxMYjWZNKqqmlmmuvnSG2QiXVuxXQuihp1giRFqwVIqt49vvniazGDQYcOT5Dq9EDXzQYo2CgAiEISVyESzpbwRpDbapGfbrOzA2zRGlMWk2pTFXY6rZpvLFAJVUYVSyftRSbFlGlR0db0okKFAIEsJFQSfYIIV1WgsioErzwm5/4eb71yDNEVoiMkHW2OHxsjl6zO1ohpgJJbIgSRVSxpGlKtV5lZnaK6blptLXUpqoktQQbGc499R9U0yJUD95xFxuvv1QuyUsSJfDJqlQQKEhERqikexEo48lowZb26CNPE1mN1YIxgssGxKmiPrsPl+WjRmSNYXpuirSagvdMTddJaylxJaY6VcXGlqSScOW1eUJvnTRWaC10l+apJBqli/I8IjGRD0yADwHEqr0VEFWYMYIdmlYYDcZQVBctrC1e5ZZ3HWfupsNkg5wkiTDGEFciKpUUAgyyjKSaktYSoiTCRoar516m8fqPqCYaXTrE6EJ5pQWjZKSEyN69OASPixS1ZI8cGCaxLUukVqpQQ8lIAWvAGlh++SL9Vou77n0nUZKAgNYabTXGGqYjS5QUCZtvdTj/1GnorZMmpgBuyndqQRtBjUqPIDL27rYYougXXgsqug4BKUPCaDCq8PjkF95yzwnemL+IMdBdb/Ds409y0+0nmL1hlqnZGSq1Ktpo8n6HzrVrrDU3aC8vEkcQxapUtrgaI0jRhgvQUqyf3nQtQUBEI2J2Exg6Qetij6vLuNSqMKWFpRcvYm1xr7VgxLO6uEjj0gWslRGwyCrSWBNFQhIpIquKpmUU1hbKoobAhyZjIkMSOxmEAEojenxmNdGJi8Wa3gFaKxkvJcpS+65fOlUkmxa0BmMLz0ZWkUSaJFIYUxYEIxizE7xG1PCFGtEa0ab8bMicINrgUbx8/iqtXk6n50HZoZf36MQTyTwsZ1rG/z/cvyolvHj6WWxUklKMldJDk1H4je5LQ6kydHQRPkqPVBjef+/0GaLYopXwp59/mEOHZhkMMh584F2cfM8pTn/7ee748J4EwmiZPDQ1updxeJaEpFRn2ISkvB8SHStXVJpxkg4BKy4uN6jXK9TrFb76lcc4cuIw//Dlb/H6wmVa7R693oCzrywB8P2n5vmdT2Y89Pff4I/+7C+3EzBRURHSalSUNPFFOZOJQ9nJylAm2naSjJvQRCgPK9z2lwiNZp+//qt/od3tkyQx//74C4hAp7vFdUfZE3aF0GsrZ3hj43aeOfc0U2mdufoMc/UpDlamsaktto06jNT4acdjT5zh2Wde4Z+/+cxP9FwYtuWdBOIowRqL0opmv02j2+DcZU/uc6wxzEzVuWFmhqMHbuDI/jmm03RUx9FFSRyfrwkhFEYQfGku87yxusnaRpfP/OGXGAzcTwR+rzFBIMWamDSpErzHeYf3Dh8cuXM0mh3WGpvMv76A944kTThy+AA3HTnMsRv3k8aGOFLESogs5YKwqD4AL59dZPH8Mt/6tx8yGORvCfhtBJI4IYpiqkkFFwLe5Tjv8aE4Fsm9x/sc54qrd57FxWXOL1wiBM/UVJX9N8yyf/8stVq12Bw1mrRbPbL+gNOPnsa5QDbIfirAMkyynQTSuEJkIqrVGt55cu9weY4LvlDCOfJSFedKdbwfzfV7OYuLKywsLBNFlkQpls4uFE7IHXleeNxY/RODnhxKCXqvPrB0/hyrK8tcXrxAtV4nrdaZqtVxgMtzcpePwDvvJxTKixN878mzAf1Wm+5qk+WVqwQ/TrZo8jDnpxjaGky0x1KiuX6NXrvFxdde3qZXUqlQqVQxUYxIcTQy/oFCAE+33abbapFtDcaAI/vjsPyPhjFm27tHBGxk0VYTJdG2ZYj3Ge1248e+WBRE6Vvj5euOANpq7N4EDFoLUWLfkjr/vzW0Vti9QkhbvTbIsn2VegWXvzUl7q0exhgG2QBt9dpoTgp3y313/8JzzWbzQ3MHZmisbaImNxb/B0YInpkbpmk2N4li85wUi6pgKLbDtpf1P3fp0tL99z9wv33pzFmWLr5RHJnzsw6n4nD54KED3HPqbp544vuZV/7zQAxkAiRAHZi95657f/uOO05+9v4PfiCdmZ0hG2R0Ox28L16y1xgq5YMvymYoV6mq+C3Le493xdG6yHAXBkqVz3k/fo8AoZhz3qG1Jo5ilBY2NzZ56smney+dfelzL8w/9wiwAbQEqAKzwAFg//59B08cP3ri49ZE7xGR+s/Y/YUGIbSyfPCfFy4t/tPq2pVFYBW4CmxMKjBXEpkCUsBSJLmeuA5NTVwV45+09/xtjtG2fHQ/ab40N3EdWj5xzYAe0Cy9vz5UwJRgkxJ4UsaXnSBh2JuM2mE7SewksBdwvwP4JOh8AnwGbAH9kkifMgeGptju5b08/WaArweeNyHxZoTeTJnhXPhvRNpvhl7bEUUAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTQtMDUtMjdUMjA6Mjk6MjQrMDg6MDAHXnTgAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE0LTA1LTI2VDE3OjQzOjE4KzA4OjAwb8FJUwAAAABJRU5ErkJggg==` // Hook up gocheck into the "go test" runner. func Test(t *testing.T) { C.TestingT(t) } type testWrapper struct{} var _ = C.Suite(&testWrapper{}) func delta(x, y float64) float64 { if x >= y { return x - y } return y - x } func (g *testWrapper) TestLoadImage(c *C.C) { _, err := LoadImage(originImg) if err != nil { c.Error(err) } } func (g *testWrapper) TestCompositeImage(c *C.C) { resultFile := "testdata/test_compositeimage.png" err := CompositeImage(originImgPngSmall, originImgPngIcon1, resultFile, 0, 0, FormatPng) if err != nil { c.Error(err) } err = CompositeImage(resultFile, originImgPngIcon2, resultFile, 24, 24, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestCompositeImageSet(c *C.C) { resultFile := "testdata/test_compositeimageset.png" compInfos := []CompositeInfo{ {originImgPngIcon1, 0, 0, 10}, {originImgPngIcon2, 24, 24, 0}, } err := CompositeImageSet(originImgPngSmall, compInfos, resultFile, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestCompositeImageUri(c *C.C) { resultFile := "testdata/test_compositeimageuri.png" srcImageUri, _ := ConvertImageToDataUri(originImgPngSmall) compImageUri1, _ := ConvertImageToDataUri(originImgPngIcon1) compImageUri2, _ := ConvertImageToDataUri(originImgPngIcon2) resultDataUri, _ := CompositeImageUri(srcImageUri, compImageUri1, 0, 0, FormatPng) resultDataUri, _ = CompositeImageUri(resultDataUri, compImageUri2, 24, 24, FormatPng) err := ConvertDataUriToImage(resultDataUri, resultFile, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestClipImage(c *C.C) { resultFile := "testdata/test_clipimage_100x200.png" err := ClipImage(originImg, resultFile, 0, 0, 100, 200, FormatPng) if err != nil { c.Error(err) } w, h, err := GetImageSize(resultFile) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, 100) c.Check(int(h), C.Equals, 200) resultFile = "testdata/test_clipimage_160x160.png" err = ClipImage(originImg, resultFile, 40, 40, 160, 160, FormatPng) if err != nil { c.Error(err) } w, h, err = GetImageSize(resultFile) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, 160) c.Check(int(h), C.Equals, 160) } func (g *testWrapper) TestConvertImage(c *C.C) { resultFile := "testdata/test_convertimage.png" err := ConvertImage(originImg, resultFile, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestConvertImageToDataUri(c *C.C) { dataUri, err := ConvertImageToDataUri(originImgPngIcon2) if err != nil { c.Error(err) } c.Check(dataUri, C.Equals, testDataUri) } func (g *testWrapper) TestConvertDataUriToImage(c *C.C) { resultFile := "testdata/test_convertdatauri.png" err := ConvertDataUriToImage(testDataUri, resultFile, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestLoadImageFromDataUri(c *C.C) { img, err := LoadImageFromDataUri(testDataUri) if err != nil { c.Error(err) } w, h := GetSize(img) c.Check(w, C.Equals, originIconWidth) c.Check(h, C.Equals, originIconHeight) } func (g *testWrapper) TestFillImage(c *C.C) { resultFile := "testdata/test_flllimage_tile_200x200.png" err := FillImage(originImg, resultFile, 200, 200, FillTile, FormatPng) if err != nil { c.Error(err) } resultFile = "testdata/test_flllimage_tile_1600x1000.png" err = FillImage(originImg, resultFile, 1600, 1000, FillTile, FormatPng) if err != nil { c.Error(err) } resultFile = "testdata/test_flllimage_center_400x400.png" err = FillImage(originImg, resultFile, 400, 400, FillCenter, FormatPng) if err != nil { c.Error(err) } resultFile = "testdata/test_flllimage_center_1600x1000.png" err = FillImage(originImg, resultFile, 1600, 1000, FillCenter, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestFillImageCache(c *C.C) { _, _, err := FillImageCache(originImg, 1024, 768, FillTile, FormatPng) if err != nil { c.Skip("Fill image cache failed:" + err.Error()) return } _, useCache, err := FillImageCache(originImg, 1024, 768, FillTile, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, true) } func (g *testWrapper) TestFlipImageHorizontal(c *C.C) { resultFile := "testdata/test_flipimagehorizontal.png" err := FlipImageHorizontal(originImg, resultFile, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestFlipImageVertical(c *C.C) { resultFile := "testdata/test_flipimagevertical.png" err := FlipImageVertical(originImg, resultFile, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestGetDominantColor(c *C.C) { h, s, v, err := GetDominantColorOfImage(originImg) if err != nil { c.Error(err) } if delta(h, originImgDominantColorH) > 1 || delta(s, originImgDominantColorS) > 0.1 || delta(v, originImgDominantColorV) > 0.1 { c.Error("h, s, v = ", h, s, v) } } // Test that a subset of RGB space can be converted to HSV and back to within // 1/256 tolerance. func (g *testWrapper) TestHsv(c *C.C) { for r := 0; r < 255; r += 7 { for g := 0; g < 255; g += 5 { for b := 0; b < 255; b += 3 { r0, g0, b0 := uint8(r), uint8(g), uint8(b) h, s, v := Rgb2Hsv(r0, g0, b0) r1, g1, b1 := Hsv2Rgb(h, s, v) if delta(float64(r0), float64(r1)) > 1 || delta(float64(g0), float64(g1)) > 1 || delta(float64(b0), float64(b1)) > 1 { c.Fatalf("r0, g0, b0 = %d, %d, %d r1, g1, b1 = %d, %d, %d", r0, g0, b0, r1, g1, b1) } } } } } func (g *testWrapper) TestGetImageSize(c *C.C) { w, h, err := GetImageSize(originImg) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, originImgWidth) c.Check(int(h), C.Equals, originImgHeight) } func (g *testWrapper) TestGetImageFormat(c *C.C) { format, err := GetImageFormat(originImg) if err != nil { c.Error(err) } c.Check(format, C.Equals, FormatJpeg) } func (g *testWrapper) TestIsSupportedImage(c *C.C) { c.Check(IsSupportedImage(originImg), C.Equals, true) c.Check(IsSupportedImage(originImgNotImage), C.Equals, false) c.Check(IsSupportedImage(""), C.Equals, false) } func (g *testWrapper) TestScaleImage(c *C.C) { resultFile := "testdata/test_scaleimage_500x600.png" err := ScaleImage(originImg, resultFile, 500, 600, FormatPng) if err != nil { c.Error(err) } w, h, err := GetImageSize(resultFile) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, 500) c.Check(int(h), C.Equals, 600) } func (g *testWrapper) TestScaleImagePrefer(c *C.C) { resultFile := "testdata/test_scaleimageprefer_500x600.png" err := ScaleImagePrefer(originImg, resultFile, 500, 600, FormatPng) if err != nil { c.Error(err) } w, h, err := GetImageSize(resultFile) if err != nil { c.Error(err) } c.Check(int(w), C.Equals, 500) c.Check(int(h), C.Equals, 600) } func (g *testWrapper) TestScaleImageCache(c *C.C) { _, _, err := ScaleImageCache(originImg, 200, 200, FormatPng) if err != nil { c.Skip("Scale image cache failed:" + err.Error()) return } _, useCache, err := ScaleImageCache(originImg, 200, 200, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, true) } func (g *testWrapper) TestThumbnailImage(c *C.C) { resultFile := "testdata/test_thumbnail.png" maxWidth, maxHeight := 200, 200 err := ThumbnailImage(originImg, resultFile, maxWidth, maxHeight, FormatPng) if err != nil { c.Error(err) } w, h, _ := GetImageSize(resultFile) c.Check(int(w) <= maxWidth, C.Equals, true) c.Check(int(h) <= maxHeight, C.Equals, true) } func (g *testWrapper) TestThumbnailImageCache(c *C.C) { _, _, err := ThumbnailImageCache(originImg, 200, 200, FormatPng) if err != nil { c.Skip("Thumb image cache failed:" + err.Error()) return } _, useCache, err := ThumbnailImageCache(originImg, 200, 200, FormatPng) if err != nil { c.Error(err) } c.Check(useCache, C.Equals, true) } func (g *testWrapper) TestRotateImageLeft(c *C.C) { resultFile := "testdata/test_rotateimageleft.png" err := RotateImageLeft(originImg, resultFile, FormatPng) if err != nil { c.Error(err) } } func (g *testWrapper) TestRotateImageRight(c *C.C) { resultFile := "testdata/test_rotateimageright.png" err := RotateImageRight(originImg, resultFile, FormatPng) if err != nil { c.Error(err) } } func (*testWrapper) TestGetPreferScaleClipRect(c *C.C) { data := []struct { refWidth, refHeight, imgWidth, imgHeight int x, y, w, h int }{ {1024, 768, 512, 100, 189, 0, 133, 100}, {1024, 768, 100, 384, 0, 154, 100, 75}, {1024, 768, 512, 384, 0, 0, 512, 384}, {1024, 768, 1024, 768, 0, 0, 1024, 768}, {1440, 900, 1440, 900, 0, 0, 1440, 900}, {1024, 768, 1920, 1080, 240, 0, 1440, 1080}, } for _, d := range data { x, y, w, h, err := GetPreferScaleClipRect(d.refWidth, d.refHeight, d.imgWidth, d.imgHeight) c.Check(err, C.Equals, nil) c.Check(x, C.Equals, d.x) c.Check(y, C.Equals, d.y) c.Check(w, C.Equals, d.w) c.Check(h, C.Equals, d.h) } // check same clip rectangle size with original width and height for i := 1; i < 10000; i++ { x, y, w, h, _ := GetPreferScaleClipRect(i, 768, i, 768) c.Check(x, C.Equals, 0) c.Check(y, C.Equals, 0) c.Check(w, C.Equals, i) c.Check(h, C.Equals, 768) } // check exceptions var err error _, _, _, _, err = GetPreferScaleClipRect(0, 0, 100, 100) c.Check(err, C.NotNil) _, _, _, _, err = GetPreferScaleClipRect(1024, 768, 512, 0) c.Check(err, C.NotNil) _, _, _, _, err = GetPreferScaleClipRect(1024, 768, 0, 384) c.Check(err, C.NotNil) _, _, _, _, err = GetPreferScaleClipRect(1024, 768, 0, 0) c.Check(err, C.NotNil) } func (g *testWrapper) TestNewImageWithColor(c *C.C) { resultFile := "testdata/test_newimagewithcolor.png" err := NewImageWithColor(resultFile, 10, 10, uint8(12), uint8(200), uint8(12), uint8(220), FormatPng) if err != nil { c.Error(err) } } func (*testWrapper) TestGetIcons(c *C.C) { var datas = []struct { dir string images map[string]string ret bool }{ { dir: "testdata/test-get_images", images: map[string]string{ "testdata/test-get_images/1.png": "testdata/test-get_images/1.png", "testdata/test-get_images/2.png": "testdata/test-get_images/2.png", "testdata/test-get_images/3.png": "testdata/test-get_images/3.png", }, ret: true, }, { dir: "testdata/test-get_images-noimage", images: nil, ret: true, }, { dir: "testdata/origin_icon.txt", images: nil, ret: false, }, } for _, data := range datas { icons, err := GetImagesInDir(data.dir) if data.ret { c.Check(err, C.Equals, nil) c.Check(len(icons), C.Equals, len(data.images)) for _, v := range icons { c.Check(v, C.Equals, data.images[v]) } } else { c.Check(err, C.Not(C.Equals), nil) c.Check(len(icons), C.Equals, 0) } } } func (*testWrapper) TestSniffImageFormat(c *C.C) { var datas = []struct { file string formatName string }{ { file: "testdata/origin_1920x1080.jpg", formatName: "jpeg", }, { file: "testdata/origin_icon.bmp", formatName: "bmp", }, { file: "testdata/origin_icon.gif", formatName: "gif", }, { file: "testdata/origin_icon_1_48x48.png", formatName: "png", }, { file: "testdata/origin_not_image", formatName: "", }, { file: "testdata/sniff_format.tiff", formatName: "tiff", }, } for _, data := range datas { formatName, err := SniffImageFormat(data.file) c.Check(err, C.Equals, nil) c.Check(formatName, C.Equals, data.formatName) } } go-lib-5.6.0.9/graphic/hsv.go000664 000000 000000 00000003677 13753517240 015612 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "math" ) // Rgb2Hsv convert color format from RGB(r, g, b=[0..255]) to HSV(h=[0..360), s,v=[0..1]). func Rgb2Hsv(r, g, b uint8) (h, s, v float64) { fr := float64(r) / 255 fg := float64(g) / 255 fb := float64(b) / 255 max := math.Max(math.Max(fr, fg), fb) min := math.Min(math.Min(fr, fg), fb) d := max - min if max == 0 { s = 0 } else { s = d / max } v = max if max == min { h = 0 } else { switch max { case fr: if fg >= fb { h = 60 * (fg - fb) / d } else { h = 60*(fg-fb)/d + 360 } case fg: h = 60*(fb-fr)/d + 120 case fb: h = 60*(fr-fg)/d + 240 } } return } // Hsv2Rgb convert color format from HSV(h=[0..360), s,v=[0..1]) to RGB(r, g, b=[0..255]). func Hsv2Rgb(h, s, v float64) (r, g, b uint8) { var fr, fg, fb float64 hi := int(math.Floor(h/60)) % 6 f := h/60 - float64(hi) p := v * (1 - s) q := v * (1 - f*s) t := v * (1 - (1-f)*s) switch hi { case 0: fr, fg, fb = v, t, p case 1: fr, fg, fb = q, v, p case 2: fr, fg, fb = p, v, t case 3: fr, fg, fb = p, q, v case 4: fr, fg, fb = t, p, v case 5: fr, fg, fb = v, p, q } r = uint8((fr * 255) + 0.5) g = uint8((fg * 255) + 0.5) b = uint8((fb * 255) + 0.5) return } go-lib-5.6.0.9/graphic/info.go000664 000000 000000 00000003711 13753517240 015732 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "image" "os" dutils "pkg.deepin.io/lib/utils" ) // GetImageSize return image's width and height. func GetImageSize(imgfile string) (w, h int, err error) { f, err := os.Open(imgfile) if err != nil { return } defer f.Close() config, _, err := image.DecodeConfig(f) return config.Width, config.Height, err } func GetSize(img image.Image) (w, h int) { w = img.Bounds().Dx() h = img.Bounds().Dy() return } // GetImageFormat return image format, such as "png", "jpeg". func GetImageFormat(imgfile string) (format Format, err error) { f, err := os.Open(imgfile) if err != nil { return } defer f.Close() _, name, err := image.DecodeConfig(f) format = Format(name) return } // IsSupportedImage check if image file is supported. func IsSupportedImage(imgfile string) bool { f, err := os.Open(imgfile) if err != nil { return false } defer f.Close() _, _, err = image.DecodeConfig(f) return err == nil } func GetImagesInDir(dir string) ([]string, error) { files, err := dutils.GetFilesInDir(dir) if err != nil { return nil, err } var images []string for _, file := range files { if !IsSupportedImage(file) { continue } images = append(images, file) } return images, nil } go-lib-5.6.0.9/graphic/new.go000664 000000 000000 00000002762 13753517240 015575 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "image" "image/color" ) // NewImageWithColor create a new image file with target size and rgba. func NewImageWithColor(dstfile string, width, height int, r, g, b, a uint8, f Format) (err error) { dstimg, err := NewWithColor(width, height, r, g, b, a) if err != nil { return } err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // NewWithColor create a new image object with target size and rgba. func NewWithColor(width, height int, r, g, b, a uint8) (dstimg *image.RGBA, err error) { dstimg = image.NewRGBA(image.Rect(0, 0, int(width), int(height))) color := color.RGBA{R: r, G: g, B: b, A: a} w, h := GetSize(dstimg) for i := 0; i < w; i++ { for j := 0; j < h; j++ { dstimg.SetRGBA(i, j, color) } } return } go-lib-5.6.0.9/graphic/rotate.go000664 000000 000000 00000003517 13753517240 016301 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "image" ) // RotateImageLeft rotate image to left side. func RotateImageLeft(srcfile, dstfile string, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return err } dstimg := doRotateImageLeft(srcimg) err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // RotateImageLeft rotate image to right side. func RotateImageRight(srcfile, dstfile string, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return err } dstimg := doRotateImageRight(srcimg) err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } func doRotateImageLeft(srcimg image.Image) (dstimg *image.RGBA) { w, h := GetSize(srcimg) dstimg = image.NewRGBA(image.Rect(0, 0, h, w)) for x := 0; x < w; x++ { for y := 0; y < h; y++ { dstimg.Set(y, w-x-1, srcimg.At(x, y)) } } return } func doRotateImageRight(srcimg image.Image) (dstimg *image.RGBA) { w, h := GetSize(srcimg) dstimg = image.NewRGBA(image.Rect(0, 0, h, w)) for x := 0; x < w; x++ { for y := 0; y < h; y++ { dstimg.Set(h-y-1, x, srcimg.At(x, y)) } } return } go-lib-5.6.0.9/graphic/save_load.go000664 000000 000000 00000003206 13753517240 016733 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "golang.org/x/image/bmp" "golang.org/x/image/tiff" "image" "image/jpeg" "image/png" "io" "os" ) // LoadImage load image file and return image.Image object. func LoadImage(imgfile string) (img image.Image, err error) { f, err := os.Open(imgfile) if err != nil { return } defer f.Close() img, _, err = image.Decode(f) return } // SaveImage save image.Image object to target file. func SaveImage(dstfile string, m image.Image, f Format) (err error) { df, err := openFileOrCreate(dstfile) if err != nil { return } defer df.Close() return doSaveImage(df, m, f) } func doSaveImage(w io.Writer, m image.Image, f Format) (err error) { switch f { case FormatPng: err = png.Encode(w, m) case FormatJpeg: err = jpeg.Encode(w, m, nil) case FormatBmp: err = bmp.Encode(w, m) case FormatTiff: err = tiff.Encode(w, m, nil) default: err = png.Encode(w, m) } return } go-lib-5.6.0.9/graphic/scale.go000664 000000 000000 00000012560 13753517240 016070 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "fmt" "image" ) // ScaleImage returns a new image file with the given width and // height created by resizing the given image. func ScaleImage(srcfile, dstfile string, newWidth, newHeight int, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return } dstimg := Scale(srcimg, newWidth, newHeight) err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // ScaleImagePrefer resize image file to new width and heigh, and // maintain the original proportions unchanged. func ScaleImagePrefer(srcfile, dstfile string, newWidth, newHeight int, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return } dstimg, err := ScalePrefer(srcimg, newWidth, newHeight) if err != nil { return } err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // ScaleImageCache resize any recognized format image file and save to cache // directory, if already exists, just return it. func ScaleImageCache(srcfile string, newWidth, newHeight int, f Format) (dstfile string, useCache bool, err error) { dstfile = generateCacheFilePath(fmt.Sprintf("ScaleImageCache%s%d%d%s", srcfile, newWidth, newHeight, f)) if isFileExists(dstfile) { useCache = true return } err = ScaleImage(srcfile, dstfile, newWidth, newHeight, f) return } // ThumbnailImage resize target image file with limited maximum width and height. func ThumbnailImage(srcfile, dstfile string, maxWidth, maxHeight int, f Format) (err error) { srcimg, err := LoadImage(srcfile) if err != nil { return } dstimg := Thumbnail(srcimg, maxWidth, maxHeight) err = SaveImage(dstfile, dstimg, f) dstimg.Pix = nil return } // ThumbnailImageCache resize target image file with limited maximum width // and height, and save to cache directory, if already exists, just // return it. func ThumbnailImageCache(srcfile string, maxWidth, maxHeight int, f Format) (dstfile string, useCache bool, err error) { dstfile = generateCacheFilePath(fmt.Sprintf("ThumbnailImageCache%s%d%d%s", srcfile, maxWidth, maxHeight, f)) if isFileExists(dstfile) { useCache = true return } err = ThumbnailImage(srcfile, dstfile, maxWidth, maxHeight, f) return } // Scale resize image object to new width and height. func Scale(srcimg image.Image, newWidth, newHeight int) (dstimg *image.RGBA) { dstimg = doScaleNearestNeighbor(srcimg, newWidth, newHeight) return } // Thumbnail resize image object with limited maximum width and height. func Thumbnail(srcimg image.Image, maxWidth, maxHeight int) (dstimg *image.RGBA) { // get new width and heigh var newWidth, newHeight int w, h := GetSize(srcimg) scale := float32(w) / float32(h) newWidth = maxWidth newHeight = int(float32(newWidth) / scale) if newHeight > maxHeight { newHeight = maxHeight newWidth = int(float32(newHeight) * scale) } return Scale(srcimg, newWidth, newHeight) } // ScalePrefer resize image object to new width and heigh, and // maintain the original proportions unchanged. func ScalePrefer(srcimg image.Image, newWidth, newHeight int) (dstimg *image.RGBA, err error) { iw, ih := GetSize(srcimg) x, y, w, h, err := GetPreferScaleClipRect(newWidth, newHeight, iw, ih) if err != nil { return } dstimg = Clip(srcimg, x, y, w, h) dstimg = Scale(dstimg, newWidth, newHeight) return } // TODO doScaleNearestNeighbor returns a new RGBA image with the given width and // height created by resizing the given image using the nearest neighbor // algorithm. func doScaleNearestNeighbor(img image.Image, newWidth, newHeight int) (newimg *image.RGBA) { w := img.Bounds().Max.X h := img.Bounds().Max.Y newimg = image.NewRGBA(image.Rect(0, 0, newWidth, newHeight)) xr := (w<<16)/newWidth + 1 yr := (h<<16)/newHeight + 1 for yo := 0; yo < newHeight; yo++ { y2 := (yo * yr) >> 16 for xo := 0; xo < newWidth; xo++ { x2 := (xo * xr) >> 16 newimg.Set(xo, yo, img.At(x2, y2)) //Much faster, but requires some image type. //newimg.Pix[offset] = img.Pix[y2*w+x2] //offset++ } } return newimg } // GetPreferScaleClipRect get the maximum rectangle in center of // image which with the same scale to reference width/heigh. func GetPreferScaleClipRect(refWidth, refHeight, imgWidth, imgHeight int) (x, y, w, h int, err error) { if refWidth*refHeight == 0 || imgWidth*imgHeight == 0 { err = fmt.Errorf("argument is invalid: %d, %d, %d, %d", refWidth, refHeight, imgWidth, imgHeight) return } scale := float32(refWidth) / float32(refHeight) w = imgWidth h = int(float32(w) / scale) if h < imgHeight { offsetY := (imgHeight - h) / 2 x = 0 y = 0 + offsetY } else { h = imgHeight w = int(float32(h) * scale) offsetX := (imgWidth - w) / 2 x = 0 + offsetX y = 0 } return } go-lib-5.6.0.9/graphic/testdata/000775 000000 000000 00000000000 13753517240 016257 5ustar00rootroot000000 000000 go-lib-5.6.0.9/graphic/testdata/origin_icon.bmp000664 000000 000000 00000022212 13753517240 021255 0ustar00rootroot000000 000000 BM$|00 $  BGRs`ttsssssssssssssssssssssssssssssssssst`txwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwxzzzzzzzzzzzyyyyyyzzzzzzzzzzzzzzzzzzzzzzzzz`}}}}}}}}}|{{zzzzzz{||}}}}}}}}}}}}}}}}}}}}}}`}~}{zyxwwxz{}ȀɁɁȁŁ€}zvsqonoguN R9@."""#D0 Z=WxȄÃ~ytnifemLB1 " !   !!"####P8`ɇƉ‰‰zrja]lL5)FA40" !  !"#####D1nLjˆˆ‰‰‰‰‰‰‰ČČË‹}sh]j4LZ\Q0yu 1- !"#####" yTȊ‰‹ËËČČČČČƏƏŎÍwjg '(xo:D#K&A$7"'###""" cEȊŒčŎŏƏƏƏƏǒǒƑďr o  I#T(],d/c0O*, #"!   `DÊÏƑƑǒǒǒǒɕɕȔđ}l u]L$X)`.f0i1e1A&" [BŒȔɕɕɕɕ˘ʘɗŔ} } ½F!S'],d/h1i2h1L($$ eÒȖʗʘ˘˘̛͛˚Ǘ! þ ľƾ Ƽ^AN%Y*b.g1i1h1f0M(G= 'Ǘ˚̛͛͛ΞΞ͝ɚ)=951.+'%!˾̿~V1W+_-e0h1h1g0c.B$k[ [U mQƘ̝͝ΞΞϠϠΟ˝ÖYSLKJLOMF@=9630 gG rK pAc/h1i1h1d/_-4# *$'ė˝ΟϠϠϠϠΟ̞ș fDJYvhRMKIG" }a oJ U |Kg1i1h1f0a.K&VJyu `ɜΟϠϠϠϠϠΟϝXC=9ɾG^kUUVJ  hE xP Z ~Kh1i1g1c/\+.!"N;ǚ͞ΟϠϠϠϠϟ՟-$!<7GmdMNCjLê lM rL V_s=h1h1d/\+; OK&ƙ̞ΟϠϠϠϠР""!O'|[y8><4)˘͞ΟϠϠϠϠϠϠӡhO###, j2j2j2j2j2 |Ffffffea [ {R 66y;HE?EA`I̛ΟΟϠϠϠϠϠϠѠ x####O*j2j2j2j2j2 |Fffffec^ Vi* ľ7 yAROL! r͝ΟϠϠϠϠϠϠϠРء;.###, f1j2j2j2j2j2v? Yfffda Z oF L\YV?%!7+ϜΞΟϠϠϠϠϠϠϠϠӡ p####>%j2j2j2j2j2j2j2s< I L K zFi6X)m1^fc`XEA  lϞΟϠϠϠϠϠϠϠϠϠРءF6####>%j2j2j2j2j2j2j2j2j2j2g1c/[+]8.Hmkh|B4ѝΟΟϠϠϠϠϠϠϠϠϠϠҠ/%####>%j2j2j2j2j2j2j2j2j2h1e0_-U(,%nnE#+#ϞΟϠϠϠϠϠϠϠϠϠϠϠϠӡ p#####0!].j2j2j2j2j2j2j2i2g0a.Y*v]5_neb j͝ΟϠϠϠϠϠϠϠϠϠϠϠϠϠРԡ p######>%T+j2j2j2j2j2j2h1d/I&/0%=Z,) f˚͞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠРա p#######'5"G(G(G(G(4"&  ='N }]Óɛ͞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРӡ;.############"!97>$8 lɜΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠӠΙ `############" $30 ė˝ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠѠա‘ _:.#########"7+ tW 60Ț̞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРҠա p _Q>Q>Q>Q> _ oϝǘƙ˝ΟΟϠϠϠϠϠϠϠ`ϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРѠҠӠӠӠӠҠѠϟ͞˜țǚǚț˝͟ΟϠϠϠϠϠϠϠ`ϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠΟΟΟ͞͞ΟΟΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠΟΟΟΟϠϠϠϠϠϠϠϠϠϠ`ϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠ`Ϡgo-lib-5.6.0.9/graphic/testdata/origin_icon.gif000664 000000 000000 00000004223 13753517240 021246 0ustar00rootroot000000 000000 GIF89a00 "!"$% (&(,&-0"/#48 702 *6(6;0:98'>A8<%B9= D0A /E&H4D!K&NAE >G*R0Q%U7R=Q+YMO.\)_GW7]>[+a/d2fAa V\Db,iIa.k6j 0l Ch Qg=oGl8rMkOl`fJnEp[kJt @xYrNw[wL| F~ R{ Z|Vc}^ryTOwy[] ZkcbnYy`ljz_fcieqy o}unn tq}v ~ |+qy{x  } } 4$ #()+ !N!8Y'4# @ .&L'F>GHP+)8;e>GQ8KEVFfW*zkC:VN_fo!Created with GIMP! ,00 H*\ȰB[#JHE3jőVƃCN+VNjENŲ%K[%]t5G)U Q)*-VZb5cE"y~bիW LP5HhޜU#XS:@@*oAb:VbYU]yQغRՆo "x`@1ᮑ0+8m Sk)$b[#2V۠2V0-?"MVJDb U/Z BҩAgOL! NzA8aN찂N? 1]E^,@oA|Ƈj}m0p7樣OL1q@%9tb^jAH!K-JtA\ϑb`jVc^HSL#5 ;0 &K XfZ,ȕg &p1ش@]ij<#HD ( ;yd)WFChD+O!M0y?Ђ 'L# A׫F 4!<"QJ00QDa`]CMU EYT!qOLA._o\aR_0E&ٰ9$GHq2QaXn \|,#0 *CO>ӏ:ds:Z{ ,U]0dhCO<0~i ?A?3 ?CX0AĀ0 HS8 <JH, n L|‰h4EM (i P?x l  @F3h$( MDiqc,c($ PKJhL" RV,$ 0@'S@ WӘ<&,:! iHMP+)C1J$ !:Al@B 8u|ELJ;;)KȪG>85S=a\z|McjR|8K)Pk!u,)VHڱZ<jbt\y3^t}>݆-=!e?:'B@@2w(jh;&p:r)/$>(w T/A9nÿd7lн'xyPFWC˖!J*4G!@?u j;ehO}}}z{|nٽ#<2|cV*?$\T.Dj}a jWW,mwT 68vlXbn׿z5 6~ g»p:Z1ع=&sfm`kǙPY^xW\O"~ ;\2hD1|rnqCiP&a{_pUplv/s+6o 2??[Taw!rIɧQyKHٱɑo5\'(@P'?yMg3t-M#0~.;t.'u!ݛG滖LA yxD%R, M%4k,3gQ~*џGK ǜ *d?'U^ƒ'\: 6ReWե\FQ*UlQEߢK%3yeρΞYMHqU-͜.iKTTrmL:B|TQiCXx3Sxϳ/xJ)k&PZ#8YNEW0^B9JJG.ۇ7,S>-$(VĀxGq*nsGϩ*+x0;ȑDN JŌ^4mP.CE(u};|=^=Mo+]NGo?m׋] n.s9AC l{PyoR=ZZ?ӖbZȜrϐarț;Rk!PK+}*OX۹ =F 3W54R#8PGNlx WdcFb)Ѵ ׈"|'# TB6!=hQ|uA@=uTCZEFEP[mԜul+=cvĉSrdIpu{A%=y~L gcTcƨVƨQI0crZgbL.ɁT;O>wo_Ȑ/$V*V6u[*1+N_ [PgXTDOnXIʥIpR //^p5%"|hc (%DgO[A+7&Ou/IzLps&ftBȴ Ƨ<߱| 񃿱/ \GNB*b9-m. S>I#R-$i2`҉J@c߱pաw.Cd%p>iRK)gxl` W|%٥U8ξ!hI,T+ UDz ⁊`] +8B7K[xx{H% ""X;ɉWyŕ-p xFѺuǡ#YJ T;i4B&7(N8yɧmqNm[عo@_@úNHZԢ rUA%iJEWBO_ҙKl٨LO SSMWΝɧL5ZBj+~E ݉9J9*o3~1b|Ni(4Z]o[ hshXVkA%IB '] );/ܸ1?eN6 x  >eu$avN~#x0yޓD!Nb~Zff +\YYù" KGςo=A^^{k߽r]+۞T?O~/_±sue35*P~mkzn vXr=!>lu?}z~"pt߃WI<9(xWqhq}y 26Yh6;Z] A\(%T҈{/<=C%F!k{?'6AF9|hqs:V~jūz[t[t}.~V:pώ'D@ltiu|L_|?>+K{t}Og4=:>[[>Tƽ!n{Zd,'O+ʕMpEtx>tz-q1~OQV[|a.|q| n8enfxQJPJDP  !2Og~<fk?rcB 2B%F5*mw;=Gk}?ww}3kZ|X8w Y!!x@{ xp.[u(yp^_Z|FV7Wd&BY cv)e4M'y}΋/lp\ٜsJ{D {: c47X\\/}bJ,?+hXYnL TAFإ@KdyZI9vb?+ rr.hse0X貱dmMy\+<.xE GyUĻ  r,g8zl+MZ@THe;)R健U~辰;o♧_e: C²@C!/;¼sg!BzMZ.DG@BpM@$Js9 Z}ur8h^_D6\)ݣ )W/E [F~oQk K@ G0e _@lJ)h.+c\Gln"FS FSV)- U@LFC+5C*ZMɜczn J(2d/E{Ԧ3%VFU (AT@| ˅zpbKVJ#ZEi h=ƞW:Ul =m!4Ң ٢CR' Z)B!`5ԫHQ!85T*zk qkwM J !8$ٹw}VQla!^ .J֦ULT x"v\)y.\LMBAeJSUc<#Mg ]d5*"]OAbػM{sjv+ʶYZ}@| rs1(6ĐNT)i¡%1I'1 bHl sIl $ #YJk!B%ջк(i"x牬 9>C_4`!I\K:[CmF} DiLZMLUi@%UU,QGG[҉ PI!]VȨy3DVu8|l^;Z!IlETiJ^efviԦ$=T"TqT.K%ɪT(HDF{(h#OYՂ1ĩ>FdaznLMIk)q%:UƖpyBo4Vh-t$<"1LĪU1V PT--^wgd$0W"* $F^&]:Byd޽8d&-KVPCHkX~"V}'Qm5#K ou8i譓&nwjAAJ 2^ *)Ch0r ޘ1]oOr'a**h~εk57h//GŪT#Hц Rt-A@D#bv:Ab˸Ԫ0/bmq`ijH*XEB)"eʢ&c"C;J#z|f5щŚZ+/%R_:U$c FVD$RS#FѦlȜ Q|*^NA١<,gZ?ܿ*%xYlTRCQKC2tt>JTآCf 2|]|)Nyh<45qxTg؄+WTq+..7+8r0oeZހ,Of/]d22o m8!bI88ɽ犫we/\"T7̲,Z5[=ӏƹ@6~*2LҸBd"yrpy P9RJu{9+,,,ED).Ny^xXJ z>t+\^@^'֙qsr;'ʋ|ɳVj啫?Nh0LR~^^ަWRPT1QHq42BOݦjm ƀ#1fۻGldV%ѶevǾXD[j Z Qbߒ:5VؽBH[6Ȳ}z5%mhN w}wsfCsfhm&7Fi67b`(ö?w?p}Y.QpsnxW@ d$@{;N~~ !dt;/^*/f(W-{wѺpJy?~sޡ&b676yɧ{/}s/?`}O?zD!|.-ڕE` lL*0WRR$MM\㟴mѶ|t?i47qZ>q̀,>T`xRƗ a؛a;I$p$||lH2 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package graphic import ( "image" "image/draw" "os" "pkg.deepin.io/lib/utils" ) func generateCacheFilePath(keyword string) (dstfile string) { return utils.GenerateCacheFilePathWithPrefix("graphic", keyword) } func openFileOrCreate(file string) (*os.File, error) { return os.OpenFile(file, os.O_WRONLY|os.O_CREATE, 0644) } func isFileExists(file string) bool { if _, err := os.Stat(file); err == nil { return true } else { return false } } // convert image.Image to *image.RGBA func convertToRGBA(img image.Image) (rgba *image.RGBA) { b := img.Bounds() r := image.Rect(0, 0, b.Dx(), b.Dy()) rgba = image.NewRGBA(r) draw.Draw(rgba, rgba.Bounds(), img, b.Min, draw.Src) return } go-lib-5.6.0.9/gsettings/000775 000000 000000 00000000000 13753517240 015040 5ustar00rootroot000000 000000 go-lib-5.6.0.9/gsettings/monitor.go000664 000000 000000 00000005756 13753517240 017073 0ustar00rootroot000000 000000 package gsettings import ( "path" "strings" "sync" "github.com/godbus/dbus" ) func addMatch(bus *dbus.Conn, rule string) error { err := bus.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule).Err return err } func initBus() (*dbus.Conn, error) { bus, err := dbus.SessionBus() if err != nil { return nil, err } err = addMatch(bus, "type='signal',sender='ca.desrt.dconf',path='/ca/desrt/dconf/Writer/user',interface='ca.desrt.dconf.Writer',member='Notify'") if err != nil { return nil, err } return bus, nil } type changedCallback struct { all bool fns []ChangedCallbackFunc } type ChangedCallbackFunc func(key string) func toPath(schemaOrPath string) string { if schemaOrPath[0] == '/' { // is path if schemaOrPath[len(schemaOrPath)-1] == '/' { schemaOrPath = schemaOrPath[:len(schemaOrPath)-1] } return schemaOrPath } // is schema id return "/" + strings.Replace(schemaOrPath, ".", "/", -1) } var changedCallbackMap map[string]*changedCallback var changedCallbackMapMu sync.RWMutex func ConnectChanged(schemaOrPath, key string, fn ChangedCallbackFunc) { if schemaOrPath == "" || key == "" { return } var all bool if key == "*" { all = true } keyPath := toPath(schemaOrPath) if !all { keyPath += "/" + key } //log.Println("ConnectChanged", keyPath) changedCallbackMapMu.Lock() if changedCallbackMap == nil { changedCallbackMap = make(map[string]*changedCallback) } callback, ok := changedCallbackMap[keyPath] if ok { if callback.all == all { callback.fns = append(callback.fns, fn) } } else { changedCallbackMap[keyPath] = &changedCallback{ all: all, fns: []ChangedCallbackFunc{fn}, } } changedCallbackMapMu.Unlock() } var started bool var startedMu sync.Mutex func StartMonitor() error { startedMu.Lock() defer startedMu.Unlock() if started { return nil } bus, err := initBus() if err != nil { return err } signalCh := make(chan *dbus.Signal, 10) bus.Signal(signalCh) go func() { for signal := range signalCh { if signal.Name == "ca.desrt.dconf.Writer.Notify" && signal.Path == "/ca/desrt/dconf/Writer/user" { if len(signal.Body) == 3 { keyPath, ok := signal.Body[0].(string) if !ok { continue } subPathList, ok := signal.Body[1].([]string) if !ok || len(subPathList) == 0 { handleSignal(keyPath) } else { for _, subPath := range subPathList { handleSignal(keyPath + subPath) } } } } } }() started = true return nil } func handleSignal(keyPath string) { parent, key := path.Split(keyPath) if parent == "" || key == "" { return } if parent[len(parent)-1] == '/' { parent = parent[:len(parent)-1] } changedCallbackMapMu.RLock() callback := changedCallbackMap[parent] if callback != nil && callback.all { for _, fn := range callback.fns { go fn(key) } } callback = changedCallbackMap[keyPath] if callback != nil && !callback.all { for _, fn := range callback.fns { go fn(key) } } changedCallbackMapMu.RUnlock() } go-lib-5.6.0.9/imgutil/000775 000000 000000 00000000000 13753517240 014503 5ustar00rootroot000000 000000 go-lib-5.6.0.9/imgutil/format_sniff.go000664 000000 000000 00000001776 13753517240 017522 0ustar00rootroot000000 000000 package imgutil import ( "bufio" "os" ) type format struct { name, magic string } // image formats: var formats = []format{ {"jpeg", "\xff\xd8"}, {"bmp", "BM????\x00\x00\x00\x00"}, {"png", "\x89PNG\r\n\x1a\n"}, {"tiff", "MM\x00\x2A"}, // little-endian {"tiff", "II\x2A\x00"}, // big-endian {"gif", "GIF8?a"}, } // Sniff determines the format of r's data. func sniff(r *bufio.Reader) format { for _, f := range formats { b, err := r.Peek(len(f.magic)) if err == nil && match(f.magic, b) { return f } } return format{} } // Match reports whether magic matches b. Magic may contain "?" wildcards. func match(magic string, b []byte) bool { if len(magic) != len(b) { return false } for i, c := range b { if magic[i] != c && magic[i] != '?' { return false } } return true } func SniffFormat(file string) (string, error) { fh, err := os.Open(file) if err != nil { return "", err } defer fh.Close() reader := bufio.NewReader(fh) format := sniff(reader) return format.name, nil } go-lib-5.6.0.9/imgutil/imgutil.go000664 000000 000000 00000003457 13753517240 016515 0ustar00rootroot000000 000000 package imgutil import ( "bufio" "image" _ "image/gif" _ "image/jpeg" "image/png" "os" _ "golang.org/x/image/bmp" _ "golang.org/x/image/tiff" "pkg.deepin.io/lib/gdkpixbuf" "pkg.deepin.io/lib/strv" ) const ( FormatGIF = "gif" FormatJPEG = "jpeg" FormatPNG = "png" FormatBMP = "bmp" FormatTIFF = "tiff" ) var supportedFormats = strv.Strv([]string{FormatGIF, FormatJPEG, FormatPNG, FormatBMP, FormatTIFF}) func GetSupportedFormats() strv.Strv { return supportedFormats } func Load(filename string) (image.Image, error) { img, err := loadViaGdkPixbuf(filename) if err == nil { return img, nil } return loadCommon(filename) } func loadCommon(filename string) (image.Image, error) { fh, err := os.Open(filename) if err != nil { return nil, err } defer fh.Close() br := bufio.NewReader(fh) img, _, err := image.Decode(br) return img, err } func loadViaGdkPixbuf(filename string) (image.Image, error) { pb, err := gdkpixbuf.NewPixbufFromFile(filename) if err != nil { return nil, err } img, err := gdkpixbuf.ToImage(pb) gdkpixbuf.FreePixbuf(pb) return img, err } func SavePng(img image.Image, filename string, enc *png.Encoder) error { fh, err := os.Create(filename) if err != nil { return err } defer fh.Close() bw := bufio.NewWriter(fh) if enc == nil { enc = &png.Encoder{} } err = enc.Encode(bw, img) if err != nil { return err } err = bw.Flush() return err } func IsSupported(filename string) bool { format, err := SniffFormat(filename) if err != nil { return false } if supportedFormats.Contains(format) { return true } return false } func CanDecodeConfig(filename string) bool { fh, err := os.Open(filename) if err != nil { return false } defer fh.Close() reader := bufio.NewReader(fh) _, _, err = image.DecodeConfig(reader) return err == nil } go-lib-5.6.0.9/imgutil/imgutil_test.go000664 000000 000000 00000003402 13753517240 017542 0ustar00rootroot000000 000000 package imgutil import ( "image" "image/png" "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" ) func TestLoad(t *testing.T) { for _, name := range []string{"deepin-music.bmp", "deepin-music.gif", "deepin-music.jpg", "deepin-music.png", "deepin-music.tiff"} { filename := filepath.Join("testdata", name) img, err := Load(filename) if assert.Nil(t, err) { assert.Equal(t, image.Rect(0, 0, 48, 48), img.Bounds()) } } } func TestIsSupported(t *testing.T) { for _, name := range []string{"deepin-music.bmp", "deepin-music.gif", "deepin-music.jpg", "deepin-music.png", "deepin-music.tiff"} { filename := filepath.Join("testdata", name) assert.True(t, IsSupported(filename), "should support "+name) } } func TestCanDecodeConfig(t *testing.T) { for _, name := range []string{"deepin-music.bmp", "deepin-music.gif", "deepin-music.jpg", "deepin-music.png", "deepin-music.tiff"} { filename := filepath.Join("testdata", name) assert.True(t, CanDecodeConfig(filename), "should decode config ok "+name) } } func TestSniffFormat(t *testing.T) { for _, ext := range []string{"bmp", "gif", "png", "tiff"} { filename := "testdata/deepin-music." + ext format, err := SniffFormat(filename) if assert.Nil(t, err) { assert.Equal(t, ext, format) } } format, err := SniffFormat("testdata/deepin-music.jpg") if assert.Nil(t, err) { assert.Equal(t, "jpeg", format) } } func TestSavePng(t *testing.T) { img, err := Load("testdata/deepin-music.png") if assert.Nil(t, err) { err = SavePng(img, "testdata/out1.png", nil) assert.Nil(t, err) os.Remove("testdata/out1.png") err = SavePng(img, "testdata/out2.png", &png.Encoder{ CompressionLevel: png.NoCompression, }) assert.Nil(t, err) os.Remove("testdata/out2.png") } } go-lib-5.6.0.9/imgutil/testdata/000775 000000 000000 00000000000 13753517240 016314 5ustar00rootroot000000 000000 go-lib-5.6.0.9/imgutil/testdata/deepin-music.bmp000664 000000 000000 00000015466 13753517240 021412 0ustar00rootroot000000 000000 BM66(00  ttssssssssssssssssssssssssssssssssssttxwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwxzzzzzzzzzzzyyyyyyzzzzzzzzzzzzzzzzzzzzzzzzz}}}}}}}}}|{{zzzzzz{||}}}}}}}}}}}}}}}}}}}}}}}~}{zyxwwxz{}ȀɁɁȁŁ€}zvsqonoguN R9@."""#D0 Z=WxȄÃ~ytnifemLB1 " !   !!"####P8`ɇƉ‰‰zrja]lL5)FA40" !  !"#####D1nLjˆˆ‰‰‰‰‰‰‰ČČË‹}sh]j4LZ\Q0yu 1- !"#####" yTȊ‰‹ËËČČČČČƏƏŎÍwjg '(xo:D#K&A$7"'###""" cEȊŒčŎŏƏƏƏƏǒǒƑďr o  I#T(],d/c0O*, #"!   `DÊÏƑƑǒǒǒǒɕɕȔđ}l u]L$X)`.f0i1e1A&" [BŒȔɕɕɕɕ˘ʘɗŔ} } ½F!S'],d/h1i2h1L($$ eÒȖʗʘ˘˘̛͛˚Ǘ! þ ľƾ Ƽ^AN%Y*b.g1i1h1f0M(G= 'Ǘ˚̛͛͛ΞΞ͝ɚ)=951.+'%!˾̿~V1W+_-e0h1h1g0c.B$k[ [U mQƘ̝͝ΞΞϠϠΟ˝ÖYSLKJLOMF@=9630 gG rK pAc/h1i1h1d/_-4# *$'ė˝ΟϠϠϠϠΟ̞ș fDJYvދޏނhRMKIG" }a oJ U |Kg1i1h1f0a.K&VJyu `ɜΟϠϠϠϠϠΟϝXC=9ɾG^ކ޾خݎkUUVJ  hE xP Z ~Kh1i1g1c/\+.!"N;ǚ͞ΟϠϠϠϠϟ՟-$!<7Gmߎޝ߄dMNCjLê lM rL V_s=h1h1d/\+; OK&ƙ̞ΟϠϠϠϠР""!O'|[y8><4)˘͞ΟϠϠϠϠϠϠӡhO###, j2j2j2j2j2 |Ffffffea [ {R 66y;HE?EA`I̛ΟΟϠϠϠϠϠϠѠ x####O*j2j2j2j2j2 |Fffffec^ Vi* ľ7 yAROL! r͝ΟϠϠϠϠϠϠϠРء;.###, f1j2j2j2j2j2v? Yfffda Z oF L\YV?%!7+ϜΞΟϠϠϠϠϠϠϠϠӡ p####>%j2j2j2j2j2j2j2s< I L K zFi6X)m1^fc`XEA  lϞΟϠϠϠϠϠϠϠϠϠРءF6####>%j2j2j2j2j2j2j2j2j2j2g1c/[+]8.Hmkh|B4ѝΟΟϠϠϠϠϠϠϠϠϠϠҠ/%####>%j2j2j2j2j2j2j2j2j2h1e0_-U(,%nnE#+#ϞΟϠϠϠϠϠϠϠϠϠϠϠϠӡ p#####0!].j2j2j2j2j2j2j2i2g0a.Y*v]5_neb j͝ΟϠϠϠϠϠϠϠϠϠϠϠϠϠРԡ p######>%T+j2j2j2j2j2j2h1d/I&/0%=Z,) f˚͞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠРա p#######'5"G(G(G(G(4"&  ='N }]Óɛ͞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРӡ;.############"!97>$8 lɜΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠӠΙ `############" $30 ė˝ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠѠա‘ _:.#########"7+ tW 60Ț̞ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРҠա p _Q>Q>Q>Q> _ oϝǘƙ˝ΟΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠРѠҠӠӠӠӠҠѠϟ͞˜țǚǚț˝͟ΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠΟΟΟ͞͞ΟΟΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠΟΟΟΟϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠϠgo-lib-5.6.0.9/imgutil/testdata/deepin-music.gif000664 000000 000000 00000004234 13753517240 021370 0ustar00rootroot000000 000000 GIF89a00#! /9"",&*"5*6$=.;-1 7;9=04)5B$C(G$K)N.@3D8H'R)U,\1S=Q;\ 9X/c1f2j:m=t9pDHB[FYV[AFDc Fk Kl FfVlMs F{ J~ Ap \t\{S{ ^~ Wt LmNubeg{uy L V Z ]]` j e m ywcm fp r | fihr|{ons{z||szw{~      !0,¾ ,  $(,!%)2;7768,%=;,DGL[QLCFJHKVW^LETZjivlc!! ImageMagick gamma=0.45455,00 H*\ȰK#JHE3j(I'Aܴ#GIQ^,R"I^NB) MH&+ܸ5Mzxǒ5 =jcfIA|X*ѦV-2))h0dV68W Hմx8V5RK%Wb=c  o28Hx"&i'lAȂu+Ep%h p0]Zo6jR&K6G=Md6[XI%嗘o!9|piTcI;mK1Cƈ Eb3L2'Lfb 2D4bJ)|c`3 7RYi R@J)$-, !5r&B@+Q@7. 3BX@'w @i&(Ѣ0I)0$.XBT$YVcy| TPfKؑSgo}Z wI-İXP .uBzFV"8t %.phPABƩ8u*"& BK4o! k1%6# *`ۄvrU! D@ |CpCBAcG#M Ђ 2Ar -C! M5<_#1 C dBJ@Z Iwl 6`c3$0b11o"{%ASYns$F1$ 5DL2b+|.k)D<@) }2 -Ӣ)/PAiqkA*Abi,"|+?(dl nM(*҄$DbH"#2QI%TBvZ"Fk$}$Ї~8D{8PX@b(d0G{#搅(A~H0~' @(C?>bsp>|k0 h \"EXqb +0U0򕱌h |P T` 1+v",@ = ! `>zTAEHҒtC (@X @/#,KZ$&/X R.0^YViI9$Af2 n)\ V0 |\f3fS Z~ ^0ag9~ҡ T:Ixn_(A 2 5=P!廊EщRΒ_JWҒ* 0LgJӚ!8ͩNwӁ;go-lib-5.6.0.9/imgutil/testdata/deepin-music.jpg000664 000000 000000 00000004443 13753517240 021405 0ustar00rootroot000000 000000 JFIFC       C 00= !12AQq"#8a3BWcr? !1Aaq2BQ"3Rr#6$4ST ?Ch:mmSu6V-uaCAņu|vqHZ{sxpP9@MV]%J)Eh+a t֫)*˜|{ 25PWa!퀻BgI\+$.R85%ye(%G<ۺ!EQIp4qҥ` +R q!·3(QLKۈE*࿞kҍfŸg ŐbNif( &{'gF4 0i]ฐoY'8'0- W7vҶ'QzaB7rkW56<פqR*HIaC.\+wU3Rm1;N2ideU ^{~ҡqmN44/Q8b ia˗\^PL>*tAʛjhfMOdƘHRyGpGPxR ġ G`WJ)ͪFmѽG zڔVhSQQ~'d #<䅪ܽn%GrٕiR[0׭-ԭ'/ShVB"M:G=4q;^1 ]q3?w >"Ә^#2z&̙8XaGP+ǩ'?w ʻMQ`l&Sc?XTw%=ڬj\-/|Z7"'Ĥz ojG_0¼ܒGGG1r<R'}*Nq} O:~}Oߓ=}Q{ mþFg&r2-\GP}^L(Rx8ܻ=fOB|` $)SJ4* @ʚݑu9rgo-lib-5.6.0.9/imgutil/testdata/deepin-music.png000664 000000 000000 00000006246 13753517240 021414 0ustar00rootroot000000 000000 PNG  IHDR00WgAMA asRGB cHRMz&u0`:pQ<bKGD pHYs   vIDATh]lu~)Dꃢ胖]+G6 җ&[}OnA~p"Mj;H+UAZeٖDIQIK{0%_rgϹށGkΧc5F>8u|ELJ;;)KȪG>85S=a\z|McjR|8K)Pk!u,)VHڱZ<jbt\y3^t}>݆-=!e?:'B@@2w(jh;&p:r)/$>(w T/A9nÿd7lн'xyPFWC˖!J*4G!@?u j;ehO}}}z{|nٽ#<2|cV*?$\T.Dj}a jWW,mwT 68vlXbn׿z5 6~ g»p:Z1ع=&sfm`kǙPY^xW\O"~ ;\2hD1|rnqCiP&a{_pUplv/s+6o 2??[Taw!rIɧQyKHٱɑo5\'(@P'?yMg3t-M#0~.;t.'u!ݛG滖LA yxD%R, M%4k,3gQ~*џGK ǜ *d?'U^ƒ'\: 6ReWե\FQ*UlQEߢK%3yeρΞYMHqU-͜.iKTTrmL:B|TQiCXx3Sxϳ/xJ)k&PZ#8YNEW0^B9JJG.ۇ7,S>-$(VĀxGq*nsGϩ*+x0;ȑDN JŌ^4mP.CE(u};|=^=Mo+]NGo?m׋] n.s9AC l{PyoR=ZZ?ӖbZȜrϐarț;Rk!PK+}*OX۹ =F 3W54R#8PGNlx WdcFb)Ѵ ׈"|'# TB6!=hQ|uA@=uTCZEFEP[mԜul+=cvĉSrdIpu{A%=y~L gcTcƨVƨQI0crZgbL.ɁT;O>wo_Ȑ/$V*V6u[*1+N_ [PgXTDOnXIʥIpR //^p5%"|hc (%DgO[A+7&Ou/IzLps&ftBȴ Ƨ<߱| 񃿱/ \GNB*b9-m. S>I#R-$i2`҉J@c߱pաw.Cd%p>iRK)gxl` W|%٥U8ξ!hI,T+ UDz ⁊`] +8B7K[xx{H% ""X;ɉWyŕ-p xFѺuǡ#YJ T;i4B&7(N8yɧmqNm[عo@_@úNHZԢ rUA%iJEWBO_ҙKl٨LO SSMWΝɧL5ZBj+~E ݉9J9*o3~1b|Ni(4Z]o[ hshXVkA%IB '] );/ܸ1?eN6 x  *V@S% 住ydg9^dfwfg>|߾kmݮ[H6K%Πo1gIcȎS&cرKϠS_ LJlLk3`6~Y o۱af9LI*:lue9+#. 0 =8|q;Ц33;&vDPwlgdǠK(-10Ȑm!AOo;)~V5T>)kϳOt{@u;Kp>8##AU6b^0 JV= OHPg=wO}#|ex$hi47z1jx&L ǹq? ,]n2\]$$ 1 僑K)G&OK]pYoaOw?XSfLNq"J(U[x)dW:~;il~t#a\0 lޏWfphO1"!rkr0$b ⚪C07$1g.OEZ%C~zA*g. K;~aͽMqxOVA!~&~nhM{:*C!x 4ՙln'^=S֗bB 0n';NCJG>g-w|A[2ȓ1ps€^NH0vvB|:Gb@4 o>mU\̇>p(h ??RŰfA( ވ@nT GhcO6P;ԉC̺eĨc aw$|vHJ1Ikz~CqW3S1ib ^҄EWZh5O}ٸ ݜ$r{'k(VqJS/eЖI96[ _hen̟WEa\wo3䷇g6ZZLe ,a¨|9;i”PQQOb k(v#7Ral'GO9PN2bZn,5!?עJ}YWobsMz$>%@z0SaL A76UT֩xy ZҒ&-W['=JufM"/;[Rͦ&4_K 5?#l'źJǒi&Q4b;"tLӝui$2'VRnNڇm]n;,6s~>ne! hD-8d^Y1,_WT;);R,k'\ɐ1.7v}U&/qa,/ԲX?2؎K O҈l4084 H| $"<čÑ>8&F|͊zb-s;F1nvI˲b[bmkl߬|/?hhq\K*qxQ=r(tˌ>Ȏ4qlP,z/M^?4)73~z=1/MGǸq\?.ֹ*^7hŻ]Z TƉ=H9pB9bbpTf!6,уL#'{֭ATWqMFa"ԯ֣yïI^P(n]o^l王m>vWzׯx7F:2iPV[Dy'<;DNPU@ 4vX[<ocAbESF(o#pnͽbe֚gGrnTO+H9[KĶD[:ƿͼ6X˟F؈y"-<7Pʌ83V-}#KxW%{_k&k3↓r]Kwx,0I|8km*K 7Lةo<8tZ -񝰃+&VYoŒ[00  0   ()=>.? R   ףzTLff&(\ PW9Tgo-lib-5.6.0.9/initializer/000775 000000 000000 00000000000 13753517240 015354 5ustar00rootroot000000 000000 go-lib-5.6.0.9/initializer/initializer.go000664 000000 000000 00000004037 13753517240 020232 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package initializer // TODO: // 1. a Promise like initializer might be better. // 2. using reflect to support different initializer. // Initializer is a chainable initializer. Init/InitOnSystemBus/InitOnSystemBus will accept a initializer, // and then pass the successful return value to the next initializer. If error occurs, the rest initializers // won't be executed any more. GetError is used to access the error. type Initializer struct { v interface{} e error } // NewInitializer creates a new Initializer. func NewInitializer() *Initializer { return new(Initializer) } func noop(v interface{}) (interface{}, error) { return v, nil } func (i *Initializer) initWithHandler(fn func(interface{}) (interface{}, error), handler func(interface{}) (interface{}, error)) *Initializer { if i.e != nil { return i } var err error var v interface{} v, err = fn(i.v) if err != nil { i.e = err return i } v, err = handler(v) if err != nil { i.e = err } i.v = v return i } // Init accepts a initializer function, and pass the successful return value to next initializer. func (i *Initializer) Init(fn func(interface{}) (interface{}, error)) *Initializer { return i.initWithHandler(fn, noop) } // GetError returns the first error of initializers. func (i *Initializer) GetError() error { return i.e } go-lib-5.6.0.9/initializer/initializer_test.go000664 000000 000000 00000003412 13753517240 021265 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package initializer_test import ( "errors" "testing" . "github.com/smartystreets/goconvey/convey" . "pkg.deepin.io/lib/initializer" ) func TestInitializer(t *testing.T) { Convey("test initializer with success", t, func(c C) { err := NewInitializer().Init(func(interface{}) (interface{}, error) { return 1, nil }).Init(func(v interface{}) (interface{}, error) { c.So(v, ShouldEqual, 1) return nil, nil }).GetError() c.So(err, ShouldBeNil) }) } func TestInitializerError(t *testing.T) { Convey("test initializer with error", t, func(c C) { var err error c.So(func() { err = NewInitializer().Init(func(interface{}) (interface{}, error) { return 1, nil }).Init(func(v interface{}) (interface{}, error) { c.So(v, ShouldEqual, 1) return nil, nil }).Init(func(interface{}) (interface{}, error) { return nil, errors.New("initialize error") }).Init(func(interface{}) (interface{}, error) { panic("should not be executed") }).GetError() }, ShouldNotPanic) c.So(err, ShouldNotBeNil) }) } go-lib-5.6.0.9/initializer/v2/000775 000000 000000 00000000000 13753517240 015703 5ustar00rootroot000000 000000 go-lib-5.6.0.9/initializer/v2/initializer.go000664 000000 000000 00000003303 13753517240 020554 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package initializer // Initializer is a chainable initializer. Init/InitOnSystemBus/InitOnSystemBus will accept a initializer, // and then pass the successful return value to the next initializer. If error occurs, the rest initializers // won't be executed any more. GetError is used to access the error. type Initializer struct { e error } func (i *Initializer) init(fn func() error) *Initializer { if i.e != nil { return i } if err := fn(); err != nil { i.e = err } return i } // Do accepts a initializer function, stop other Do if any error occurs. func (i *Initializer) Do(fn func() error) *Initializer { return i.init(func() error { err := fn() if err != nil { return err } return nil }) } // GetError returns the first error of initializers. func (i *Initializer) GetError() error { if i.e != nil { return i.e } return nil } // Do starts the initialization. func Do(fn func() error) *Initializer { i := new(Initializer) return i.Do(fn) } go-lib-5.6.0.9/initializer/v2/initializer_test.go000664 000000 000000 00000003270 13753517240 021616 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package initializer_test import ( "errors" "testing" . "github.com/smartystreets/goconvey/convey" "pkg.deepin.io/lib/initializer/v2" ) func e1() error { return nil } func e2() error { var err error return err } func TestInitializer(t *testing.T) { Convey("test initializer with success", t, func(c C) { err := initializer.Do(func() error { return nil }).Do(func() error { return e1() }).Do(func() error { return e2() }).GetError() c.So(err, ShouldBeNil) }) } func TestInitializerError(t *testing.T) { Convey("test initializer with error", t, func(c C) { var err error c.So(func() { err = initializer.Do(func() error { return e1() }).Do(func() error { return e2() }).Do(func() error { return errors.New("initialize error") }).Do(func() error { panic("should not be executed") }).GetError() }, ShouldNotPanic) c.So(err, ShouldNotBeNil) c.So(err.Error(), ShouldEqual, "initialize error") }) } go-lib-5.6.0.9/iso/000775 000000 000000 00000000000 13753517240 013623 5ustar00rootroot000000 000000 go-lib-5.6.0.9/iso/README.md000664 000000 000000 00000000245 13753517240 015103 0ustar00rootroot000000 000000 ISO 标准配置解析库, 相关文件位于 /usr/share/xml/iso-codes/, 目前实现了 对 iso_3166.xml 的解析从而可以获取国家和地区的相关信息. go-lib-5.6.0.9/iso/country.go000664 000000 000000 00000010613 13753517240 015656 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package iso import ( "encoding/xml" "fmt" "io/ioutil" "os" . "pkg.deepin.io/lib/gettext" "strings" "sync" ) const iso3166XMLFile = "/usr/share/xml/iso-codes/iso_3166.xml" // map dtd of iso_3166.xml to go structures type CountryDatabase struct { Countries []Country `xml:"iso_3166_entry"` } type Country struct { Alpha2Code string `xml:"alpha_2_code,attr"` Alpha3Code string `xml:"alpha_3_code,attr"` NumericCode string `xml:"numeric_code,attr"` CommonName string `xml:"common_name,attr"` Name string `xml:"name,attr"` OfficialName string `xml:"official_name,attr"` } var countryDatabase *CountryDatabase var countryDatabaseLock sync.Mutex var ( errLanguageFormatInvalid = fmt.Errorf("invalid environment variable LANGUAGE") errCountryCodeInvalid = fmt.Errorf("invalid country code") ) // GetCountryDatabase return country database that marshaled from ISO // 3166 xml file. func GetCountryDatabase() (*CountryDatabase, error) { countryDatabaseLock.Lock() defer countryDatabaseLock.Unlock() if countryDatabase != nil { return countryDatabase, nil } countryDatabase = &CountryDatabase{} xmlContent, err := ioutil.ReadFile(iso3166XMLFile) if err != nil { return countryDatabase, err } err = xml.Unmarshal(xmlContent, countryDatabase) return countryDatabase, err } // GetLocaleCountryCode return locale country code by analysis // environment variable "LANGUAGE". func GetLocaleCountryCode() (code string, err error) { return GetCountryCodeForLanguage(getLocalLanguage()) } func getLocalLanguage() string { if value := os.Getenv("LANGUAGE"); len(value) > 0 { return value } if value := os.Getenv("LC_ALL"); len(value) > 0 { return value } if value := os.Getenv("LC_MESSAGES"); len(value) > 0 { return value } if value := os.Getenv("LANG"); len(value) > 0 { return value } return "en_US.UTF-8" } // GetLocaleCountryName return locale country name by analysis // environment variable "LANGUAGE". func GetLocaleCountryName() (name string, err error) { code, err := GetLocaleCountryCode() if err != nil { return } return GetCountryNameForCode(code) } // GetCountryCodeForLanguage return country code for a language // variable, e.g. "CN" will be return if passing "zh_CN.UTF-8". func GetCountryCodeForLanguage(language string) (code string, err error) { if !strings.Contains(language, "_") { err = errLanguageFormatInvalid return } var indexFrom, indexTo int indexFrom = strings.Index(language, "_") if strings.Contains(language, ".") { indexTo = strings.Index(language, ".") } else { indexTo = len(language) } if indexFrom+1 >= indexTo { err = errLanguageFormatInvalid return } code = language[indexFrom+1 : indexTo] return } // GetCountryNameForCode return country name that corresponding to the // country code. func GetCountryNameForCode(code string) (name string, err error) { database, err := GetCountryDatabase() if err != nil { return } for _, entry := range database.Countries { if strings.EqualFold(code, entry.Alpha2Code) { name = DGettext("iso_3166", entry.Name) break } } if len(name) == 0 { err = errCountryCodeInvalid } return } // GetAllCountryCode return all country code. func GetAllCountryCode() (codeList []string, err error) { database, err := GetCountryDatabase() if err != nil { return } for _, entry := range database.Countries { codeList = append(codeList, entry.Alpha2Code) } return } // GetAllCountryNames return all country names. func GetAllCountryNames() (nameList []string, err error) { database, err := GetCountryDatabase() if err != nil { return } for _, entry := range database.Countries { nameList = append(nameList, DGettext("iso_3166", entry.Name)) } return } go-lib-5.6.0.9/iso/country_test.go000664 000000 000000 00000005751 13753517240 016724 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package iso import ( C "gopkg.in/check.v1" "os" . "pkg.deepin.io/lib/gettext" ) const envLanguage = "LANGUAGE" func (*testWrapper) TestGetCountryDatabase(c *C.C) { database, err := GetCountryDatabase() c.Check(database, C.NotNil) c.Check(err, C.Equals, nil) } func (*testWrapper) TestGetLocaleCountryInfo(c *C.C) { cur := os.Getenv("LC_ALL") if cur == "C" || cur == "POSIX" { c.Skip("Unsupported locale") return } oldLanguage := os.Getenv(envLanguage) defer os.Setenv(envLanguage, oldLanguage) testData := []struct { language, code, name string }{ {"zh_CN.UTF-8", "CN", "中国"}, {"en_US.UTF-8", "US", "United States"}, } for _, d := range testData { os.Setenv("LC_MESSAGES", "en_US.UTF-8") os.Setenv("LC_CTYPE", "en_US.UTF-8") InitI18n() os.Setenv(envLanguage, d.language) code, _ := GetLocaleCountryCode() c.Check(code, C.Equals, d.code) name, _ := GetLocaleCountryName() c.Check(name, C.Equals, d.name) } } func (*testWrapper) TestGetCountryCodeForLanguage(c *C.C) { testData := []struct { language, code string }{ {"de_DE.ISO-8859-1", "DE"}, {"en_US.UTF-8", "US"}, {"zh_CN.UTF-8", "CN"}, {"zh_CN", "CN"}, } for _, d := range testData { code, _ := GetCountryCodeForLanguage(d.language) c.Check(code, C.Equals, d.code) } // check invalid format _, err := GetCountryCodeForLanguage("") c.Check(err, C.NotNil) _, err = GetCountryCodeForLanguage("en.US_UTF-8") c.Check(err, C.NotNil) _, err = GetCountryCodeForLanguage("en_.US.UTF-8") c.Check(err, C.NotNil) } func (*testWrapper) TestGetCountryInfoForCode(c *C.C) { cur := os.Getenv("LC_ALL") if cur == "C" || cur == "POSIX" { c.Skip("Unsupported locale") return } oldLanguage := os.Getenv(envLanguage) defer os.Setenv(envLanguage, oldLanguage) testData := []struct { language, code, name string }{ {"zh_CN.UTF-8", "CN", "中国"}, {"zh_CN.UTF-8", "US", "美国"}, {"en_US.UTF-8", "CN", "China"}, {"en_US.UTF-8", "US", "United States"}, {"en_US.UTF-8", "Cn", "China"}, {"en_US.UTF-8", "cn", "China"}, } for _, d := range testData { os.Setenv("LC_MESSAGES", "en_US.UTF-8") os.Setenv("LC_CTYPE", "en_US.UTF-8") InitI18n() os.Setenv(envLanguage, d.language) name, _ := GetCountryNameForCode(d.code) c.Check(name, C.Equals, d.name) } } go-lib-5.6.0.9/iso/iso_test.go000664 000000 000000 00000001630 13753517240 016003 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package iso import ( C "gopkg.in/check.v1" "testing" ) type testWrapper struct{} func Test(t *testing.T) { C.TestingT(t) } func init() { C.Suite(&testWrapper{}) } go-lib-5.6.0.9/keyfile/000775 000000 000000 00000000000 13753517240 014461 5ustar00rootroot000000 000000 go-lib-5.6.0.9/keyfile/get.go000664 000000 000000 00000013524 13753517240 015574 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package keyfile import ( "bytes" "fmt" "strconv" "strings" "unicode/utf8" libLocale "pkg.deepin.io/lib/locale" ) func parseValueAsBool(value string) (bool, error) { switch value { case "true": return true, nil case "false": return false, nil default: return false, InvalidValueError{value} } } func (f *KeyFile) GetInt(section, key string) (int, error) { value, err := f.GetValue(section, key) if err != nil { return 0, err } return strconv.Atoi(value) } func (f *KeyFile) GetInt64(section, key string) (int64, error) { value, err := f.GetValue(section, key) if err != nil { return 0, err } return strconv.ParseInt(value, 10, 64) } func (f *KeyFile) GetUint64(section, key string) (uint64, error) { value, err := f.GetValue(section, key) if err != nil { return 0, err } return strconv.ParseUint(value, 10, 64) } func (f *KeyFile) GetFloat64(section, key string) (float64, error) { value, err := f.GetValue(section, key) if err != nil { return 0.0, err } return strconv.ParseFloat(value, 64) } // support escape characters: // \s space // \n newline // \t tab // \r carriage return // \\ backslash func parseValueAsString(value string, wantArray bool, listSeparator byte) (string, []string, error) { var buf bytes.Buffer var outlist []string reader := strings.NewReader(value) for { ch, err := reader.ReadByte() if err != nil { break } if ch == '\\' { ch, err := reader.ReadByte() if err != nil { break } switch ch { case 's': buf.WriteByte(' ') case 'n': buf.WriteByte('\n') case 't': buf.WriteByte('\t') case 'r': buf.WriteByte('\r') case '\\': buf.WriteByte('\\') default: if wantArray && ch == listSeparator { buf.WriteByte(';') } else { buf.WriteByte('\\') buf.WriteByte(ch) } } } else if wantArray && ch == listSeparator { outlist = append(outlist, buf.String()) buf.Reset() } else { buf.WriteByte(ch) } } if wantArray { if buf.Len() != 0 { outlist = append(outlist, buf.String()) } return "", outlist, nil } else { return buf.String(), nil, nil } } func (f *KeyFile) GetString(section, key string) (string, error) { value, err := f.GetValue(section, key) if err != nil { return "", err } if !utf8.ValidString(value) { return "", ValueInvalidUTF8Error{section, key} } str, _, err := parseValueAsString(value, false, f.ListSeparator) return str, err } func (f *KeyFile) GetLocaleString(section, key, locale string) (string, error) { var languages []string if locale == "" { languages = libLocale.GetLanguageNames() } else { languages = libLocale.GetLocaleVariants(locale) } for _, lang := range languages { translated, err := f.GetString(section, fmt.Sprintf("%s[%s]", key, lang)) if err == nil { return translated, nil } } // NOTE: not support key Gettext-Domain // fallback to default key return f.GetString(section, key) } func (f *KeyFile) GetStringList(section, key string) ([]string, error) { value, err := f.GetValue(section, key) if err != nil { return nil, err } if !utf8.ValidString(value) { return nil, ValueInvalidUTF8Error{section, key} } _, list, err := parseValueAsString(value, true, f.ListSeparator) return list, err } func (f *KeyFile) GetLocaleStringList(section, key, locale string) ([]string, error) { var languages []string if locale == "" { languages = libLocale.GetLanguageNames() } else { languages = libLocale.GetLocaleVariants(locale) } for _, lang := range languages { translated, err := f.GetStringList(section, fmt.Sprintf("%s[%s]", key, lang)) if err == nil { return translated, nil } } // fallback to default key return f.GetStringList(section, key) } type ValueInvalidUTF8Error struct { Section string Key string } func (err ValueInvalidUTF8Error) Error() string { return fmt.Sprintf("value of key %q in section %q is not a valid utf8 string", err.Key, err.Section) } func (f *KeyFile) GetBoolList(section, key string) ([]bool, error) { value, err := f.GetValue(section, key) if err != nil { return nil, err } _, list, err := parseValueAsString(value, true, f.ListSeparator) if err != nil { return nil, err } ret := make([]bool, len(list)) for i, str := range list { ret[i], err = parseValueAsBool(str) if err != nil { return nil, err } } return ret, nil } func (f *KeyFile) GetIntList(section, key string) ([]int, error) { value, err := f.GetValue(section, key) if err != nil { return nil, err } _, list, err := parseValueAsString(value, true, f.ListSeparator) if err != nil { return nil, err } ret := make([]int, len(list)) for i, str := range list { ret[i], err = strconv.Atoi(str) if err != nil { return nil, err } } return ret, nil } func (f *KeyFile) GetFloat64List(section, key string) ([]float64, error) { value, err := f.GetValue(section, key) if err != nil { return nil, err } _, list, err := parseValueAsString(value, true, f.ListSeparator) if err != nil { return nil, err } ret := make([]float64, len(list)) for i, str := range list { ret[i], err = strconv.ParseFloat(str, 64) if err != nil { return nil, err } } return ret, nil } go-lib-5.6.0.9/keyfile/keyfile.go000664 000000 000000 00000013311 13753517240 016437 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package keyfile import ( "fmt" "regexp" "sync" ) var LineBreak = "\n" type KeyFile struct { mutex sync.RWMutex keyReg *regexp.Regexp data map[string]map[string]string // section -> key : value sectionList []string // section name list keyList map[string][]string // section -> key name list sectionComments map[string]string keyComments map[string]map[string]string // keys comments. ListSeparator byte } func NewKeyFile() *KeyFile { f := &KeyFile{ data: make(map[string]map[string]string), keyList: make(map[string][]string), sectionComments: make(map[string]string), keyComments: make(map[string]map[string]string), ListSeparator: ';', } return f } func (f *KeyFile) SetKeyRegexp(keyReg *regexp.Regexp) { f.keyReg = keyReg } // it returns true if the key and value were inserted // or return false if the value was overwritten. func (f *KeyFile) SetValue(section, key, value string) bool { if section == "" || key == "" { return false } if f.keyReg != nil && !f.keyReg.MatchString(key) { return false } f.mutex.Lock() defer f.mutex.Unlock() // Check if section exists if _, ok := f.data[section]; !ok { f.data[section] = make(map[string]string) f.sectionList = append(f.sectionList, section) } // check if key exists _, ok := f.data[section][key] f.data[section][key] = value if !ok { f.keyList[section] = append(f.keyList[section], key) } return !ok } func (f *KeyFile) DeleteKey(section, key string) bool { f.mutex.Lock() defer f.mutex.Unlock() // Check if section exists if _, ok := f.data[section]; !ok { return false } // Check if key exists if _, ok := f.data[section][key]; ok { delete(f.data[section], key) f.SetKeyComments(section, key, "") i := 0 for _, keyName := range f.keyList[section] { if keyName == key { break } i++ } // Remove from key list keyList := f.keyList[section] f.keyList[section] = append(keyList[:i], keyList[i+1:]...) return true } return false } func (f *KeyFile) GetValue(section, key string) (string, error) { f.mutex.RLock() defer f.mutex.RUnlock() // Check if section exists if _, ok := f.data[section]; !ok { return "", SectionNotFoundError{section} } // Section exists // Check if key exists or empty value value, ok := f.data[section][key] if !ok { return "", KeyNotFoundError{key} } // Key exists return value, nil } func (f *KeyFile) GetBool(section, key string) (bool, error) { value, err := f.GetValue(section, key) if err != nil { return false, err } return parseValueAsBool(value) } func (f *KeyFile) GetSections() []string { return f.sectionList } func (f *KeyFile) GetKeys(section string) []string { if _, ok := f.data[section]; !ok { // Section not exists return nil } return f.keyList[section] } // It returns true if the section was deleted, and false if the section didn't exist func (f *KeyFile) DeleteSection(section string) bool { if _, ok := f.data[section]; !ok { return false } delete(f.data, section) f.SetSectionComments(section, "") // Remove from sectionList i := 0 for _, secName := range f.sectionList { if secName == section { break } i++ } f.sectionList = append(f.sectionList[:i], f.sectionList[i+1:]...) delete(f.keyList, section) delete(f.keyComments, section) return true } func (f *KeyFile) GetSection(section string) (map[string]string, error) { if _, ok := f.data[section]; !ok { return nil, SectionNotFoundError{section} } secMap := f.data[section] return secMap, nil } func (f *KeyFile) SetSectionComments(section, comments string) bool { if len(comments) == 0 { delete(f.sectionComments, section) return true } // Check if comment exists _, ok := f.sectionComments[section] if comments[0] != '#' { comments = "# " + comments } f.sectionComments[section] = comments return !ok } func (f *KeyFile) SetKeyComments(section, key, comments string) bool { if _, ok := f.keyComments[section]; ok { if len(comments) == 0 { delete(f.keyComments[section], key) return true } } else { if len(comments) == 0 { return true } else { f.keyComments[section] = make(map[string]string) } } _, ok := f.keyComments[section][key] if comments[0] != '#' { comments = "# " + comments } f.keyComments[section][key] = comments return !ok } func (f *KeyFile) GetSectionComments(section string) string { return f.sectionComments[section] } func (f *KeyFile) GetKeyComments(section, key string) string { if _, ok := f.keyComments[section]; ok { return f.keyComments[section][key] } return "" } type SectionNotFoundError struct { Name string } func (err SectionNotFoundError) Error() string { return fmt.Sprintf("section %q not found", err.Name) } type KeyNotFoundError struct { Name string } func (err KeyNotFoundError) Error() string { return fmt.Sprintf("key %q not found", err.Name) } type InvalidValueError struct { Value string } func (err InvalidValueError) Error() string { return fmt.Sprintf("value %q is invalid", err.Value) } go-lib-5.6.0.9/keyfile/keyfile_test.go000664 000000 000000 00000022247 13753517240 017506 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package keyfile import ( "bytes" "path/filepath" "regexp" "testing" . "github.com/smartystreets/goconvey/convey" ) const desktopFileContent0 = `#!/usr/bin/env xdg-open [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=cxoffice-407693d8-5e19-11e6-845f-2b300706ad83 Categories=chat; # icon comments Icon=apps.com.qq.im.light Exec="/opt/cxoffice/support/apps.com.qq.im.light/desktopdata/cxmenu/StartMenu.C^5E3A_users_crossover_Start^2BMenu/Programs/QQ轻聊版.lnk" %u Name=QQ轻聊版` const desktopFileContent1 = ` Encoding=UTF-8 Type=Application ` const desktopFileContent2 = ` [Desktop Entry] Encoding=UTF-8 Type=Application X-Created-By=cxoffice-407693d8-5e19-11e6-845f-2b300706ad83 Categories: chat; ` const desktopFileContent3 = ` [Desktop Entry] =nokey ` const desktopFileContent4 = ` [Desktop Entry] abc/def=nokey ` func TestLoadFromData(t *testing.T) { Convey("Test LoadFromData EntryNotInSectionError", t, func(c C) { f := NewKeyFile() err := f.LoadFromData([]byte(desktopFileContent1)) c.So(err, ShouldNotBeNil) c.So(err, ShouldHaveSameTypeAs, EntryNotInSectionError{}) t.Log(err) }) Convey("Test LoadFromData ParseError", t, func(c C) { f := NewKeyFile() err := f.LoadFromData([]byte(desktopFileContent2)) c.So(err, ShouldNotBeNil) c.So(err, ShouldHaveSameTypeAs, ParseError{}) t.Log(err) }) Convey("Test LoadFromData key is empty", t, func(c C) { f := NewKeyFile() err := f.LoadFromData([]byte(desktopFileContent3)) c.So(err, ShouldNotBeNil) t.Log(err) }) Convey("Test LoadFromData InvalidKeyError", t, func(c C) { f := NewKeyFile() keyReg := regexp.MustCompile(`^[A-Za-z0-9\-]+$`) f.SetKeyRegexp(keyReg) err := f.LoadFromData([]byte(desktopFileContent4)) c.So(err, ShouldNotBeNil) t.Log(err) ret := f.SetValue("Desktop Entry", "Abc+", "123") c.So(ret, ShouldBeFalse) ret = f.SetValue("Desktop Entry", "Abc", "123") c.So(ret, ShouldBeTrue) }) Convey("Test LoadFromData", t, func(c C) { f := NewKeyFile() err := f.LoadFromData([]byte(desktopFileContent0)) c.So(err, ShouldBeNil) c.Convey("Test GetSections", func(c C) { c.So(f.GetSections(), ShouldResemble, []string{"Desktop Entry"}) }) c.Convey("Get value that does exist", func(c C) { v, err := f.GetValue("Desktop Entry", "Type") c.So(err, ShouldBeNil) c.So(v, ShouldEqual, "Application") }) c.Convey("Get value the does not exist", func(c C) { _, err := f.GetValue("Desktop Entry", "x") c.So(err, ShouldNotBeNil) }) c.Convey("Get value that section not exist", func(c C) { _, err := f.GetValue("X", "X") c.So(err, ShouldNotBeNil) }) c.Convey("Test GetKeys", func(c C) { c.So(f.GetKeys("Desktop Entry"), ShouldResemble, []string{ "Encoding", "Type", "X-Created-By", "Categories", "Icon", "Exec", "Name", }) }) c.Convey("Get section comments", func(c C) { c.So(f.GetSectionComments("Desktop Entry"), ShouldEqual, "#!/usr/bin/env xdg-open\n") }) c.Convey("Get key comments", func(c C) { c.So(f.GetKeyComments("Desktop Entry", "Icon"), ShouldEqual, "# icon comments") c.So(f.GetKeyComments("Desktop Entry", "Categories"), ShouldEqual, "") }) }) } func TestLoadFromFile(t *testing.T) { Convey("LoadFromFile ok", t, func(c C) { f := NewKeyFile() err := f.LoadFromFile("testdata/deepin-screenshot.desktop") c.So(err, ShouldBeNil) localeName, err := f.GetLocaleString("Desktop Entry", "Name", "zh_CN") c.So(localeName, ShouldEqual, "深度截图") c.So(err, ShouldBeNil) }) Convey("Load file in dir", t, func(c C) { files, err := filepath.Glob("/usr/share/applications/*.desktop") c.So(err, ShouldBeNil) for _, file := range files { f := NewKeyFile() err := f.LoadFromFile(file) c.So(err, ShouldBeNil) } }) } const keyFileContent0 = ` [Test] strlist0=a;b;c;d; strlist1=a;b;c strlist2=; strlist3= strlist4=abc\ strlist5=abc\befg strlist6=a\;bc;def strlist7=?` func TestGetStringList(t *testing.T) { Convey("GetStringList", t, func(c C) { f := NewKeyFile() keyFileContent := keyFileContent0 + string([]byte{0xff, 0xfe, 0xfd}) err := f.LoadFromData([]byte(keyFileContent)) c.So(err, ShouldBeNil) list, err := f.GetStringList("Test", "strlist0") c.So(err, ShouldBeNil) c.So(list, ShouldResemble, []string{"a", "b", "c", "d"}) list, err = f.GetStringList("Test", "strlist1") c.So(err, ShouldBeNil) c.So(list, ShouldResemble, []string{"a", "b", "c"}) list, err = f.GetStringList("Test", "strlist2") c.So(err, ShouldBeNil) c.So(list, ShouldResemble, []string{""}) list, err = f.GetStringList("Test", "strlist3") c.So(err, ShouldBeNil) c.So(list, ShouldBeNil) list, err = f.GetStringList("Test", "strlist4") c.So(err, ShouldBeNil) c.So(list, ShouldResemble, []string{"abc"}) t.Log(err) list, err = f.GetStringList("Test", "strlist5") c.So(err, ShouldBeNil) c.So(list, ShouldResemble, []string{"abc\\befg"}) t.Log(err) list, err = f.GetStringList("Test", "strlist6") c.So(err, ShouldBeNil) c.So(list, ShouldResemble, []string{"a;bc", "def"}) _, err = f.GetStringList("Test", "strlist7") c.So(err, ShouldNotBeNil) c.So(err, ShouldHaveSameTypeAs, ValueInvalidUTF8Error{}) t.Log(err) }) } const keyFileContent1 = ` [Test] str0 = abcdef str1=line\n<-newline\r<-break\t<-table\s<-space str2=abcdef\ str3=abc\bdef str4=abc\;def str5=?` func TestGetString(t *testing.T) { Convey("GetString", t, func(c C) { f := NewKeyFile() keyFileContent := keyFileContent1 + string([]byte{0xff, 0xfe, 0xfd}) err := f.LoadFromData([]byte(keyFileContent)) c.So(err, ShouldBeNil) str, err := f.GetString("Test", "str0") c.So(err, ShouldBeNil) c.So(str, ShouldEqual, "abcdef") str, err = f.GetString("Test", "str1") c.So(err, ShouldBeNil) c.So(str, ShouldEqual, "line\n<-newline\r<-break\t<-table <-space") str, err = f.GetString("Test", "str2") c.So(err, ShouldBeNil) c.So(str, ShouldEqual, "abcdef") str, err = f.GetString("Test", "str3") c.So(err, ShouldBeNil) c.So(str, ShouldEqual, "abc\\bdef") str, err = f.GetString("Test", "str4") c.So(err, ShouldBeNil) c.So(str, ShouldEqual, "abc\\;def") _, err = f.GetString("Test", "str5") c.So(err, ShouldHaveSameTypeAs, ValueInvalidUTF8Error{}) }) } func TestSetString(t *testing.T) { Convey("SetString", t, func(c C) { f := NewKeyFile() const s0 = "space newline\ncarriage-return\rtab\tbackslash\\" f.SetString("Test", "str0", s0) str0, err := f.GetString("Test", "str0") c.So(err, ShouldBeNil) c.So(str0, ShouldEqual, s0) val0, err := f.GetValue("Test", "str0") c.So(err, ShouldBeNil) c.So(val0, ShouldEqual, `space newline\ncarriage-return\rtab\tbackslash\\`) }) } func TestSetStringList(t *testing.T) { Convey("SetStringList", t, func(c C) { f := NewKeyFile() strlist := []string{"space ", "newline\n", "carriage\rreturn", "tab\t", "backslash\\", "List;Separator;"} f.SetStringList("Test", "strlist", strlist) strlist1, err := f.GetStringList("Test", "strlist") c.So(err, ShouldBeNil) c.So(strlist1, ShouldResemble, strlist) strlistValue, err := f.GetValue("Test", "strlist") c.So(err, ShouldBeNil) c.So(strlistValue, ShouldEqual, `space\s;newline\n;carriage\rreturn;tab\t;backslash\\;List\;Separator\;;`) }) } func TestSetBoolList(t *testing.T) { Convey("SetBoolList", t, func(c C) { f := NewKeyFile() blist := []bool{true, true, false, false, true, false} f.SetBoolList("Test", "blist", blist) blist1, err := f.GetBoolList("Test", "blist") c.So(err, ShouldBeNil) c.So(blist1, ShouldResemble, blist) blistStr, err := f.GetValue("Test", "blist") c.So(err, ShouldBeNil) c.So(blistStr, ShouldEqual, "true;true;false;false;true;false;") }) } func TestSetIntList(t *testing.T) { Convey("SetIntList", t, func(c C) { f := NewKeyFile() ints := []int{-345, -1, 0, 1, 3, 5, 7, 9, 11989} f.SetIntList("Test", "ints", ints) ints1, err := f.GetIntList("Test", "ints") c.So(err, ShouldBeNil) c.So(ints1, ShouldResemble, ints) intsStr, err := f.GetValue("Test", "ints") c.So(err, ShouldBeNil) c.So(intsStr, ShouldResemble, "-345;-1;0;1;3;5;7;9;11989;") }) } const keyFileContent2 = `[Test] KeyA=aaaa KeyB=1234567890 KeyC=true [Main] KeyD=keyfile ` func TestSaveToWriter(t *testing.T) { Convey("SaveToWriter", t, func(c C) { f := NewKeyFile() f.SetValue("Test", "KeyA", "aaaa") f.SetValue("Test", "KeyB", "1234567890") f.SetValue("Test", "KeyC", "true") f.SetValue("Main", "KeyD", "keyfile") var buf bytes.Buffer err := f.SaveToWriter(&buf) c.So(err, ShouldBeNil) c.So(buf.String(), ShouldEqual, keyFileContent2) }) } go-lib-5.6.0.9/keyfile/read.go000664 000000 000000 00000006042 13753517240 015725 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package keyfile import ( "bufio" "bytes" "errors" "fmt" "io" "os" "strings" "unicode" ) func (f *KeyFile) LoadFromReader(reader io.Reader) error { var comments string var section string // Parse line by line scanner := bufio.NewScanner(reader) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) lineLength := len(line) switch { case lineLength == 0 || line[0] == '#': // Comment // Append comments if len(comments) == 0 { comments = line } else { comments += (LineBreak + line) } continue case line[0] == '[' && line[lineLength-1] == ']': // New section section = strings.TrimSpace(line[1 : lineLength-1]) if len(section) == 0 { return BlankSectionNameError{} } if len(comments) > 0 { f.SetSectionComments(section, comments) comments = "" } continue default: idx := strings.IndexRune(line, '=') if idx == -1 { return ParseError{line} } if section == "" { return EntryNotInSectionError{line} } key := strings.TrimRightFunc(line[:idx], unicode.IsSpace) if key == "" { return errEmptyKey } if f.keyReg != nil { if !f.keyReg.MatchString(key) { return InvalidKeyError{key} } } value := strings.TrimLeftFunc(line[idx+1:], unicode.IsSpace) f.SetValue(section, key, value) if len(comments) > 0 { f.SetKeyComments(section, key, comments) comments = "" } } } return nil } func (f *KeyFile) LoadFromData(data []byte) error { return f.LoadFromReader(bytes.NewBuffer(data)) } func (f *KeyFile) LoadFromFile(filename string) error { fh, err := os.Open(filename) if err != nil { return err } defer fh.Close() return f.LoadFromReader(bufio.NewReader(fh)) } type BlankSectionNameError struct{} func (err BlankSectionNameError) Error() string { return "empty section name not allowed" } type EntryNotInSectionError struct { Line string } func (err EntryNotInSectionError) Error() string { return fmt.Sprintf("entry %q not in any section", err.Line) } type InvalidKeyError struct { Key string } func (err InvalidKeyError) Error() string { return fmt.Sprintf("invalid key name %q", err.Key) } var errEmptyKey = errors.New("key is empty") type ParseError struct { Line string } func (err ParseError) Error() string { return fmt.Sprintf("could not parse line: %q", err.Line) } go-lib-5.6.0.9/keyfile/set.go000664 000000 000000 00000006116 13753517240 015607 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package keyfile import ( "bytes" "strconv" ) func stringEscape(in string) string { var buf bytes.Buffer for _, r := range in { switch r { case '\n': buf.WriteString(`\n`) case '\t': buf.WriteString(`\t`) case '\r': buf.WriteString(`\r`) case '\\': buf.WriteString(`\\`) default: buf.WriteRune(r) } } return buf.String() } func (f *KeyFile) SetString(section, key, value string) { f.SetValue(section, key, stringEscape(value)) } // TODO SetLocaleString func (f *KeyFile) SetBool(section, key string, value bool) { f.SetValue(section, key, strconv.FormatBool(value)) } func (f *KeyFile) SetInt(section, key string, value int) { f.SetValue(section, key, strconv.Itoa(value)) } func (f *KeyFile) SetInt64(section, key string, value int64) { f.SetValue(section, key, strconv.FormatInt(value, 10)) } func (f *KeyFile) SetUint64(section, key string, value uint64) { f.SetValue(section, key, strconv.FormatUint(value, 10)) } func (f *KeyFile) SetFloat64(section, key string, value float64) { f.SetValue(section, key, strconv.FormatFloat(value, 'g', -1, 64)) } func (f *KeyFile) SetStringList(section, key string, values []string) { var buf bytes.Buffer for _, val := range values { for _, r := range val { switch r { case ' ': buf.WriteString(`\s`) case '\n': buf.WriteString(`\n`) case '\t': buf.WriteString(`\t`) case '\r': buf.WriteString(`\r`) case '\\': buf.WriteString(`\\`) case rune(f.ListSeparator): buf.WriteByte('\\') buf.WriteRune(r) default: buf.WriteRune(r) } } buf.WriteByte(f.ListSeparator) } f.SetValue(section, key, buf.String()) } func (f *KeyFile) SetBoolList(section, key string, values []bool) { var buf bytes.Buffer for _, val := range values { buf.WriteString(strconv.FormatBool(val)) buf.WriteByte(f.ListSeparator) } f.SetValue(section, key, buf.String()) } func (f *KeyFile) SetIntList(section, key string, values []int) { var buf bytes.Buffer for _, val := range values { buf.WriteString(strconv.Itoa(val)) buf.WriteByte(f.ListSeparator) } f.SetValue(section, key, buf.String()) } func (f *KeyFile) SetFloat64List(section, key string, values []float64) { var buf bytes.Buffer for _, val := range values { buf.WriteString(strconv.FormatFloat(val, 'g', -1, 64)) buf.WriteByte(f.ListSeparator) } f.SetValue(section, key, buf.String()) } go-lib-5.6.0.9/keyfile/testdata/000775 000000 000000 00000000000 13753517240 016272 5ustar00rootroot000000 000000 go-lib-5.6.0.9/keyfile/testdata/deepin-screenshot.desktop000664 000000 000000 00000013624 13753517240 023312 0ustar00rootroot000000 000000 [Desktop Entry] Categories=Graphics;GTK; Comment=Screen capturing application Exec=deepin-screenshot --icon GenericName=Screen capturing application Icon=deepin-screenshot Name=Deepin Screenshot StartupNotify=false Type=Application # Translations Comment[am]=መመልከቻውን ፎቶ ማንሻ መተግበሪያ GenericName[am]=መመልከቻውን ፎቶ ማንሻ መተግበሪያ Name[am]=መመልከቻውን ፎቶ ማንሻ Comment[ar]=تطبيق أخذ لقطة للشاشة GenericName[ar]=تطبيق أخذ لقطة للشاشة Name[ar]=دييبن لقطة الشاشة Comment[az]=Ekran çəkmə tətbiqetməsi GenericName[az]=Ekran çəkmə tətbiqetməsi Name[az]=Deepin Ekran Görüntüsü Comment[bg]=Програма за заснемане на екрана GenericName[bg]=Програма за заснемане на екрана Name[bg]=Deepin Снимка на екрана Comment[cs]=Program na zachytávání obrazovky GenericName[cs]=Program na zachytávání obrazovky Name[cs]=Snímek obrazovky Comment[da]=Skærmbillede program GenericName[da]=Skærmbillede program Name[da]=Deepin skærmbillede Comment[de]=Bildschirmfoto Aufnahmesoftware GenericName[de]=Bildschirmfoto Aufnahmesoftware Name[de]=Deepin Bildschirmfoto Comment[el]=Εφαρμογή καταγραφής οθόνης GenericName[el]=Εφαρμογή καταγραφής οθόνης Name[el]=Στιγμιότυπο οθόνης Deepin Comment[es]=Aplicación para captura de pantalla GenericName[es]=Aplicación para captura de pantalla Name[es]=Captura de pantalla Deepin Comment[fi]=Kuvakaappaus ohjelma GenericName[fi]=Kuvakaappaus ohjelma Name[fi]=Deepin Kuvakaappaus Comment[fr]=Application de capture d'écran GenericName[fr]=Application de capture d'écran Name[fr]=Capture d'écran de Deepin Comment[es_CL]=Captura de pantalla a Aplicación GenericName[es_CL]=Captura de pantalla a Aplicación Name[es_CL]=Captura de pantalla Deepin Comment[he]=תוכנת צילום מסך GenericName[he]=תוכנת צילום מסך Name[he]=צילום-מסך Deepin Comment[hr]=Aplikacija snimke zaslona GenericName[hr]=Aplikacija snimke zaslona Name[hr]=Deepin snimak zaslona Comment[hu]=Képernyőkép rögzítő alkalmazás GenericName[hu]=Képernyőkép rögzítő alkalmazás Name[hu]=Deepin képernyőkép Comment[hy]=Էկրանից նկար ստեղծող հավելված GenericName[hy]=Էկրանից նկար ստեղծող հավելված Name[hy]=Deepin-ի Նկար Comment[id]=Aplikasi penangkap layar GenericName[id]=Aplikasi penangkap layar Name[id]=Tangkapan Layar Deepin Comment[it]=Applicazione per screenshot GenericName[it]=Applicazione per screenshot Name[it]=Deepin Screenshot Comment[ja]=スクリンキャプチャーアプリ GenericName[ja]=スクリンキャプチャーアプリ Name[ja]=スクリンショート Comment[es_PE]=Aplicación para captura de pantallas GenericName[es_PE]=Aplicación para captura de pantallas Name[es_PE]=Deepin Capturas de pantalla Comment[pam]=Application a pamag kuang Screen GenericName[pam]=Application a pamag kuang Screen Name[pam]=Deepin Screenshot Comment[ms]=Aplikasi menangkap layar GenericName[ms]=Aplikasi menangkap layar Name[ms]=Penangkap Layar Deepin Comment[nl]=Applicatie voor het maken van schermopnames GenericName[nl]=Applicatie voor het maken van schermopnames Name[nl]=Deepin Schermopname Comment[es_419]=Aplicación de captura de pantalla GenericName[es_419]=Aplicación de captura de pantalla Name[es_419]=Captura de pantalla Deepin Comment[pl]=Program do przechwytywania ekranu GenericName[pl]=Program do przechwytywania ekranu Name[pl]=Zrzut ekranu Deepin Comment[pt]=Aplicação de captura de ecrã GenericName[pt]=Aplicação de captura de ecrã Name[pt]=Captura de Ecrã Deepin Comment[pt_BR]=Aplicação de captura de tela GenericName[pt_BR]=Aplicação de captura de tela Name[pt_BR]=Deepin Screenshot Comment[ro]=Aplicație de capturare a ecranului GenericName[ro]=Aplicație de capturare a ecranului Name[ro]= Deepin Screenshot Comment[ru]=Приложение для снимков экрана GenericName[ru]=Приложение для снимков экрана Name[ru]=Deepin Screenshot Comment[sk]=Program na nahrávanie obrazovky GenericName[sk]=Program na nahrávanie obrazovky Name[sk]=Deepin Snímka obrazovky Comment[sl]=Program za zajem zaslona GenericName[sl]=Program za zajem zaslona Name[sl]=Zajemalnik zaslona Deepin Comment[tr]=Ekran yakalama uygulaması GenericName[tr]=Ekran yakalama uygulaması Name[tr]=Deepin Ekran görüntüsü Comment[uk]=Програма для створення знімків екрана GenericName[uk]=Програма для створення знімків екрана Name[uk]=Знімки екрана Deepin Comment[zh_CN]=屏幕截图程序 GenericName[zh_CN]=屏幕截图程序 Name[zh_CN]=深度截图 Comment[zh_HK]=螢幕擷取程式 GenericName[zh_HK]=螢幕擷取程式 Comment[zh_TW]=螢幕擷取程式 GenericName[zh_TW]=螢幕擷取程式 Name[zh_TW]=深度截圖 Comment[es_AR]=Aplicación de Captura de Pantalla GenericName[es_AR]=Aplicación de Captura de Pantalla Name[es_AR]=Capturador de Pantalla Deepin Comment[en_AU]=Screen capture application GenericName[en_AU]=Screen capture application Name[en_AU]=Deepin Screenshot Comment[es_ES]=Capturador de Pantalla GenericName[es_ES]=Capturador de Pantalla Name[es_ES]=Captura de Pantalla de Deepin [Full_Screenshot Shortcut Group] Exec=deepin-screenshot -f Name=Full Screenshot Name[ar]=أخد لقطة لكامل الشاشة Name[cs]=Plný snímek obrazovky Name[da]=Tag billede af hele skrivebordet Name[en]=Full Screenshot Name[es]=Captura de pantalla Completa Name[fr]=Plein écran Name[pt_BR]=Captura de Tela Completa Name[ru]=Полный скриншот Name[sk]=Celý snímok obrazovky Name[sl]=Zajem celotnega zaslona Name[zh_CN]=截取全屏 Name[zh_HK]=擷取全螢幕 Name[zh_TW]=擷取全螢幕 [Delay_Screenshot Shortcut Group] Exec=deepin-screenshot -d 5 Name=Delay Screenshot Name[zh_CN]=延时截图 go-lib-5.6.0.9/keyfile/write.go000664 000000 000000 00000005023 13753517240 016142 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package keyfile import ( "bytes" "io" "os" ) func (f *KeyFile) SaveToWriter(w io.Writer) error { const equalSign = "=" var buf bytes.Buffer for _, section := range f.sectionList { // write section comments sectionComments := f.GetSectionComments(section) if len(sectionComments) > 0 { if _, err := buf.WriteString(sectionComments); err != nil { return err } if _, err := buf.WriteString(LineBreak); err != nil { return err } } // write section name if err := buf.WriteByte('['); err != nil { return err } if _, err := buf.WriteString(section); err != nil { return err } if err := buf.WriteByte(']'); err != nil { return err } if _, err := buf.WriteString(LineBreak); err != nil { return err } // write keys for _, key := range f.keyList[section] { // ignore empty key if key == "" { continue } // write key comments keyComments := f.GetKeyComments(section, key) if len(keyComments) > 0 { if _, err := buf.WriteString(keyComments); err != nil { return err } if _, err := buf.WriteString(LineBreak); err != nil { return err } } // write key and value if _, err := buf.WriteString(key); err != nil { return err } if _, err := buf.WriteString(equalSign); err != nil { return err } value := f.data[section][key] if _, err := buf.WriteString(value); err != nil { return err } if _, err := buf.WriteString(LineBreak); err != nil { return err } } // Put a line between sections. if _, err := buf.WriteString(LineBreak); err != nil { return err } } _, err := buf.WriteTo(w) return err } func (kf *KeyFile) SaveToFile(file string) error { fh, err := os.Create(file) if err != nil { return err } defer fh.Close() return kf.SaveToWriter(fh) } go-lib-5.6.0.9/libc/000775 000000 000000 00000000000 13753517240 013742 5ustar00rootroot000000 000000 go-lib-5.6.0.9/libc/libc.go000664 000000 000000 00000003371 13753517240 015206 0ustar00rootroot000000 000000 package libc /* #define _POSIX_SOURCE #include #include */ import "C" import ( "time" "unsafe" ) type Tm struct { core C.struct_tm } func (tm Tm) native() *C.struct_tm { return &tm.core } func NewTm(t time.Time) Tm { var tm C.struct_tm tm.tm_sec = C.int(t.Second()) tm.tm_min = C.int(t.Minute()) tm.tm_hour = C.int(t.Hour()) tm.tm_mday = C.int(t.Day()) tm.tm_mon = C.int(t.Month() - 1) tm.tm_year = C.int(t.Year() - 1900) tm.tm_wday = C.int(t.Weekday()) tm.tm_yday = C.int(t.YearDay() - 1) tm.tm_isdst = -1 return Tm{ core: tm, } } const initialBufSize = 256 func Strftime(format string, tm Tm) (s string) { if format == "" { return } fmt := C.CString(format) defer C.free(unsafe.Pointer(fmt)) for size := initialBufSize; ; size *= 2 { buf := (*C.char)(C.malloc(C.size_t(size))) // can panic defer C.free(unsafe.Pointer(buf)) n := C.strftime(buf, C.size_t(size), fmt, tm.native()) if n == 0 { // strftime(3), unhelpfully: "Note that the return value 0 does not // necessarily indicate an error; for example, in many locales %p // yields an empty string." This leaves no definite way to // distinguish between the cases where the value doesn't fit and // where it does because the string is empty. In the latter case, // allocating increasingly larger buffers will never change the // result, so we need some heuristic for bailing out. // // Since a single 2-byte conversion sequence should not produce an // output longer than about 24 bytes, we conservatively allow the // buffer size to grow up to 20 times larger than the format string // before giving up. if size > 20*len(format) { return } } else if int(n) < size { s = C.GoStringN(buf, C.int(n)) return } } } go-lib-5.6.0.9/locale/000775 000000 000000 00000000000 13753517240 014270 5ustar00rootroot000000 000000 go-lib-5.6.0.9/locale/locale.go000664 000000 000000 00000011052 13753517240 016055 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package locale import ( "bufio" "bytes" "os" "regexp" "strings" "sync" ) const ( charUscore = '_' charDot = '.' charAt = '@' ) /* * Compute all interesting variants for a given locale name - * by stripping off different components of the value. * * For simplicity, we assume that the locale is in * X/Open format: language[_territory][.codeset][@modifier] */ func GetLocaleVariants(locale string) (variants []string) { cs := ExplodeLocale(locale) mask := cs.Mask for j := uint(0); j <= mask; j++ { i := mask - j if (i & ^mask) == 0 { var buf bytes.Buffer buf.WriteString(cs.Language) if i&ComponentTerritory != 0 { buf.WriteByte(charUscore) buf.WriteString(cs.Territory) } if i&ComponentCodeset != 0 { buf.WriteByte(charDot) buf.WriteString(cs.Codeset) } if i&ComponentModifier != 0 { buf.WriteByte(charAt) buf.WriteString(cs.Modifier) } variants = append(variants, buf.String()) } } return } type Components struct { Language string Territory string Codeset string Modifier string Mask uint } const ( ComponentCodeset = 1 << iota ComponentTerritory ComponentModifier ) // ExplodeLocale Break an X/Open style locale specification into components func ExplodeLocale(locale string) *Components { var c Components atIdx := strings.IndexByte(locale, charAt) if atIdx != -1 { c.Modifier = locale[atIdx+1:] locale = locale[:atIdx] c.Mask |= ComponentModifier } dotIdx := strings.IndexByte(locale, charDot) if dotIdx != -1 { c.Codeset = locale[dotIdx+1:] locale = locale[:dotIdx] c.Mask |= ComponentCodeset } uscoreIdx := strings.IndexByte(locale, charUscore) if uscoreIdx != -1 { c.Territory = locale[uscoreIdx+1:] locale = locale[:uscoreIdx] c.Mask |= ComponentTerritory } c.Language = locale return &c } func guessCategoryValue(categoryName string) (ret string) { // The highest priority value is the 'LANGUAGE' environment // variable. This is a GNU extension. ret = os.Getenv("LANGUAGE") if ret != "" { return } // Setting of LC_ALL overwrites all other. ret = os.Getenv("LC_ALL") if ret != "" { return } // Next comes the name of the desired category. ret = os.Getenv(categoryName) if ret != "" { return } // Last possibility is the LANG environment variable. ret = os.Getenv("LANG") if ret != "" { return } return "C" } type _LanguageNamesCache struct { Language string Names []string mutex sync.Mutex } var languageNameCache _LanguageNamesCache func GetLanguageNames() []string { value := guessCategoryValue("LC_MESSAGES") if value == "" { return []string{"C"} } languageNameCache.mutex.Lock() if languageNameCache.Language != value { languageNameCache.Language = value langs := strings.Split(value, ":") var names []string for _, lang := range langs { variants := GetLocaleVariants(unaliasLang(lang)) names = append(names, variants...) } names = append(names, "C") languageNameCache.Names = names } languageNameCache.mutex.Unlock() return languageNameCache.Names } var splitor = regexp.MustCompile(`\s+|:`) func readAliases(filename string) (aliasTable map[string]string) { file, err := os.Open(filename) if err != nil { return nil } defer file.Close() aliasTable = make(map[string]string) scanner := bufio.NewScanner(bufio.NewReader(file)) for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) if len(line) == 0 || line[0] == '#' { continue } parts := splitor.Split(line, -1) if len(parts) == 2 { aliasTable[parts[0]] = parts[1] } } return } var aliases map[string]string var aliasesOnce sync.Once var aliasFile = "/usr/share/locale/locale.alias" func unaliasLang(lang string) string { aliasesOnce.Do(func() { // init Aliases aliases = readAliases(aliasFile) }) if lang1, ok := aliases[lang]; ok { return lang1 } return lang } go-lib-5.6.0.9/locale/locale_test.go000664 000000 000000 00000006366 13753517240 017130 0ustar00rootroot000000 000000 /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package locale import ( . "github.com/smartystreets/goconvey/convey" "os" "testing" ) func TestExplodeLocale(t *testing.T) { Convey("ExplodeLocale", t, func(c C) { cs := ExplodeLocale("zh_CN.UTF-8@hubei") c.So(cs, ShouldResemble, &Components{ Language: "zh", Territory: "CN", Codeset: "UTF-8", Modifier: "hubei", Mask: ComponentTerritory | ComponentCodeset | ComponentModifier, }) cs = ExplodeLocale("zh_CN.UTF-8") c.So(cs, ShouldResemble, &Components{ Language: "zh", Territory: "CN", Codeset: "UTF-8", Mask: ComponentTerritory | ComponentCodeset, }) cs = ExplodeLocale("zh_CN") c.So(cs, ShouldResemble, &Components{ Language: "zh", Territory: "CN", Mask: ComponentTerritory, }) cs = ExplodeLocale("zh") c.So(cs, ShouldResemble, &Components{ Language: "zh", }) cs = ExplodeLocale("") c.So(cs, ShouldResemble, &Components{}) cs = ExplodeLocale("_.@") c.So(cs, ShouldResemble, &Components{ Mask: ComponentTerritory | ComponentCodeset | ComponentModifier, }) }) } func TestGetLocaleVariants(t *testing.T) { Convey("GetLocaleVariants", t, func(c C) { variants := GetLocaleVariants("zh_CN") c.So(variants, ShouldResemble, []string{"zh_CN", "zh"}) variants = GetLocaleVariants("zh_CN.UTF-8") c.So(variants, ShouldResemble, []string{"zh_CN.UTF-8", "zh_CN", "zh.UTF-8", "zh"}) variants = GetLocaleVariants("zh_CN.UTF-8@hubei") c.So(variants, ShouldResemble, []string{"zh_CN.UTF-8@hubei", "zh_CN@hubei", "zh.UTF-8@hubei", "zh@hubei", "zh_CN.UTF-8", "zh_CN", "zh.UTF-8", "zh"}) }) } func Test_readAliases(t *testing.T) { Convey("readAliases", t, func(c C) { aliases := readAliases("testdata/locale.alias") c.So(aliases, ShouldResemble, map[string]string{"bokmal": "nb_NO.ISO-8859-1", "catalan": "ca_ES.ISO-8859-1", "croatian": "hr_HR.ISO-8859-2"}) aliases = readAliases("testdata/x") c.So(aliases, ShouldBeNil) c.So(aliases["nil"], ShouldEqual, "") }) } func Test_unaliasLang(t *testing.T) { Convey("unaliasLang", t, func(c C) { aliasFile = "testdata/locale.alias" c.So(unaliasLang("zh_CN"), ShouldEqual, "zh_CN") c.So(unaliasLang(""), ShouldEqual, "") c.So(unaliasLang("bokmal"), ShouldEqual, "nb_NO.ISO-8859-1") }) } func TestGetLanguageNames(t *testing.T) { Convey("GetLanguageNames", t, func(c C) { os.Setenv("LANGUAGE", "zh_CN") c.So(GetLanguageNames(), ShouldResemble, []string{"zh_CN", "zh", "C"}) os.Setenv("LANGUAGE", "en_US") c.So(GetLanguageNames(), ShouldResemble, []string{"en_US", "en", "C"}) }) } go-lib-5.6.0.9/locale/testdata/000775 000000 000000 00000000000 13753517240 016101 5ustar00rootroot000000 000000 go-lib-5.6.0.9/locale/testdata/locale.alias000664 000000 000000 00000000155 13753517240 020354 0ustar00rootroot000000 000000 # Locale name alias data base. bokmal nb_NO.ISO-8859-1 catalan ca_ES.ISO-8859-1 croatian hr_HR.ISO-8859-2 go-lib-5.6.0.9/log/000775 000000 000000 00000000000 13753517240 013612 5ustar00rootroot000000 000000 go-lib-5.6.0.9/log/README.md000664 000000 000000 00000004622 13753517240 015075 0ustar00rootroot000000 000000 ## 接口简介 - **NewLogger** 创建 Logger 对象, 需要传递一个日志名称, 如 "daemon/network" - **Logger.SetLogLevel** 设置日志记录级别, 默认为 Logger.LevelInfo - **Logger.Debug**, **Logger.Info**, **Logger.Warning**, **Logger.Error** 日志记录接口, 其中 Logger.Error() 会额外打印 go 函数调用轨迹 (trace) - **Logger.Debugf**, **Logger.Infof**, **Logger.Warningf**, **Logger.Errorf** 日志记录接口, 支持 format 格式, 语法风格和 fmt.Printf() 相同 - **Logger.Panic** 记录日志并额外执行一条 panic() 语句 - **Logger.Fatal** 记录日志并额外执行 os.Exit(1) ## 环境变量 - **DDE_DEBUG**, 若值不为空, 则打印所有日志, 启用其他 **DDE_DEBUG_XXX** 变 量时, 该变量会默认启用 - **DDE_DEBUG_MATCH**, 仅允许匹配该环境变量的 logger 对象打印i日志, 对 logger name 进行匹配, 不区分大小写 - **DDE_DEBUG_LEVEL**, 用于从外部设置日志打印级别, 可选值为 "debug", "info", "warning", "error", "fatal" - **DDE_DEBUG_CONSOLE**, 若值不为空, 则以 syslog 格式打印终端日志 示例 1, 打印 startdde 所有日志: ``` env DDE_DEBUG=1 /usr/bin/startdde ``` 示例 2, 仅打印 startdde 警告级别以上的日志: ``` env DDE_DEBUG_LEVEL="warning" startddek ``` 示例 3, 打印 dde-daemon 中网络模块的所有日志: ``` env DDE_DEBUG_MATCH="network" dde-session-daemon ``` 示例 4, 打印 dde-daemon 中网络模块的日志, 且仅打印警告级别以上的日志: ``` env DDE_DEBUG_MATCH="network" DDE_DEBUG_LEVEL="warning" dde-session-daemon ``` ## 示例代码 ```go import "pkg.deepin.io/lib/log" import "flag" var ( l = log.NewLogger("daemon/test") argDebug bool ) func main() { defer func() { if err := recover(); err != nil { l.Fatal(err) } }() // parse arguments flag.BoolVar(&argDebug, "d", false, "debug") flag.Parse() // setup logger if argDebug { l.SetLogLevel(l.LevelDebug) } } ``` ## 查看日志 对于 rsyslog, 可以配合辅助工具 logtool 高亮显示日志条目, 更加方便 ```sh # apt-get install logtool $ tailf /var/log/syslog | logtool # follow syslog $ tailf /var/log/syslog | grep "startdde" | logtool # filter startdde syslog items ``` 对于 systemd,则可以使用 journalctl ```sh $ journalctl -f # follow syslog $ journalctl /usr/bin/startdde # filter startdde syslog items ``` go-lib-5.6.0.9/log/backend_console.go000664 000000 000000 00000004347 13753517240 017262 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package log import ( "fmt" "os" "pkg.deepin.io/lib/utils" "time" ) const defaultDebugConsoleEnv = "DDE_DEBUG_CONSOLE" var ( // DebugConsoleEnv is the name of environment variable that used to control // the console backend print log in syslog format. DebugConsoleEnv = defaultDebugConsoleEnv ) type backendConsole struct { name string syslogMode bool } func newBackendConsole(name string) (b *backendConsole) { b = &backendConsole{} b.name = name if utils.IsEnvExists(DebugConsoleEnv) { b.syslogMode = true } return } func (b *backendConsole) log(level Priority, msg string) (err error) { formatMsg, err := b.formatMsg(level, msg) if err != nil { return } if b.syslogMode { fmt.Println(getSyslogPrefix(b.name), formatMsg) } else { fmt.Println(formatMsg) } return } func getSyslogPrefix(name string) (prefix string) { hostname, _ := os.Hostname() prefix = fmt.Sprintf("%s %s %s[%d]:", time.Now().Format("Jan 2 15:04:05"), hostname, name, os.Getpid()) return } func (b *backendConsole) formatMsg(level Priority, msg string) (fmtMsg string, err error) { var levelStr string switch level { case LevelDebug: levelStr = "" case LevelInfo: levelStr = "" case LevelWarning: levelStr = "" case LevelError: levelStr = "" case LevelPanic: levelStr = "" case LevelFatal: levelStr = "" default: err = errUnknownLogLevel return } fmtMsg = levelStr + " " + msg return } func (b *backendConsole) close() (err error) { return } go-lib-5.6.0.9/log/backend_syslog.go000664 000000 000000 00000003565 13753517240 017141 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package log import ( "log/syslog" ) const defaultSyslogTagPrefix = "" var ( // SyslogTagPrefix define the prefix of syslog tag, default is // empty. SyslogTagPrefix = defaultSyslogTagPrefix ) type backendSyslog struct { name string writer *syslog.Writer } func newBackendSyslog(name string) (b *backendSyslog) { b = &backendSyslog{} b.name = name var err error b.writer, err = newSyslogWriter(name) if err != nil { std.Println(" syslog is not available:", err) return nil } return } func newSyslogWriter(name string) (l *syslog.Writer, err error) { tag := SyslogTagPrefix + name l, err = syslog.New(syslog.LOG_DAEMON, tag) return } func (b *backendSyslog) log(level Priority, msg string) (err error) { switch level { case LevelDebug: err = b.writer.Debug(msg) case LevelInfo: err = b.writer.Info(msg) case LevelWarning: err = b.writer.Warning(msg) case LevelError: err = b.writer.Err(msg) case LevelPanic: err = b.writer.Emerg(msg) case LevelFatal: err = b.writer.Emerg(msg) default: err = errUnknownLogLevel } return } func (b *backendSyslog) close() (err error) { err = b.writer.Close() return } go-lib-5.6.0.9/log/logger.go000664 000000 000000 00000026345 13753517240 015432 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package log import ( "encoding/json" "fmt" "io/ioutil" golog "log" "os" "path/filepath" "reflect" "regexp" "runtime" "sync" "pkg.deepin.io/lib/utils" ) const ( defaultDebugEnv = "DDE_DEBUG" defaultDebugLelveEnv = "DDE_DEBUG_LEVEL" defaultDebugMatchEnv = "DDE_DEBUG_MATCH" defaultDebugFile = "/var/cache/dde_debug" crashReporterExe = "/usr/bin/deepin-crash-reporter" // TODO ) // Priority is the data type of log level. type Priority int // Definitions of log level, the larger of the value, the higher of // the priority. const ( LevelDisable Priority = iota LevelFatal LevelPanic LevelError LevelWarning LevelInfo LevelDebug ) var ( // DebugEnv is the name of environment variable that used to // enable debug mode , if exists the default log level will be // "LevelDebug". DebugEnv = defaultDebugEnv // DebugLevelEnv is the name of environment variable that used to // control the log level, could be "debug", "info", "warning", // "error", "fatal" and "disable". DebugLevelEnv = defaultDebugLelveEnv // DebugMatchEnv is the name of environment variable that used to // enable debug mode for target logger object. DebugMatchEnv = defaultDebugMatchEnv // DebugFile if the file name that if exist the default log level // will be "LevelDebug". DebugFile = defaultDebugFile ) var ( errUnknownLogLevel = fmt.Errorf("unknown log level") std = golog.New(os.Stderr, "", golog.Lshortfile) ) // Backend defines interface of logger's back-ends. type Backend interface { log(level Priority, msg string) error close() error } // Logger is a wrapper object to access Logger dbus service. type Logger struct { name string level Priority backends []Backend backendsLock sync.Mutex config *restartConfig } // NewLogger create a Logger object, which need a string as name to // register Logger dbus service, if the environment variable exists // which name stores in variable "DebugEnv", the default log level // will be "LevelDebug" or is "LevelInfo". func NewLogger(name string) (l *Logger) { // ignore panic defer func() { if err := recover(); err != nil { std.Println(" dbus unavailable,", err) } }() l = &Logger{name: name} l.config = newRestartConfig(name) l.level = getDefaultLogLevel(name) l.AddBackendConsole() l.AddBackendSyslog() return } // parse environment variables to get default log level func getDefaultLogLevel(name string) (level Priority) { level = LevelInfo if utils.IsEnvExists(DebugLevelEnv) { switch os.Getenv(DebugLevelEnv) { case "debug": level = LevelDebug case "info": level = LevelInfo case "warning": level = LevelWarning case "error": level = LevelError case "fatal": level = LevelFatal case "disable": level = LevelDisable } } if utils.IsEnvExists(DebugEnv) || utils.IsFileExist(DebugFile) { if !utils.IsEnvExists(DebugLevelEnv) { level = LevelDebug } } if utils.IsEnvExists(DebugMatchEnv) { if matchLogger(name, os.Getenv(DebugMatchEnv)) { if !utils.IsEnvExists(DebugLevelEnv) { level = LevelDebug } } else { level = LevelDisable } } return } func matchLogger(name, expr string) bool { reg, err := regexp.Compile(expr) if err != nil { std.Printf("match variable $%s failed %v\n", DebugMatchEnv, err) return false } return reg.Match([]byte(name)) } // SetLogLevel reset the log level. func (l *Logger) SetLogLevel(level Priority) *Logger { l.level = level return l } // GetLogLevel return the log level. func (l *Logger) GetLogLevel() Priority { return l.level } // ResetBackends clear all backends. func (l *Logger) ResetBackends() { for _, b := range l.backends { _ = b.close() } l.backends = nil } // AddBackend append a log back-end. func (l *Logger) AddBackend(b Backend) bool { l.backendsLock.Lock() defer l.backendsLock.Unlock() if utils.IsInterfaceNil(b) { return false } l.backends = append(l.backends, b) return true } // RemoveBackend remove all back-end with target type. func (l *Logger) RemoveBackend(b Backend) { len := len(l.backends) targetType := reflect.TypeOf(b) for i := len - 1; i >= 0; i-- { itemType := reflect.TypeOf(l.backends[i]) if itemType == targetType { l.doRemoveBackend(i) } } } func (l *Logger) doRemoveBackend(i int) { l.backendsLock.Lock() defer l.backendsLock.Unlock() _ = l.backends[i].close() l.backends[i] = nil newLen := len(l.backends) - 1 copy(l.backends[i:], l.backends[i+1:]) l.backends[newLen] = nil l.backends = l.backends[:newLen] } // AddBackendConsole append a console back-end. func (l *Logger) AddBackendConsole() bool { return l.AddBackend(newBackendConsole(l.name)) } // RemoveBackendConsole remove all console back-end. func (l *Logger) RemoveBackendConsole() { l.RemoveBackend(&backendConsole{}) } // AddBackendSyslog append a syslog back-end. func (l *Logger) AddBackendSyslog() bool { return l.AddBackend(newBackendSyslog(l.name)) } // RemoveBackendSyslog remove all console back-end. func (l *Logger) RemoveBackendSyslog() { l.RemoveBackend(&backendSyslog{}) } // SetRestartCommand reset the command and argument when restart after fatal. func (l *Logger) SetRestartCommand(exefile string, args ...string) { l.config.RestartCommand = append([]string{exefile}, args...) } // AddExtArgForRestart add the command option which be used when // process fataled and restart by Logger dbus service. func (l *Logger) AddExtArgForRestart(arg string) { if !isStringInArray(arg, l.config.RestartCommand[1:]) { l.config.RestartCommand = append(l.config.RestartCommand, arg) } } // BeginTracing log function information when entering it. func (l *Logger) BeginTracing() { // TODO // funcName, file, line, ok := getCallerFuncInfo(2) // if !ok { // return // } // msg := fmt.Sprintf("%s:%d %s begin", filepath.Base(file), line, funcName) // l.doLog(LevelInfo, msg) } // EndTracing log function information when leaving it. func (l *Logger) EndTracing() { // TODO // funcName, file, line, ok := getCallerFuncInfo(2) // if !ok { // return // } // msg := fmt.Sprintf("%s:%d %s end", filepath.Base(file), line, funcName) // l.doLog(LevelInfo, msg) } func (l *Logger) isNeedLog(level Priority) bool { return level <= l.level } func (l *Logger) isNeedTraceMore(level Priority) bool { return level <= LevelError } func (l *Logger) log(level Priority, v ...interface{}) { if !l.isNeedLog(level) { return } s := buildMsg(3, l.isNeedTraceMore(level), v...) l.doLog(level, s) } func (l *Logger) logf(level Priority, format string, v ...interface{}) { if !l.isNeedLog(level) { return } s := buildFormatMsg(3, l.isNeedTraceMore(level), format, v...) l.doLog(level, s) } func (l *Logger) doLog(level Priority, msg string) { for _, b := range l.backends { _ = b.log(level, msg) } } func buildMsg(calldepth int, loop bool, v ...interface{}) (msg string) { s := fmtSprint(v...) msg = doBuildMsg(calldepth+1, loop, s) return } func buildFormatMsg(calldepth int, loop bool, format string, v ...interface{}) (msg string) { s := fmt.Sprintf(format, v...) msg = doBuildMsg(calldepth+1, loop, s) return } func doBuildMsg(calldepth int, loop bool, s string) (msg string) { var file, lastFile string var line, lastLine int var ok bool _, file, line, ok = runtime.Caller(calldepth) lastFile, lastLine = file, line msg = fmt.Sprintf("%s:%d: %s", filepath.Base(file), line, s) if loop && ok { for { calldepth++ _, file, line, ok = runtime.Caller(calldepth) if file == lastFile && line == lastLine { // prevent infinite loop for that some platforms not // works well, e.g. mips break } if ok { msg = fmt.Sprintf("%s\n -> %s:%d", msg, filepath.Base(file), line) } lastFile, lastLine = file, line } } return } // Debug log a message in "debug" level. func (l *Logger) Debug(v ...interface{}) { l.log(LevelDebug, v...) } // Debugf formats message according to a format specifier and log it in "debug" level. func (l *Logger) Debugf(format string, v ...interface{}) { l.logf(LevelDebug, format, v...) } // Info log a message in "info" level. func (l *Logger) Info(v ...interface{}) { l.log(LevelInfo, v...) } // Infof formats message according to a format specifier and log it in "info" level. func (l *Logger) Infof(format string, v ...interface{}) { l.logf(LevelInfo, format, v...) } // Warning log a message in "warning" level. func (l *Logger) Warning(v ...interface{}) { l.log(LevelWarning, v...) } // Warningf formats message according to a format specifier and log it in "warning" level. func (l *Logger) Warningf(format string, v ...interface{}) { l.logf(LevelWarning, format, v...) } // Error log a message in "error" level. func (l *Logger) Error(v ...interface{}) { l.log(LevelError, v...) } // Errorf formats message according to a format specifier and log it in "error" level. func (l *Logger) Errorf(format string, v ...interface{}) { l.logf(LevelError, format, v...) } // Panic is equivalent to Error() followed by a call to panic(). func (l *Logger) Panic(v ...interface{}) { l.log(LevelPanic, v...) s := fmtSprint(v...) panic(s) } // Panicf is equivalent to Errorf() followed by a call to panic(). func (l *Logger) Panicf(format string, v ...interface{}) { l.logf(LevelPanic, format, v...) s := fmt.Sprintf(format, v...) panic(s) } // Fatal is equivalent to Error() followed by a call to os.Exit(1). func (l *Logger) Fatal(v ...interface{}) { l.log(LevelFatal, v...) l.launchCrashReporter() os.Exit(1) } // Fatalf is equivalent to Errorf() followed by a call to os.Exit(1). func (l *Logger) Fatalf(format string, v ...interface{}) { l.logf(LevelFatal, format, v...) l.launchCrashReporter() os.Exit(1) } func (l *Logger) launchCrashReporter() { // if deepin-crash-reporter exists, launch it if utils.IsFileExist(crashReporterExe) { // save config to a temporary json file l.config.LogDetail = "not ready" // TODO use lib/logquery to get log messages. fileContent, err := json.Marshal(l.config) if err != nil { l.Error(err) } // create temporary json file and it will be removed by deepin-crash-reporter f, err := ioutil.TempFile("", "deepin_crash_reporter_config_") defer func() { _ = f.Close() }() if err != nil { l.Error(err) } _, err = f.Write(fileContent) if err != nil { l.Error(err) } // launch crash reporter l.Infof("launch deepin-crash-reporter: %s %v", crashReporterExe, append(crashReporterArgs, f.Name())) _, err = os.StartProcess(crashReporterExe, append(crashReporterArgs, f.Name()), &os.ProcAttr{Files: []*os.File{os.Stdin, os.Stdout, os.Stderr}}) if err != nil { l.Error("launch deepin-crash-reporter failed:", err) } } } go-lib-5.6.0.9/log/logger_test.go000664 000000 000000 00000021631 13753517240 016462 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package log import ( "fmt" "io" "io/ioutil" "os" "regexp" "testing" C "gopkg.in/check.v1" ) var originStdout = os.Stdout var redirectStdoutFile = "testdata/stdout" var redirectStdout, _ = os.OpenFile(redirectStdoutFile, os.O_CREATE|os.O_RDWR, 0644) func Test(t *testing.T) { C.TestingT(t) } type testWrapper struct{} func init() { DebugFile = "" // disable outside debug file testWrapper := &testWrapper{} C.Suite(testWrapper) } func redirectOutput() { os.Stdout = redirectStdout } func restoreOutput() { os.Stdout = originStdout } func resetOutput() { _ = redirectStdout.Truncate(0) _, _ = redirectStdout.Seek(0, io.SeekStart) } func readOutput() string { fileContent, err := ioutil.ReadFile(redirectStdoutFile) if err != nil { std.Println("read stdout file failed:", err) } return string(fileContent) } func checkOutput(c *C.C, regfmt string, preferResult bool) { output := readOutput() result, _ := regexp.MatchString(regfmt, output) if result != preferResult { c.Errorf("match output failed: `%s`, `%#v`", regfmt, output) } } func (*testWrapper) BenchmarkSyslog(c *C.C) { b := newBackendSyslog("benchSyslog") for i := 0; i < c.N; i++ { _ = b.log(LevelInfo, "test") } } func (*testWrapper) TestGeneral(c *C.C) { defer func() { if err := recover(); err != nil { std.Println("catch panic:", err) } }() redirectOutput() defer restoreOutput() defer resetOutput() logger := NewLogger("logger_test") logger.SetLogLevel(LevelDebug) resetOutput() logger.Debug("test debug") checkOutput(c, `^ logger_test.go:\d+: test debug\n$`, true) resetOutput() logger.Info("test info") checkOutput(c, `^ logger_test.go:\d+: test info\n$`, true) resetOutput() logger.Info("test info multi-lines\n\nthe thread line and following two empty lines\n\n") checkOutput(c, `^ logger_test.go:\d+: test info multi-lines\n\nthe thread line and following two empty lines\n\n\n$`, true) resetOutput() logger.Warning("test warning:", fmt.Errorf("error message"), "append string") checkOutput(c, `^ logger_test.go:\d+: test warning: error message append string\n$`, true) resetOutput() logger.Warning("test warning:", fmt.Errorf("error message")) checkOutput(c, `^ logger_test.go:\d+: test warning: error message\n$`, true) resetOutput() logger.Warningf("test warningf: %v", fmt.Errorf("error message")) checkOutput(c, `^ logger_test.go:\d+: test warningf: error message\n$`, true) resetOutput() logger.Error("test error:", fmt.Errorf("error message")) checkOutput(c, `^ logger_test.go:\d+: test error: error message\n( -> \w+\.\w+:\d+\n)+$`, true) resetOutput() logger.Errorf("test errorf: %v", fmt.Errorf("error message")) checkOutput(c, `^ logger_test.go:\d+: test errorf: error message\n( -> \w+\.\w+:\d+\n)+$`, true) testPanicFunc := func() { defer func() { if err := recover(); err != nil { logger.Info("got panic") } }() logger.Panic("test panic") } resetOutput() testPanicFunc() checkOutput(c, `^ logger_test.go:\d+: test panic\n( -> \w+\.\w+:\d+\n)+ logger_test.go:\d+: got panic\n$`, true) } // TODO: remove func (*testWrapper) TestFuncTracing(c *C.C) { defer func() { if err := recover(); err != nil { std.Println("catch error:", err) } }() logger := NewLogger("logger_test") logger.BeginTracing() defer logger.EndTracing() defer func() { logger.EndTracing() }() logger.EndTracing() subFunc := func() { logger.BeginTracing() logger.EndTracing() } go subFunc() panic("test panic") } func (*testWrapper) TestIsNeedLog(c *C.C) { logger := &Logger{} logger.SetLogLevel(LevelInfo) c.Check(logger.isNeedLog(LevelDebug), C.Equals, false) c.Check(logger.isNeedLog(LevelInfo), C.Equals, true) c.Check(logger.isNeedLog(LevelWarning), C.Equals, true) c.Check(logger.isNeedLog(LevelError), C.Equals, true) c.Check(logger.isNeedLog(LevelPanic), C.Equals, true) c.Check(logger.isNeedLog(LevelFatal), C.Equals, true) logger.SetLogLevel(LevelDebug) c.Check(logger.isNeedLog(LevelDebug), C.Equals, true) c.Check(logger.isNeedLog(LevelInfo), C.Equals, true) c.Check(logger.isNeedLog(LevelWarning), C.Equals, true) c.Check(logger.isNeedLog(LevelError), C.Equals, true) c.Check(logger.isNeedLog(LevelPanic), C.Equals, true) c.Check(logger.isNeedLog(LevelFatal), C.Equals, true) } func (*testWrapper) TestIsNeedTraceMore(c *C.C) { logger := &Logger{} logger.SetLogLevel(LevelInfo) c.Check(logger.isNeedTraceMore(LevelDebug), C.Equals, false) c.Check(logger.isNeedTraceMore(LevelInfo), C.Equals, false) c.Check(logger.isNeedTraceMore(LevelWarning), C.Equals, false) c.Check(logger.isNeedTraceMore(LevelError), C.Equals, true) c.Check(logger.isNeedTraceMore(LevelPanic), C.Equals, true) c.Check(logger.isNeedTraceMore(LevelFatal), C.Equals, true) } func (*testWrapper) TestAddRemoveBackend(c *C.C) { logger := &Logger{} var backendNull Backend logger.AddBackend(backendNull) c.Check(len(logger.backends), C.Equals, 0) var backendConsoleNull *backendConsole logger.AddBackend(backendConsoleNull) c.Check(len(logger.backends), C.Equals, 0) logger.ResetBackends() logger.AddBackendConsole() c.Check(len(logger.backends), C.Equals, 1) logger.AddBackendConsole() c.Check(len(logger.backends), C.Equals, 2) logger.RemoveBackendConsole() c.Check(len(logger.backends), C.Equals, 0) } func (*testWrapper) TestDebugFile(c *C.C) { oldDebugFile := DebugFile DebugFile = "testdata/dde_debug" defer func() { DebugFile = oldDebugFile }() os.Clearenv() defer os.Clearenv() _ = os.Remove(DebugFile) c.Check(getDefaultLogLevel("test_debug_file"), C.Equals, LevelInfo) _, _ =os.Create(DebugFile) c.Check(getDefaultLogLevel("test_debug_file"), C.Equals, LevelDebug) } func (*testWrapper) TestDebugEnv(c *C.C) { os.Clearenv() defer os.Clearenv() c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelInfo) os.Clearenv() _ = os.Setenv("DDE_DEBUG", "") c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelDebug) os.Clearenv() _ = os.Setenv("DDE_DEBUG", "1") c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelDebug) } func (*testWrapper) TestDebugLevelEnv(c *C.C) { os.Clearenv() defer os.Clearenv() c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelInfo) _ = os.Setenv("DDE_DEBUG_LEVEL", "debug") c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelDebug) _ = os.Setenv("DDE_DEBUG_LEVEL", "warning") c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelWarning) } func (*testWrapper) TestDebugMatchEnv(c *C.C) { os.Clearenv() defer os.Clearenv() _ = os.Setenv("DDE_DEBUG_MATCH", "test1") c.Check(getDefaultLogLevel("test1"), C.Equals, LevelDebug) c.Check(getDefaultLogLevel("test2"), C.Equals, LevelDisable) _ = os.Setenv("DDE_DEBUG_MATCH", "test1|test2") c.Check(getDefaultLogLevel("test1"), C.Equals, LevelDebug) c.Check(getDefaultLogLevel("test2"), C.Equals, LevelDebug) _ = os.Setenv("DDE_DEBUG_MATCH", "not match") c.Check(getDefaultLogLevel("test1"), C.Equals, LevelDisable) c.Check(getDefaultLogLevel("test2"), C.Equals, LevelDisable) } func (*testWrapper) TestDebugMixEnv(c *C.C) { os.Clearenv() defer os.Clearenv() _ = os.Setenv("DDE_DEBUG", "1") _ = os.Setenv("DDE_DEBUG_LEVEL", "warning") c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelWarning) os.Clearenv() _ = os.Setenv("DDE_DEBUG_LEVEL", "error") _ = os.Setenv("DDE_DEBUG_MATCH", "test_env") c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelError) os.Clearenv() _ = os.Setenv("DDE_DEBUG_LEVEL", "error") _ = os.Setenv("DDE_DEBUG_MATCH", "not match") c.Check(getDefaultLogLevel("test_env"), C.Equals, LevelDisable) } func (*testWrapper) TestDebugConsoleEnv(c *C.C) { os.Clearenv() defer os.Clearenv() _ = os.Setenv("DDE_DEBUG_CONSOLE", "1") console := newBackendConsole("test-console") c.Check(console.syslogMode, C.Equals, true) redirectOutput() defer restoreOutput() resetOutput() _ = console.log(LevelInfo, "this line shows as syslog format in console") checkOutput(c, `\w+ \d+ \d{2}:\d{2}:\d{2} .* test-console\[\d+\]: this line shows as syslog format in console\n$`, true) } func (*testWrapper) TestFmtSprint(c *C.C) { c.Check(fmtSprint(""), C.Equals, "") c.Check(fmtSprint("a", "b", "c"), C.Equals, "a b c") c.Check(fmtSprint("a\n", "b\n", "c\n"), C.Equals, "a\n b\n c\n") } go-lib-5.6.0.9/log/restart_config.go000664 000000 000000 00000003255 13753517240 017157 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package log import ( "os" "path/filepath" "strings" ) // TODO var crashReporterArgs = []string{crashReporterExe, "--remove-config", "--config"} // restartConfig stores data to be used by deepin-crash-reporter type restartConfig struct { AppName string RestartCommand []string RestartEnv map[string]string RestartDirectory string LogDetail string } func newRestartConfig(logname string) *restartConfig { config := &restartConfig{} config.AppName = logname config.RestartCommand = os.Args config.RestartCommand[0], _ = filepath.Abs(os.Args[0]) config.RestartDirectory, _ = os.Getwd() // setup envrionment variables config.RestartEnv = make(map[string]string) environs := os.Environ() for _, env := range environs { values := strings.SplitN(env, "=", 2) // values[0] is environment variable name, values[1] is the value if len(values) == 2 { config.RestartEnv[values[0]] = values[1] } } return config } go-lib-5.6.0.9/log/testdata/000775 000000 000000 00000000000 13753517240 015423 5ustar00rootroot000000 000000 go-lib-5.6.0.9/log/testdata/dde_debug000664 000000 000000 00000000000 13753517240 017236 0ustar00rootroot000000 000000 go-lib-5.6.0.9/log/testdata/stdout000664 000000 000000 00000000000 13753517240 016656 0ustar00rootroot000000 000000 go-lib-5.6.0.9/log/utils.go000664 000000 000000 00000002111 13753517240 015274 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package log import ( "fmt" "strings" ) // same with fmt.Sprintln() but trim the additional end line func fmtSprint(v ...interface{}) (s string) { s = fmt.Sprintln(v...) s = strings.TrimSuffix(s, "\n") return } func isStringInArray(s string, arr []string) bool { for _, t := range arr { if t == s { return true } } return false } go-lib-5.6.0.9/mime/000775 000000 000000 00000000000 13753517240 013760 5ustar00rootroot000000 000000 go-lib-5.6.0.9/mime/mime.go000664 000000 000000 00000005300 13753517240 015234 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package mime import ( "fmt" "pkg.deepin.io/gir/gio-2.0" dutils "pkg.deepin.io/lib/utils" ) const ( MimeTypeGtk = "application/x-gtk-theme" MimeTypeIcon = "application/x-icon-theme" MimeTypeCursor = "application/x-cursor-theme" ) // Query query file mime type func Query(uri string) (string, error) { file := dutils.DecodeURI(uri) // determine whether theme type mime, err := queryThemeMime(file) if err == nil { return mime, nil } return doQueryFile(file) } // Set 'mime' default app to 'desktopId' // // desktopId: the basename of the desktop file func SetDefaultApp(mime, desktopId string) error { cur, _ := GetDefaultApp(mime, false) if cur == desktopId { return nil } app := gio.NewDesktopAppInfo(desktopId) if app == nil { return fmt.Errorf("Invalid id '%v'", desktopId) } defer app.Unref() _, err := app.SetAsDefaultForType(mime) return err } // Get default app for 'mime' // // ret0: desktopId func GetDefaultApp(mime string, mustSupportURIs bool) (string, error) { app := gio.AppInfoGetDefaultForType(mime, false) if app == nil { return "", fmt.Errorf("Invalid mime '%v'", mime) } defer app.Unref() if mustSupportURIs { if !app.SupportsUris() { return "", fmt.Errorf("Not found app supported '%s' and uris", mime) } } return app.GetId(), nil } // Get app list of supported the 'mime' // ret0: desktopId list func GetAppList(mime string) []string { apps := gio.AppInfoGetAllForType(mime) var list []string for _, app := range apps { list = append(list, app.GetId()) app.Unref() } return list } func doQueryFile(file string) (string, error) { if !dutils.IsFileExist(file) { return "", fmt.Errorf("Not found the file '%s'", file) } gf := gio.FileNewForPath(file) defer gf.Unref() info, err := gf.QueryInfo(gio.FileAttributeStandardContentType, gio.FileQueryInfoFlagsNone, nil) if err != nil { return "", err } defer info.Unref() return info.GetAttributeString( gio.FileAttributeStandardContentType), nil } go-lib-5.6.0.9/mime/mime_test.go000664 000000 000000 00000002335 13753517240 016300 0ustar00rootroot000000 000000 /* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ package mime import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestQueryURI(t *testing.T) { Convey("Query uri mime", t, func(c C) { var infos = []struct { uri string mime string }{ { uri: "testdata/data.txt", mime: "text/plain", }, { uri: "testdata/Deepin/index.theme", mime: MimeTypeGtk, }, } for _, info := range infos { m, err := Query(info.uri) c.So(m, ShouldEqual, info.mime) c.So(err, ShouldBeNil) } }) } go-lib-5.6.0.9/mime/testdata/000775 000000 000000 00000000000 13753517240 015571 5ustar00rootroot000000 000000 go-lib-5.6.0.9/mime/testdata/Deepin/000775 000000 000000 00000000000 13753517240 016775 5ustar00rootroot000000 000000 go-lib-5.6.0.9/mime/testdata/Deepin/cursors/000775 000000 000000 00000000000 13753517240 020475 5ustar00rootroot000000 000000 go-lib-5.6.0.9/mime/testdata/Deepin/cursors/left_ptr000664 000000 000000 00000207000 13753517240 022236 0ustar00rootroot000000 000000 XcurL p 0@=`}$2    /// <<< DDD PPP $$$]]]qqq +++fffkkk  &&&222sss]]]   ---:::PPPt  (((444AAAKKKo  <<( AAAZ,,,( PPPt٣u?%.&$0002" ()(}}}'&qqq% mmm$ ___# ###YYY" '''MMMy! !!!,,,???n  %%%222<<>>,,,\  ###)))000FFF###T  '''---333JJJK  $$$***000777RRRG !!!(((...444:::WWWA  %%%+++111888>>>___ <  """)))///555;;;BBBhhh8  &&&,,,222999???EEEjjj5 ###***000666<<>>000~;" ppp??? ? ttt KKKe' wwwt%%%{;;;8nR@ [[[W$ mM. ***N7774kK+  pppDgJ* 000M333[[[P$  }}}XF)AAArrrP%  www68& ***I qDCCCh𒒒lO-  2GROA,  &$ $@@@ 2eeee]]]i YYYo HHHm% >>>l( :::k( ...a' &&&[& ###X& $$$P% +++K$ 000G# 777 B# ???>" EEE<! """LLL9   $$$QQQ5  """'''[[[5  %%%***eee4 ###(((---jjj2 !!!&&&+++///ttt2 $$$)))---222yyy1 """'''+++0005550   %%%)))...333777/  ###''',,,111555:::}}}.  !!!%%%***///333888===ppp-  ###(((---111666;;;???jjj,  !!!&&&+++///444999>>>BBB\\\,  $$$)))---222777<<<@@@FFFOOO}+  """'''+++000555:::>>>CCCIIIJJJy*   %%%)))...333888<<>>o)  ###''',,,111666:::???DDDHHHLLL111e(  ,,,***^&  ###T" cccE''' ppp????????????????????????????????????uH!VVV### sss{j[SONMMLIC9+^^^  %%%YC5.,+++*'"ccc S7# fff &&&g8 ooo C%ttt ... X1 wwwwhk @"wwwt`LB 888Q/t]E1(D> }}}s\C, GGGL+wwwq[B* @e7 pppmZA)  {{{ ((({> jjjaU@) !!!B___gB"dddJJ;(  _>  ]]]o,51# =nR3     777]aaamX>%  5J[bc\O=( -9@@:/" !! $```2   '! /% 4( 7( }}}7( nnn7( aaa7' xxxZZZ6& }}}MMM~5& HHHz5% <<.  """%%%(((DDD=,  !!!$$$'''***KKK<,  """&&&))),,,OOO;+  !!!$$$'''+++...WWW;+   ###&&&))),,,///```:+  """%%%(((+++...111ccc:)   ###'''***---000333lll9)  """%%%(((+++///222555vvv8(  !!!$$$'''***---000444777zzzqqq8(  ###&&&))),,,///222555888kkk7'  !!!$$$(((+++...111444777:::]]]6'   ###&&&))),,,000333666999<<>>KKK}5&   $$$'''***---000333666999===@@@???t4% """%%%(((,,,///222555888;;;>>>BBB:::p4% !!!$$$'''***---111444777:::===@@@DDD000g3$  ###&&&))),,,///222555999<<>>AAADDDIII###\2#  ###&&&)))---000333666999<<>>AAADDDGGGLLLQ1" !!!$$$'''***---000333666:::===@@@CCCFFFHHHOOOM0"  """%%%))),,,///222555888;;;???BBBEEEHHHHHHPPP H/!  !!!$$$'''***...111444777:::===@@@CCCGGGHHHHHHSSSE/   AAAA-  <*  eee5% ,  tttyyy\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ 7 GGG  woiebaaaa`_^[VOE:, IIIBBB vj^UOLJIIHHHGFC>7/%LLL '''o_PD;53111110/.+'"UUU<<<  rYG7,%  ZZZ 000YD2# ZZZ::: ^G2" eee ;;;M8% gggzzz777 V@+iii GGGjjjJ4! tttwp222 T>)wwwyyy}qf^Z VVVPPPH2  wwwvvv|naSJF--- R<( kkk{n^OA74; fff888F1eeezm]L=/&%+,,, P:& ___zm\L;, / vvvkD.YYYyl\K:+"&&& ###M7# TTTwk\J:* . U>( MMMti[J9)   ### nnn[D-HHHleYI8)  1 _G0AAA_^UG8)   !!! qqq_H1<<,   $4???t缼bbbvoh]P@0!   &5COX^`_ZRH</" %0:BGIGC<3) &,010,'      go-lib-5.6.0.9/mime/testdata/Deepin/gtk-2.0/000775 000000 000000 00000000000 13753517240 020057 5ustar00rootroot000000 000000 go-lib-5.6.0.9/mime/testdata/Deepin/gtk-2.0/gtkrc000664 000000 000000 00000056214 13753517240 021124 0ustar00rootroot000000 000000 # Numix GTK Theme gtk-color-scheme = "bg_color:#fdfdfd\nfg_color:#282828\nbase_color:#ffffff\ntext_color:#333333\nselected_bg_color:#2CA7F8\nselected_fg_color:#f9f9f9\ntooltip_bg_color:#2d2d2d\ntooltip_fg_color:#dedede\ntitlebar_bg_color:#252627\ntitlebar_fg_color:#dcdcdc\nmenubar_bg_color:#252627\nmenubar_fg_color:#dcdcdc\ntoolbar_bg_color:#dedede\ntoolbar_fg_color:#555555\nmenu_bg_color:#2d2d2d\nmenu_fg_color:#dcdcdc\npanel_bg_color:#252627\npanel_fg_color:#dcdcdc\nlink_color:#007aff" # Default Style style "murrine-default" { GtkArrow::arrow-scaling= 0.6 GtkButton::child-displacement-x = 0 GtkButton::child-displacement-y = 0 GtkButton::default-border = { 0, 0, 0, 0 } GtkButtonBox::child-min-height = 26 GtkCheckButton::indicator-size = 16 # The following line hints to gecko (and possibly other appliations) # that the entry should be drawn transparently on the canvas. # Without this, gecko will fill in the background of the entry. GtkEntry::honors-transparent-bg-hint = 1 GtkEntry::state-hint = 0 GtkExpander::expander-size = 16 GtkImage::x-ayatana-indicator-dynamic = 1 GtkMenu::horizontal-padding = 0 GtkMenu::vertical-padding = 0 GtkMenuBar::internal-padding = 0 GtkMenuBar::window-dragging = 1 GtkMenuItem::arrow-scaling= 0.5 GtkPaned::handle-size = 1 GtkProgressBar::min-horizontal-bar-height = 12 GtkProgressBar::min-vertical-bar-width = 12 GtkRange::trough-border = 0 GtkRange::slider-width = 12 GtkRange::stepper-size = 12 GtkRange::stepper_spacing = 0 GtkRange::trough-under-steppers = 1 GtkScale::slider-length = 16 GtkScale::slider-width = 16 GtkScale::trough-side-details = 1 GtkScrollbar::activate-slider = 1 GtkScrollbar::has-backward-stepper = 0 GtkScrollbar::has-forward-stepper = 0 GtkScrollbar::has-secondary-backward-stepper = 0 GtkScrollbar::has-secondary-forward-stepper = 0 GtkScrollbar::min-slider-length = 80 GtkScrollbar::slider-width = 4 GtkScrollbar::trough-border = 0 GtkScrolledWindow::scrollbar-spacing = 0 GtkScrolledWindow::scrollbars-within-bevel = 1 GtkSeparatorMenuItem::horizontal-padding = 0 GtkToolbar::internal-padding = 0 GtkTreeView::expander-size = 11 GtkTreeView::vertical-separator = 0 GtkWidget::focus-line-width = 1 # The following line prevents the Firefox tabs # from jumping a few pixels when you create a new tab GtkWidget::focus-padding = 0 GtkWidget::wide-separators = 1 GtkWidget::separator-width = 1 GtkWidget::separator-height = 1 GtkWindow::resize-grip-height = 0 GtkWindow::resize-grip-width = 0 WnckTasklist::fade-overlay-rect = 0 GnomeHRef::link_color = @link_color GtkHTML::link-color = @link_color GtkIMHtmlr::hyperlink-color = @link_color GtkIMHtml::hyperlink-color = @link_color GtkWidget::link-color = @link_color GtkWidget::visited-link-color = @text_color GtkToolbar::shadow-type = GTK_SHADOW_NONE # Makes toolbars flat and unified GtkMenuBar::shadow-type = GTK_SHADOW_NONE # Makes menubars flat and unified xthickness = 1 ythickness = 1 fg[NORMAL] = @fg_color fg[PRELIGHT] = @fg_color fg[SELECTED] = @selected_fg_color fg[ACTIVE] = @fg_color fg[INSENSITIVE] = mix (0.5, @bg_color, @fg_color) bg[NORMAL] = @bg_color bg[PRELIGHT] = shade (1.02, @bg_color) bg[SELECTED] = @selected_bg_color bg[ACTIVE] = shade (0.9, @bg_color) bg[INSENSITIVE] = @bg_color base[NORMAL] = @base_color base[PRELIGHT] = shade (0.95, @base_color) base[SELECTED] = @selected_bg_color base[ACTIVE] = @selected_bg_color base[INSENSITIVE] = shade (0.85, @base_color) text[NORMAL] = @text_color text[PRELIGHT] = @text_color text[SELECTED] = @selected_fg_color text[ACTIVE] = @selected_fg_color text[INSENSITIVE] = mix (0.5, @base_color, @text_color) engine "murrine" { animation = FALSE arrowstyle = 1 # 0 = normal arrows, 1 = filled arrows border_shades = { 1.0, 1.0 } # gradient to draw on border colorize_scrollbar = FALSE comboboxstyle = 0 # 0 = normal combobox, 1 = colorized combobox below arrow contrast = 0.8 # overal contrast with borders focusstyle = 1 # 0 = none, 1 = grey dotted, 2 = colored with fill, 3 = colored glow glazestyle = 0 # 0 = flat highlight, 1 = curved highlight, 2 = concave, 3 = top curved highlight, 4 = beryl highlight glowstyle = 0 # 0 = glow on top, 1 = glow on bottom, 2 = glow on top and bottom, 3 = glow on middle vertically, 4 = glow on middle horizontally, 5 = glow on all sides glow_shade = 1.0 # amount of glow gradient_shades = { 1.0, 1.0, 1.0, 1.0 } # gradient to draw on widgets highlight_shade = 1.0 # amount of highlight lightborder_shade = 1.0 # amount of inset light border lightborderstyle = 1 # 0 = lightborder on top side, 1 = lightborder on all sides listviewheaderstyle = 0 # 0 = flat, 1 = glassy, 2 = raised listviewstyle = 0 # 0 = none, 1 = dotted, 2 = line menubaritemstyle = 0 # 0 = menuitem look, 1 = button look menubarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient, 3 = striped menuitemstyle = 0 # 0 = flat, 1 = glassy, 2 = striped menustyle = 0 # 0 = none, 1 = vertical striped progressbarstyle = 0 # 0 = none, 1 = diagonal striped, 2 = vertical striped reliefstyle = 0 # 0 = flat, 1 = inset, 2 = shadow, 3 = shadow with gradient, 4 = stronger shadow with gradient roundness = 2 # roundness of widgets scrollbarstyle = 0 # 0 = none, 1 = circles, 2 = handles, 3 = diagonal stripes, 4 = diagonal stripes and handles, 5 = horizontal stripes, 6 = horizontal stripes and handles sliderstyle = 0 # 0 = none, 1 = handles stepperstyle = 1 # 0 = standard, 1 = integrated stepper handles toolbarstyle = 0 # 0 = flat, 1 = glassy, 2 = gradient } } style "murrine-wide" { xthickness = 2 ythickness = 2 } style "murrine-wider" { xthickness = 3 ythickness = 3 } style "murrine-thin" { xthickness = 0 ythickness = 0 } # Notebook style "murrine-notebook-bg" { bg[NORMAL] = @base_color bg[ACTIVE] = shade (0.87, @base_color) } style "murrine-notebook" = "murrine-notebook-bg" { xthickness = 2 ythickness = 2 engine "murrine" { roundness = 2 } } # Various Standard Widgets style "murrine-button" = "murrine-wider" { xthickness = 3 ythickness = 3 bg[NORMAL] = shade (0.96, @base_color) bg[PRELIGHT] = "#9ad7ff" bg[ACTIVE] = "#68c3ff" bg[INSENSITIVE] = shade (0.95, @bg_color) fg[NORMAL] = shade (0.95, @fg_color) engine "murrine" { contrast = 0.85 roundness = 3 gradient_shades = {1.05,1.0,1.0,0.98} border_shades = {1.10, 0.95} lightborderstyle = 1 # 0 = top side, 1 = all sides lightborder_shade = 1.3 highlight_shade = 1.03 focusstyle = 0 glowstyle = 0 # 0 = top, 1 = bottom, 2 = top and bottom, 3 = horizontal, 4 = centered glow glow_shade = 1.05 reliefstyle = 3 textstyle = 1 text_shade = 1.2 } } style "murrine-scrollbar" { bg[NORMAL] = mix (0.21, @fg_color, @bg_color) bg[PRELIGHT] = mix (0.31, @fg_color, @bg_color) bg[ACTIVE] = @selected_bg_color engine "murrine" { roundness = 0 contrast = 0.0 border_shades = { 0.9, 0.9 } trough_shades = { 0.97, 0.97 } trough_border_shades = { 1.0, 1.0 } } } style "murrine-overlay-scrollbar" { bg[ACTIVE] = shade (0.8, @bg_color) bg[INSENSITIVE] = shade (0.97, @bg_color) base[SELECTED] = shade (0.6, @base_color) base[INSENSITIVE] = shade (0.85, @base_color) } style "murrine-scale" = "murrine-thin" { bg[NORMAL] = @bg_color bg[ACTIVE] = @bg_color bg[SELECTED] = @selected_bg_color bg[INSENSITIVE] = shade (0.95, @bg_color) engine "murrine" { roundness = 8 gradient_shades = { 1.08, 1.08, 1.08, 1.08 } border_shades = { 1.0, 1.0 } trough_shades = { 1.08, 1.08 } trough_border_shades = { 0.8, 0.8 } } } style "murrine-progressbar" = "murrine-thin" { bg[NORMAL] = @bg_color bg[ACTIVE] = shade (1.08, @bg_color) fg[PRELIGHT] = @selected_fg_color engine "murrine" { roundness = 3 border_shades = { 1.2, 1.2 } trough_border_shades = { 0.9, 0.9 } } } style "murrine-treeview-header" = "murrine-button" { engine "murrine" { roundness = 0 } } style "murrine-treeview" { engine "murrine" { roundness = 0 } } style "murrine-frame-title" { fg[NORMAL] = lighter (@fg_color) } style "murrine-tooltips" { xthickness = 5 ythickness = 5 bg[NORMAL] = @tooltip_bg_color bg[SELECTED] = @tooltip_bg_color fg[NORMAL] = @tooltip_fg_color engine "murrine" { textstyle = 0 roundness = 2 rgba = FALSE } } style "murrine-spinbutton" = "murrine-button" { engine "murrine" { } } style "murrine-radiocheck" = "murrine-default" { bg[NORMAL] = @base_color bg[PRELIGHT] = "#9ad7ff" bg[SELECTED] = @base_color text[NORMAL] = @text_color text[PRELIGHT] = @text_color } style "murrine-entry" = "murrine-wider" { engine "murrine" { border_shades = { 1.15, 1.15 } } } style "metacity-frame" = "murrine-default" { bg[SELECTED] = @selected_bg_color } style "murrine-statusbar" { } style "murrine-comboboxentry" = "murrine-entry" { } style "murrine-hscale" = "murrine-scale" { } style "murrine-vscale" = "murrine-scale" { } style "murrine-hscrollbar" = "murrine-scrollbar" { } style "murrine-vscrollbar" = "murrine-scrollbar" { } # Menus style "murrine-menu" = "murrine-thin" { bg[NORMAL] = @menu_bg_color bg[PRELIGHT] = @selected_bg_color bg[SELECTED] = @selected_bg_color bg[ACTIVE] = @menu_bg_color bg[INSENSITIVE] = @menu_bg_color fg[NORMAL] = @menu_fg_color fg[PRELIGHT] = @selected_fg_color fg[SELECTED] = @selected_fg_color fg[ACTIVE] = @selected_fg_color fg[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color) text[NORMAL] = @menu_fg_color text[PRELIGHT] = @selected_fg_color text[SELECTED] = @selected_fg_color text[ACTIVE] = @selected_fg_color text[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color) engine "murrine" { roundness = 0 } } style "murrine-menu-item" = "murrine-wider" { bg[PRELIGHT] = @selected_bg_color bg[SELECTED] = @selected_bg_color bg[ACTIVE] = @selected_bg_color fg[NORMAL] = @menu_fg_color # Fix for XFCE menu text fg[PRELIGHT] = @selected_fg_color fg[SELECTED] = @selected_fg_color fg[ACTIVE] = @selected_fg_color fg[INSENSITIVE] = mix (0.5, @menu_bg_color, @menu_fg_color) engine "murrine" { textstyle = 0 border_shades = { 1.2, 1.2 } } } style "murrine-separator-menu-item" = "murrine-thin" { } style "murrine-menubar" { bg[NORMAL] = @menubar_bg_color bg[PRELIGHT] = mix (0.21, @menubar_fg_color, @menubar_bg_color) bg[SELECTED] = mix (0.21, @menubar_fg_color, @menubar_bg_color) bg[ACTIVE] = shade (0.9, @menubar_bg_color) bg[INSENSITIVE] = @menubar_bg_color fg[NORMAL] = @menubar_fg_color fg[PRELIGHT] = shade (1.08, @menubar_fg_color) fg[SELECTED] = shade (1.08, @menubar_fg_color) fg[ACTIVE] = @menubar_fg_color fg[INSENSITIVE] = mix (0.5, @menubar_bg_color, @menubar_fg_color) engine "murrine" { roundness = 0 } } style "murrine-menubaritem" { bg[NORMAL] = @menubar_bg_color bg[PRELIGHT] = mix (0.21, @menubar_fg_color, @menubar_bg_color) bg[SELECTED] = mix (0.21, @menubar_fg_color, @menubar_bg_color) bg[ACTIVE] = shade (0.9, @menubar_bg_color) bg[INSENSITIVE] = @menubar_bg_color fg[NORMAL] = @menubar_fg_color fg[PRELIGHT] = shade (1.08, @menubar_fg_color) fg[SELECTED] = shade (1.08, @menubar_fg_color) fg[ACTIVE] = @menubar_fg_color fg[INSENSITIVE] = mix (0.5, @menubar_bg_color, @menubar_fg_color) engine "murrine" { roundness = 0 } } # Toolbars style "murrine-toolbar" = "murrine-thin" { bg[NORMAL] = @base_color bg[PRELIGHT] = shade (1.02, @bg_color) bg[SELECTED] = @selected_bg_color bg[ACTIVE] = shade (0.9, @bg_color) bg[INSENSITIVE] = @bg_color fg[NORMAL] = @fg_color fg[PRELIGHT] = @fg_color fg[SELECTED] = @selected_fg_color fg[ACTIVE] = @fg_color fg[INSENSITIVE] = mix (0.5, @bg_color, @fg_color) engine "murrine" { } } style "murrine-toolbutton" = "murrine-button" { bg[NORMAL] = shade (1.08, @bg_color) bg[PRELIGHT] = shade (1.10, @bg_color) bg[SELECTED] = @selected_bg_color bg[ACTIVE] = shade (0.95, @bg_color) bg[INSENSITIVE] = shade (0.85, @bg_color) fg[NORMAL] = @fg_color fg[PRELIGHT] = @fg_color fg[SELECTED] = @selected_fg_color fg[ACTIVE] = @fg_color fg[INSENSITIVE] = mix (0.5, @bg_color, @fg_color) engine "murrine" { } } class "GtkToolbar" style "murrine-toolbar" class "GtkHandleBox" style "murrine-toolbar" widget_class "*Toolbar*.*Separator*" style "murrine-toolbar" # Panels style "murrine-panel" = "murrine-thin" { xthickness = 2 bg[NORMAL] = @panel_bg_color bg[PRELIGHT] = mix (0.21, @panel_fg_color, @panel_bg_color) bg[SELECTED] = mix (0.21, @panel_fg_color, @panel_bg_color) bg[ACTIVE] = shade (0.8, @panel_bg_color) bg[INSENSITIVE] = @panel_bg_color fg[NORMAL] = @panel_fg_color fg[PRELIGHT] = shade (1.08, @panel_fg_color) fg[SELECTED] = shade (1.08, @panel_fg_color) fg[ACTIVE] = @panel_fg_color fg[INSENSITIVE] = mix (0.5, @panel_bg_color, @panel_fg_color) base[NORMAL] = @panel_bg_color base[PRELIGHT] = mix (0.21, @panel_fg_color, @panel_bg_color) base[SELECTED] = mix (0.21, @panel_fg_color, @panel_bg_color) base[ACTIVE] = shade (0.9, @panel_bg_color) base[INSENSITIVE] = @panel_bg_color text[NORMAL] = @panel_fg_color text[PRELIGHT] = shade (1.08, @panel_fg_color) text[SELECTED] = shade (1.08, @panel_fg_color) text[ACTIVE] = @panel_fg_color text[INSENSITIVE] = mix (0.5, @panel_bg_color, @panel_fg_color) engine "murrine" { roundness = 0 contrast = 0.0 } } widget "*PanelWidget*" style "murrine-panel" widget "*PanelApplet*" style "murrine-panel" widget "*fast-user-switch*" style "murrine-panel" widget "*CPUFreq*Applet*" style "murrine-panel" widget "*indicator-applet*" style "murrine-panel" class "PanelApp*" style "murrine-panel" class "PanelToplevel*" style "murrine-panel" widget_class "*PanelToplevel*" style "murrine-panel" widget_class "*notif*" style "murrine-panel" widget_class "*Notif*" style "murrine-panel" widget_class "*Tray*" style "murrine-panel" widget_class "*tray*" style "murrine-panel" widget_class "*computertemp*" style "murrine-panel" widget_class "*Applet*Tomboy*" style "murrine-panel" widget_class "*Applet*Netstatus*" style "murrine-panel" widget "*gdm-user-switch-menubar*" style "murrine-panel" style "bold-panel-item" { font_name = "Bold" engine "murrine" { roundness = 0 } } widget "*Panel*MenuBar*" style "bold-panel-item" widget "*gimmie*" style "bold-panel-item" # widget_class "*Mail*" style "murrine-panel" # Disabled to fix Evolution bug # class "*Panel*" style "murrine-panel" # Disabled to fix bug # XFCE Styles style "workspace-switcher" = "murrine-panel" { bg[SELECTED] = @selected_bg_color } style "xfce-header" { bg[NORMAL] = shade (0.9, @bg_color) base[NORMAL] = shade (1.18, @bg_color) } style "xfdesktop-windowlist" { bg[NORMAL] = @base_color fg[INSENSITIVE] = shade (0.95, @base_color) text[INSENSITIVE] = shade (0.95, @base_color) } style "xfdesktop-icon-view" { XfdesktopIconView::label-alpha = 0 XfdesktopIconView::selected-label-alpha = 60 XfdesktopIconVIew::ellipsize-icon-labels = 1 base[NORMAL] = @selected_bg_color base[SELECTED] = @selected_bg_color base[ACTIVE] = @selected_bg_color fg[NORMAL] = @selected_fg_color fg[SELECTED] = @selected_fg_color fg[ACTIVE] = @selected_fg_color engine "murrine" { textstyle = 5 text_shade = 0.05 } } style "xfwm-tabwin" { Xfwm4TabwinWidget::border-width = 0 Xfwm4TabwinWidget::icon-size = 64 bg[NORMAL] = @menu_bg_color fg[NORMAL] = @menu_fg_color engine "murrine" { focusstyle = 0 } } style "xfsm-logout" { bg[NORMAL] = @menu_bg_color bg[ACTIVE] = @menu_bg_color bg[PRELIGHT] = shade (1.1, @menu_bg_color) bg[SELECTED] = shade (0.5, @menu_bg_color) bg[INSENSITIVE] = shade (1.3, @menu_bg_color) fg[NORMAL] = @menu_fg_color fg[PRELIGHT] = @menu_fg_color text[NORMAL] = @menu_fg_color engine "murrine" { } } style "xfsm-logout-button" { bg[NORMAL] = shade (1.2, @menu_bg_color) bg[PRELIGHT] = shade (1.4, @menu_bg_color) engine "murrine" { } } widget "*WnckPager*" style "workspace-switcher" widget "*Xfce*Panel*" style "murrine-panel" class "*Xfce*Panel*" style "murrine-panel" # Thunar Styles style "sidepane" { base[NORMAL] = @bg_color base[INSENSITIVE] = mix (0.4, shade (1.35, @selected_bg_color), shade (0.9, @base_color)) bg[NORMAL] = @bg_color text[NORMAL] = mix (0.9, @fg_color, @bg_color) } widget_class "*ThunarShortcutsView*" style "sidepane" widget_class "*ThunarTreeView*" style "sidepane" widget_class "*ThunarLocationEntry*" style "murrine-entry" # Gtk2 Open-File Dialog widget_class "*GtkFileChooserWidget.GtkFileChooserDefault.GtkVBox.GtkHPaned.GtkVBox.GtkScrolledWindow.GtkTreeView*" style "sidepane" widget_class "*GtkFileChooserWidget.GtkFileChooserDefault.GtkVBox.GtkHPaned.GtkVBox.GtkScrolledWindow.." style "murrine-treeview-header" # Google Chrome/Chromium Styles (requires 9.0.597 or newer) style "chromium-toolbar-button" { engine "murrine" { roundness = 2 textstyle = 0 } } style "chrome-gtk-frame" { ChromeGtkFrame::frame-color = @titlebar_bg_color ChromeGtkFrame::inactive-frame-color = @titlebar_bg_color ChromeGtkFrame::frame-gradient-size = 0 ChromeGtkFrame::frame-gradient-color = @titlebar_bg_color ChromeGtkFrame::incognito-frame-color = @titlebar_bg_color ChromeGtkFrame::incognito-inactive-frame-color = @titlebar_bg_color ChromeGtkFrame::incognito-frame-gradient-size = 0 ChromeGtkFrame::incognito-frame-gradient-color = @titlebar_bg_color ChromeGtkFrame::scrollbar-trough-color = @bg_color ChromeGtkFrame::scrollbar-slider-normal-color = mix (0.21, @fg_color, @bg_color) ChromeGtkFrame::scrollbar-slider-prelight-color = mix (0.31, @fg_color, @bg_color) } class "ChromeGtkFrame" style "chrome-gtk-frame" widget_class "*Chrom*Button*" style "chromium-toolbar-button" # General Styles class "GtkWidget" style "murrine-default" class "GtkFrame" style "murrine-wide" class "MetaFrames" style "metacity-frame" class "GtkWindow" style "metacity-frame" class "GtkSeparator" style "murrine-wide" class "GtkCalendar" style "murrine-wide" class "GtkSpinButton" style "murrine-spinbutton" class "GtkScale" style "murrine-scale" class "GtkVScale" style "murrine-vscale" class "GtkHScale" style "murrine-hscale" class "GtkScrollbar" style "murrine-scrollbar" class "GtkVScrollbar" style "murrine-vscrollbar" class "GtkHScrollbar" style "murrine-hscrollbar" class "GtkRadio*" style "murrine-radiocheck" class "GtkCheck*" style "murrine-radiocheck" class "GtkEntry" style "murrine-entry" widget_class "*" style "murrine-notebook" widget_class "**" style "murrine-notebook-bg" widget_class "**" style "murrine-notebook-bg" widget_class "**" style "murrine-notebook-bg" widget_class "*.GtkNotebook.*.GtkViewport" style "murrine-notebook" widget_class "*" style "murrine-button" widget_class "**" style "murrine-statusbar" widget_class "*" style "murrine-progressbar" widget_class "*" style "murrine-progressbar" widget_class "**" style "murrine-comboboxentry" widget_class "**" style "murrine-comboboxentry" widget_class "**" style "murrine-menu" widget_class "**" style "murrine-menu-item" widget_class "**" style "murrine-separator-menu-item" widget_class "*Menu*.*Sepa*" style "murrine-separator-menu-item" widget_class "**" style "murrine-menubar" widget_class "***" style "murrine-menubaritem" widget_class "*GtkToolButton*" style "murrine-toolbutton" widget_class "*GtkToggleToolButton*" style "murrine-toolbutton" widget_class "*GtkMenuToolButton*" style "murrine-toolbutton" widget_class "*GtkToolbar*Button" style "murrine-toolbutton" widget_class "*.." style "murrine-frame-title" widget_class "*.*" style "murrine-treeview" widget_class "*.." style "murrine-treeview-header" widget_class "*.." style "murrine-treeview-header" widget_class "*.." style "murrine-treeview-header" widget_class "*.." style "murrine-treeview-header" widget "gtk-tooltip*" style "murrine-tooltips" widget_class "**" style "murrine-overlay-scrollbar" # Workarounds and Non-Standard Styling style "text-is-fg-color-workaround" { text[NORMAL] = @text_color text[PRELIGHT] = @fg_color text[SELECTED] = @selected_fg_color text[ACTIVE] = @fg_color text[INSENSITIVE] = mix (0.5, @bg_color, @fg_color) } widget_class "*.." style "text-is-fg-color-workaround" style "fg-is-text-color-workaround" { fg[NORMAL] = @text_color fg[PRELIGHT] = @text_color fg[ACTIVE] = @selected_fg_color fg[SELECTED] = @selected_fg_color fg[INSENSITIVE] = darker (@fg_color) } widget_class "**" style "fg-is-text-color-workaround" widget_class "*" style "fg-is-text-color-workaround" widget_class "*" style "fg-is-text-color-workaround" style "murrine-evo-new-button-workaround" { engine "murrine" { toolbarstyle = 0 } } widget_class "EShellWindow.GtkVBox.BonoboDock.BonoboDockBand.BonoboDockItem*" style "murrine-evo-new-button-workaround" style "inkscape-toolbar-fix" { engine "murrine" { gradient_shades = { 1.0, 1.0, 1.0, 1.0 } highlight_shade = 1.0 } } #widget "*GtkHandleBox*" style "inkscape-toolbar-fix" #widget "*HandleBox*CommandsToolbar*" style "inkscape-toolbar-fix" #widget "*HandleBox*SnapToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*SelectToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*NodeToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*TweakToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*ZoomToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*StarToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*RectToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*3DBoxToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*ArcToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*SpiralToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*PencilToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*PenToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*CalligraphyToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*EraserToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*LPEToolToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*DropperToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*ConnectorToolbar*" style "inkscape-toolbar-fix" widget "*HandleBox*PaintbucketToolbar*" style "inkscape-toolbar-fix" # Performance Fixes style "performance-fix" { engine "murrine" { textstyle = 0 } } widget_class "*gtkmm__GtkWindow*" style "performance-fix" # Inkscape widget_class "*GimpDisplayShell*" style "performance-fix" # Gimp widget_class "*GimpToolbox*" style "performance-fix" widget_class "*GimpMenuDock*" style "performance-fix" widget "*OOoFixed*" style "performance-fix" # Openoffice/Libreoffice widget_class "*MozContainer*" style "performance-fix" # Firefox (Not sure if this one does anything though.) widget_class "*XfceHeading*" style "xfce-header" widget_class "*XfceDesktop*" style "xfdesktop-windowlist" widget_class "*XfdesktopIconView*" style "xfdesktop-icon-view" widget "xfwm4-tabwin*" style "xfwm-tabwin" widget_class "*XfsmLogoutDialog*" style "xfsm-logout" widget_class "*XfsmLogoutDialog*GtkButton" style "xfsm-logout-button" go-lib-5.6.0.9/mime/testdata/Deepin/gtk-3.0/000775 000000 000000 00000000000 13753517240 020060 5ustar00rootroot000000 000000 go-lib-5.6.0.9/mime/testdata/Deepin/gtk-3.0/settings.ini000664 000000 000000 00000000100 13753517240 022410 0ustar00rootroot000000 000000 [Settings] gtk-auto-mnemonics = 1 gtk-visible-focus = automatic go-lib-5.6.0.9/mime/testdata/Deepin/index.theme000664 000000 000000 00000000075 13753517240 021132 0ustar00rootroot000000 000000 [Icon Theme] Name=Deepin Directories=apps/24,apps/32,apps/48 go-lib-5.6.0.9/mime/testdata/Deepin/metacity-1/000775 000000 000000 00000000000 13753517240 020752 5ustar00rootroot000000 000000 go-lib-5.6.0.9/mime/testdata/Deepin/metacity-1/metacity-theme-3.xml000664 000000 000000 00000243416 13753517240 024565 0ustar00rootroot000000 000000 Deepin Satyajit Sahoo GPL-3.0+ 11 December 2013 Numix Mutter Theme <title version=">= 3.1" x="(0 `max` ((frame_x_center - title_width/2) `min` (width - title_width))) + 2" y="(0 `max` ((height - title_height) / 2))" ellipsize_width="width" color="C_title_focused" /> </draw_ops> <draw_ops name="title_unfocused"> <title version="< 3.1" x="(0 `max` ((width - title_width) / 2)) + 2" y="(0 `max` ((height - title_height) / 2))" color="C_title_unfocused" /> <title version=">= 3.1" x="(0 `max` ((frame_x_center - title_width/2) `min` (width - title_width))) + 2" y="(0 `max` ((height - title_height) / 2))" ellipsize_width="width" color="C_title_unfocused" /> </draw_ops> <!-- ::: WINDOW DECORATIONS ::: --> <draw_ops name="entire_background_focused"> <rectangle color="C_titlebar" x="0" y="0" width="width" height="height" filled="true" /> </draw_ops> <draw_ops name="entire_background_unfocused"> <include name="entire_background_focused" /> </draw_ops> <draw_ops name="titlebar_fill_focused"> <rectangle color="C_titlebar" x="0" y="0" width="width" height="height" filled="true" /> </draw_ops> <draw_ops name="titlebar_fill_attached_focused"> <include name="entire_background_focused" /> </draw_ops> <draw_ops name="titlebar_fill_unfocused"> <rectangle color="C_titlebar" x="0" y="0" width="width" height="height" filled="true" /> </draw_ops> <draw_ops name="titlebar_focused"> <include name="titlebar_fill_focused" /> </draw_ops> <draw_ops name="titlebar_attached_focused"> <!-- titlebar for attached and modal dialogs --> <include name="titlebar_fill_attached_focused" /> </draw_ops> <draw_ops name="rounded_titlebar_focused"> <include name="titlebar_fill_focused" /> </draw_ops> <draw_ops name="border_focused"> <rectangle color="C_border_focused" x="0" y="0" width="width-1" height="height-1" filled="false" /> </draw_ops> <draw_ops name="border_unfocused"> <rectangle color="C_border_unfocused" x="0" y="0" width="width-1" height="height-1" filled="false" /> </draw_ops> <draw_ops name="rounded_border_focused"> <line color="C_border_focused" x1="2" y1="0" x2="width-3" y2="0" /> <line color="C_border_focused" x1="0" y1="height-1" x2="width-1" y2="height-1" /> <line color="C_border_focused" x1="0" y1="2" x2="0" y2="height-2" /> <line color="C_border_focused" x1="width-1" y1="2" x2="width-1" y2="height-2" /> <arc color="C_border_focused" x="0" y="0" width="3" height="3" start_angle="270" extent_angle="90" /> <arc color="C_border_focused" x="width-3" y="0" width="2" height="3" start_angle="0" extent_angle="90" /> <!-- double arcs for darker borders --> <arc color="C_border_focused" x="0" y="0" width="3" height="3" start_angle="270" extent_angle="90" /> <arc color="C_border_focused" x="width-3" y="0" width="2" height="3" start_angle="0" extent_angle="90" /> </draw_ops> <draw_ops name="rounded_border_unfocused"> <line color="C_border_unfocused" x1="2" y1="0" x2="width-3" y2="0" /> <line color="C_border_unfocused" x1="0" y1="height-1" x2="width-1" y2="height-1" /> <line color="C_border_unfocused" x1="0" y1="2" x2="0" y2="height-2" /> <line color="C_border_unfocused" x1="width-1" y1="2" x2="width-1" y2="height-2" /> <arc color="C_border_unfocused" x="0" y="0" width="3" height="3" start_angle="270" extent_angle="90" /> <arc color="C_border_unfocused" x="width-3" y="0" width="2" height="3" start_angle="0" extent_angle="90" /> <!-- double arcs for darker borders --> <arc color="C_border_unfocused" x="0" y="0" width="3" height="3" start_angle="270" extent_angle="90" /> <arc color="C_border_unfocused" x="width-3" y="0" width="2" height="3" start_angle="0" extent_angle="90" /> </draw_ops> <draw_ops name="border_right_focused"> <line x1="width-1" y1="0" x2="width-1" y2="height" color="C_border_focused" /> </draw_ops> <draw_ops name="border_right_unfocused"> <line x1="width-1" y1="0" x2="width-1" y2="height" color="C_border_unfocused" /> </draw_ops> <draw_ops name="border_left_focused"> <line x1="0" y1="0" x2="0" y2="height" color="C_border_focused" /> </draw_ops> <draw_ops name="border_left_unfocused"> <line x1="0" y1="0" x2="0" y2="height" color="C_border_unfocused" /> </draw_ops> <!-- ::: BUTTON ICONS ::: --> <!-- note: negative values in x or y causes gnome-shell to crash --> <!-- close icon --> <draw_ops name="close_focused"> <line x1="width-(width-width%3)/3-2" y1="(height-height%3)/3+1" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-2" color="C_icons_focused" /> <line x1="width-(width-width%3)/3-2" y1="(height-height%3)/3+2" x2="(width-width%3)/3+2" y2="height-(height-height%3)/3-2" color="C_icons_focused" /> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+1" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-3" color="C_icons_focused" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-2" y2="height-(height-height%3)/3-2" color="C_icons_focused" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-2" color="C_icons_focused" /> <line x1="(width-width%3)/3+2" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-2" y2="height-(height-height%3)/3-3" color="C_icons_focused" /> </draw_ops> <draw_ops name="close_focused_prelight"> <line x1="width-(width-width%3)/3-2" y1="(height-height%3)/3+1" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-2" color="C_icons_focused_prelight" /> <line x1="width-(width-width%3)/3-2" y1="(height-height%3)/3+2" x2="(width-width%3)/3+2" y2="height-(height-height%3)/3-2" color="C_icons_focused_prelight" /> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+1" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-3" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-2" y2="height-(height-height%3)/3-2" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-2" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3+2" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-2" y2="height-(height-height%3)/3-3" color="C_icons_focused_prelight" /> </draw_ops> <draw_ops name="close_focused_pressed"> <line x1="width-(width-width%3)/3-2" y1="(height-height%3)/3+1" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-2" color="C_icons_focused_pressed" /> <line x1="width-(width-width%3)/3-2" y1="(height-height%3)/3+2" x2="(width-width%3)/3+2" y2="height-(height-height%3)/3-2" color="C_icons_focused_pressed" /> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+1" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-3" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-2" y2="height-(height-height%3)/3-2" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-2" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+2" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-2" y2="height-(height-height%3)/3-3" color="C_icons_focused_pressed" /> </draw_ops> <draw_ops name="close_unfocused"> <line x1="width-(width-width%3)/3-2" y1="(height-height%3)/3+1" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-2" color="C_icons_unfocused" /> <line x1="width-(width-width%3)/3-2" y1="(height-height%3)/3+2" x2="(width-width%3)/3+2" y2="height-(height-height%3)/3-2" color="C_icons_unfocused" /> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+1" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-3" color="C_icons_unfocused" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-2" y2="height-(height-height%3)/3-2" color="C_icons_unfocused" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-2" color="C_icons_unfocused" /> <line x1="(width-width%3)/3+2" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-2" y2="height-(height-height%3)/3-3" color="C_icons_unfocused" /> </draw_ops> <draw_ops name="close_unfocused_prelight"> <include name="close_focused_prelight" /> </draw_ops> <draw_ops name="close_unfocused_pressed"> <include name="close_focused_pressed" /> </draw_ops> <!-- maximize icon --> <draw_ops name="maximize_focused"> <rectangle x="(width-width%3)/3+1" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused" /> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused" /> </draw_ops> <draw_ops name="maximize_focused_prelight"> <rectangle x="(width-width%3)/3+1" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused_prelight" /> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused_prelight" /> </draw_ops> <draw_ops name="maximize_focused_pressed"> <rectangle x="(width-width%3)/3+1" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused_pressed" /> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused_pressed" /> </draw_ops> <draw_ops name="maximize_unfocused"> <rectangle x="(width-width%3)/3+1" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_unfocused" /> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_unfocused" /> </draw_ops> <draw_ops name="maximize_unfocused_prelight"> <include name="maximize_focused_prelight" /> </draw_ops> <draw_ops name="maximize_unfocused_pressed"> <include name="maximize_focused_pressed" /> </draw_ops> <!-- unmaximize icon --> <draw_ops name="unmaximize_focused"> <rectangle x="(width-width%3)/3+1" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused" /> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused" /> </draw_ops> <draw_ops name="unmaximize_focused_prelight"> <rectangle x="(width-width%3)/3+1" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused_prelight" /> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused_prelight" /> </draw_ops> <draw_ops name="unmaximize_focused_pressed"> <rectangle x="(width-width%3)/3+1" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused_pressed" /> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused_pressed" /> </draw_ops> <draw_ops name="unmaximize_unfocused"> <rectangle x="(width-width%3)/3+1" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_unfocused" /> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_unfocused" /> </draw_ops> <draw_ops name="unmaximize_unfocused_prelight"> <include name="unmaximize_focused_prelight" /> </draw_ops> <draw_ops name="unmaximize_unfocused_pressed"> <include name="unmaximize_focused_pressed" /> </draw_ops> <!-- minimize icon --> <draw_ops name="minimize_focused"> <rectangle x="(width-width%3)/3+2" y="height-(height-height%3)/3-5" width="width-2*(width-width%3)/3-2" height="2" filled="true" color="C_icons_focused" /> </draw_ops> <draw_ops name="minimize_focused_prelight"> <rectangle x="(width-width%3)/3+2" y="height-(height-height%3)/3-5" width="width-2*(width-width%3)/3-2" height="2" filled="true" color="C_icons_focused_prelight" /> </draw_ops> <draw_ops name="minimize_focused_pressed"> <rectangle x="(width-width%3)/3+2" y="height-(height-height%3)/3-5" width="width-2*(width-width%3)/3-2" height="2" filled="true" color="C_icons_focused_pressed" /> </draw_ops> <draw_ops name="minimize_unfocused"> <rectangle x="(width-width%3)/3+2" y="height-(height-height%3)/3-5" width="width-2*(width-width%3)/3-2" height="2" filled="true" color="C_icons_unfocused" /> </draw_ops> <draw_ops name="minimize_unfocused_prelight"> <include name="minimize_focused_prelight" /> </draw_ops> <draw_ops name="minimize_unfocused_pressed"> <include name="minimize_focused_pressed" /> </draw_ops> <!-- menu icon --> <draw_ops name="menu_focused"> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused" /> <rectangle x="(width-width%3)/3+3" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused" /> <rectangle x="(width-width%3)/3+5" y="height/2-2" width="width-2*(width-width%3)/3-8" height="2" filled="true" color="C_icons_focused" /> </draw_ops> <draw_ops name="menu_focused_prelight"> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused_prelight" /> <rectangle x="(width-width%3)/3+3" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused_prelight" /> <rectangle x="(width-width%3)/3+5" y="height/2-2" width="width-2*(width-width%3)/3-8" height="2" filled="true" color="C_icons_focused_prelight" /> </draw_ops> <draw_ops name="menu_focused_pressed"> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_focused_pressed" /> <rectangle x="(width-width%3)/3+3" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_focused_pressed" /> <rectangle x="(width-width%3)/3+5" y="height/2-2" width="width-2*(width-width%3)/3-8" height="2" filled="true" color="C_icons_focused_pressed" /> </draw_ops> <draw_ops name="menu_unfocused"> <rectangle x="(width-width%3)/3+2" y="(height-height%3)/3+1" width="width-2*(width-width%3)/3-3" height="height-2*(height-height%3)/3-3" color="C_icons_unfocused" /> <rectangle x="(width-width%3)/3+3" y="(height-height%3)/3+2" width="width-2*(width-width%3)/3-5" height="height-2*(height-height%3)/3-5" color="C_icons_unfocused" /> <rectangle x="(width-width%3)/3+5" y="height/2-2" width="width-2*(width-width%3)/3-8" height="2" filled="true" color="C_icons_unfocused" /> </draw_ops> <draw_ops name="menu_unfocused_prelight"> <include name="menu_focused_prelight" /> </draw_ops> <draw_ops name="menu_unfocused_pressed"> <include name="menu_focused_pressed" /> </draw_ops> <!-- shade icon --> <draw_ops name="shade_focused"> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-5" color="C_icons_focused" /> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+2" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-5" color="C_icons_focused" /> <line x1="width-(width-width%3)/3-7" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-6" color="C_icons_focused" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-5" color="C_icons_focused" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-4" y2="height-(height-height%3)/3-5" color="C_icons_focused" /> <line x1="(width-width%3)/3+4" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-6" color="C_icons_focused" /> <rectangle x="(width-width%3)/3+3" y="height/2-2" width="width-2*(width-width%3)/3-8" height="6" filled="true" color="C_icons_focused" /> </draw_ops> <draw_ops name="shade_focused_prelight"> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-5" color="C_icons_focused_prelight" /> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+2" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-5" color="C_icons_focused_prelight" /> <line x1="width-(width-width%3)/3-7" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-6" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-5" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-4" y2="height-(height-height%3)/3-5" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3+4" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-6" color="C_icons_focused_prelight" /> <rectangle x="(width-width%3)/3+3" y="height/2-2" width="width-2*(width-width%3)/3-8" height="6" filled="true" color="C_icons_focused_prelight" /> </draw_ops> <draw_ops name="shade_focused_pressed"> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-5" color="C_icons_focused_pressed" /> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+2" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-5" color="C_icons_focused_pressed" /> <line x1="width-(width-width%3)/3-7" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-6" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-5" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-4" y2="height-(height-height%3)/3-5" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+4" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-6" color="C_icons_focused_pressed" /> <rectangle x="(width-width%3)/3+3" y="height/2-2" width="width-2*(width-width%3)/3-8" height="6" filled="true" color="C_icons_focused_pressed" /> </draw_ops> <draw_ops name="shade_unfocused"> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-5" color="C_icons_unfocused" /> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+2" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-5" color="C_icons_unfocused" /> <line x1="width-(width-width%3)/3-7" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-6" color="C_icons_unfocused" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-5" color="C_icons_unfocused" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-4" y2="height-(height-height%3)/3-5" color="C_icons_unfocused" /> <line x1="(width-width%3)/3+4" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-6" color="C_icons_unfocused" /> <rectangle x="(width-width%3)/3+3" y="height/2-2" width="width-2*(width-width%3)/3-8" height="6" filled="true" color="C_icons_unfocused" /> </draw_ops> <draw_ops name="shade_unfocused_prelight"> <include name="shade_focused_prelight" /> </draw_ops> <draw_ops name="shade_unfocused_pressed"> <include name="shade_focused_pressed" /> </draw_ops> <!-- unshade icon --> <draw_ops name="unshade_focused"> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+4" x2="(width-width%3)/3+3" y2="height-(height-height%3)/3-2" color="C_icons_focused" /> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+5" x2="(width-width%3)/3+4" y2="height-(height-height%3)/3-2" color="C_icons_focused" /> <line x1="width-(width-width%3)/3-4" y1="(height-height%3)/3+4" x2="(width-width%3)/3+3" y2="height-(height-height%3)/3-3" color="C_icons_focused" /> <line x1="(width-width%3)/3" y1="(height-height%3)/3+4" x2="width-(width-width%3)/3-6" y2="height-(height-height%3)/3-2" color="C_icons_focused" /> <line x1="(width-width%3)/3" y1="(height-height%3)/3+5" x2="width-(width-width%3)/3-7" y2="height-(height-height%3)/3-2" color="C_icons_focused" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+4" x2="width-(width-width%3)/3-6" y2="height-(height-height%3)/3-3" color="C_icons_focused" /> <rectangle x="(width-width%3)/3+3" y="height/2-4" width="width-2*(width-width%3)/3-8" height="6" filled="true" color="C_icons_focused" /> </draw_ops> <draw_ops name="unshade_focused_prelight"> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+4" x2="(width-width%3)/3+3" y2="height-(height-height%3)/3-2" color="C_icons_focused_prelight" /> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+5" x2="(width-width%3)/3+4" y2="height-(height-height%3)/3-2" color="C_icons_focused_prelight" /> <line x1="width-(width-width%3)/3-4" y1="(height-height%3)/3+4" x2="(width-width%3)/3+3" y2="height-(height-height%3)/3-3" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3" y1="(height-height%3)/3+4" x2="width-(width-width%3)/3-6" y2="height-(height-height%3)/3-2" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3" y1="(height-height%3)/3+5" x2="width-(width-width%3)/3-7" y2="height-(height-height%3)/3-2" color="C_icons_focused_prelight" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+4" x2="width-(width-width%3)/3-6" y2="height-(height-height%3)/3-3" color="C_icons_focused_prelight" /> <rectangle x="(width-width%3)/3+3" y="height/2-4" width="width-2*(width-width%3)/3-8" height="6" filled="true" color="C_icons_focused_prelight" /> </draw_ops> <draw_ops name="unshade_focused_pressed"> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-5" color="C_icons_focused_pressed" /> <line x1="width-(width-width%3)/3-6" y1="(height-height%3)/3+2" x2="(width-width%3)/3+1" y2="height-(height-height%3)/3-5" color="C_icons_focused_pressed" /> <line x1="width-(width-width%3)/3-7" y1="(height-height%3)/3+1" x2="(width-width%3)/3" y2="height-(height-height%3)/3-6" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-5" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+3" y1="(height-height%3)/3+2" x2="width-(width-width%3)/3-4" y2="height-(height-height%3)/3-5" color="C_icons_focused_pressed" /> <line x1="(width-width%3)/3+4" y1="(height-height%3)/3+1" x2="width-(width-width%3)/3-3" y2="height-(height-height%3)/3-6" color="C_icons_focused_pressed" /> <rectangle x="(width-width%3)/3+3" y="height/2-2" width="width-2*(width-width%3)/3-8" height="6" filled="true" color="C_icons_focused_pressed" /> </draw_ops> <draw_ops name="unshade_unfocused"> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+4" x2="(width-width%3)/3+3" y2="height-(height-height%3)/3-2" color="C_icons_unfocused" /> <line x1="width-(width-width%3)/3-3" y1="(height-height%3)/3+5" x2="(width-width%3)/3+4" y2="height-(height-height%3)/3-2" color="C_icons_unfocused" /> <line x1="width-(width-width%3)/3-4" y1="(height-height%3)/3+4" x2="(width-width%3)/3+3" y2="height-(height-height%3)/3-3" color="C_icons_unfocused" /> <line x1="(width-width%3)/3" y1="(height-height%3)/3+4" x2="width-(width-width%3)/3-6" y2="height-(height-height%3)/3-2" color="C_icons_unfocused" /> <line x1="(width-width%3)/3" y1="(height-height%3)/3+5" x2="width-(width-width%3)/3-7" y2="height-(height-height%3)/3-2" color="C_icons_unfocused" /> <line x1="(width-width%3)/3+1" y1="(height-height%3)/3+4" x2="width-(width-width%3)/3-6" y2="height-(height-height%3)/3-3" color="C_icons_unfocused" /> <rectangle x="(width-width%3)/3+3" y="height/2-4" width="width-2*(width-width%3)/3-8" height="6" filled="true" color="C_icons_unfocused" /> </draw_ops> <draw_ops name="unshade_unfocused_prelight"> <include name="unshade_focused_prelight" /> </draw_ops> <draw_ops name="unshade_unfocused_pressed"> <include name="unshade_focused_pressed" /> </draw_ops> <!-- ::: FRAME STYLES ::: --> <frame_style name="normal_focused" geometry="normal"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="rounded_titlebar_focused" /> <piece position="title" draw_ops="title_focused" /> <piece position="overlay" draw_ops="rounded_border_focused" /> <button function="close" state="normal" draw_ops="close_focused" /> <button function="close" state="prelight" draw_ops="close_focused_prelight" /> <button function="close" state="pressed" draw_ops="close_focused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_focused" /> <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_focused" /> <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> <button function="menu" state="normal" draw_ops="menu_focused" /> <button function="menu" state="prelight" draw_ops="menu_focused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> <button function="shade" state="normal" draw_ops="shade_focused" /> <button function="shade" state="prelight" draw_ops="shade_focused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_focused" /> <button function="unshade" state="prelight" draw_ops="unshade_focused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_focused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="normal_unfocused" geometry="normal_unfocused"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> <piece position="title" draw_ops="title_unfocused" /> <piece position="overlay" draw_ops="rounded_border_unfocused" /> <button function="close" state="normal" draw_ops="close_unfocused" /> <button function="close" state="prelight" draw_ops="close_unfocused_prelight" /> <button function="close" state="pressed" draw_ops="close_unfocused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_unfocused" /> <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_unfocused" /> <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed" /> <button function="menu" state="normal" draw_ops="menu_unfocused" /> <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> <button function="shade" state="normal" draw_ops="shade_unfocused" /> <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_unfocused" /> <button function="unshade" state="prelight" draw_ops="unshade_unfocused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_unfocused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="normal_max_focused" geometry="max"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="titlebar_fill_focused" /> <piece position="title" draw_ops="title_focused" /> <button function="close" state="normal" draw_ops="close_focused" /> <button function="close" state="prelight" draw_ops="close_focused_prelight" /> <button function="close" state="pressed" draw_ops="close_focused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_focused" /> <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_focused" /> <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> <button function="menu" state="normal" draw_ops="menu_focused" /> <button function="menu" state="prelight" draw_ops="menu_focused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> <button function="shade" state="normal" draw_ops="shade_focused" /> <button function="shade" state="prelight" draw_ops="shade_focused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_focused" /> <button function="unshade" state="prelight" draw_ops="unshade_focused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_focused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="normal_max_unfocused" geometry="max"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> <piece position="title" draw_ops="title_unfocused" /> <button function="close" state="normal" draw_ops="close_unfocused" /> <button function="close" state="prelight" draw_ops="close_unfocused_prelight" /> <button function="close" state="pressed" draw_ops="close_unfocused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_unfocused" /> <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_unfocused" /> <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed" /> <button function="menu" state="normal" draw_ops="menu_unfocused" /> <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> <button function="shade" state="normal" draw_ops="shade_unfocused" /> <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_unfocused" /> <button function="unshade" state="prelight" draw_ops="unshade_unfocused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_unfocused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="normal_max_shaded_focused" geometry="max"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="titlebar_fill_focused" /> <piece position="title" draw_ops="title_focused" /> <piece position="overlay"><draw_ops><line x1="0" y1="height-1" x2="width" y2="height-1" color="C_border_focused" /></draw_ops></piece> <button function="close" state="normal" draw_ops="close_focused" /> <button function="close" state="prelight" draw_ops="close_focused_prelight" /> <button function="close" state="pressed" draw_ops="close_focused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_focused" /> <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_focused" /> <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> <button function="menu" state="normal" draw_ops="menu_focused" /> <button function="menu" state="prelight" draw_ops="menu_focused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> <button function="shade" state="normal" draw_ops="shade_focused" /> <button function="shade" state="prelight" draw_ops="shade_focused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_focused" /> <button function="unshade" state="prelight" draw_ops="unshade_focused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_focused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="normal_max_shaded_unfocused" geometry="max"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> <piece position="title" draw_ops="title_unfocused" /> <piece position="overlay"><draw_ops><line x1="0" y1="height-1" x2="width" y2="height-1" color="C_border_unfocused" /></draw_ops></piece> <button function="close" state="normal" draw_ops="close_unfocused" /> <button function="close" state="prelight" draw_ops="close_unfocused_prelight" /> <button function="close" state="pressed" draw_ops="close_unfocused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_unfocused" /> <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_unfocused" /> <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed" /> <button function="menu" state="normal" draw_ops="menu_unfocused" /> <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> <button function="shade" state="normal" draw_ops="shade_unfocused" /> <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_unfocused" /> <button function="unshade" state="prelight" draw_ops="unshade_unfocused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_unfocused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="dialog_focused" geometry="nobuttons"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="rounded_titlebar_focused" /> <piece position="title" draw_ops="title_focused" /> <piece position="overlay" draw_ops="rounded_border_focused" /> <button function="close" state="normal" draw_ops="close_focused" /> <button function="close" state="prelight" draw_ops="close_focused_prelight" /> <button function="close" state="pressed" draw_ops="close_focused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_focused" /> <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_focused" /> <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> <button function="menu" state="normal" draw_ops="menu_focused" /> <button function="menu" state="prelight" draw_ops="menu_focused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> <button function="shade" state="normal" draw_ops="shade_focused" /> <button function="shade" state="prelight" draw_ops="shade_focused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_focused" /> <button function="unshade" state="prelight" draw_ops="unshade_focused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_focused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="dialog_unfocused" geometry="nobuttons"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> <piece position="title" draw_ops="title_unfocused" /> <piece position="overlay" draw_ops="rounded_border_unfocused" /> <button function="close" state="normal" draw_ops="close_unfocused" /> <button function="close" state="prelight" draw_ops="close_unfocused_prelight" /> <button function="close" state="pressed" draw_ops="close_unfocused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_unfocused" /> <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_unfocused" /> <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed" /> <button function="menu" state="normal" draw_ops="menu_unfocused" /> <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> <button function="shade" state="normal"><draw_ops></draw_ops></button> <button function="shade" state="prelight"><draw_ops></draw_ops></button> <button function="shade" state="pressed"><draw_ops></draw_ops></button> <button function="unshade" state="normal"><draw_ops></draw_ops></button> <button function="unshade" state="prelight"><draw_ops></draw_ops></button> <button function="unshade" state="pressed"><draw_ops></draw_ops></button> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="modal_dialog_focused" geometry="modal"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="titlebar_attached_focused" /> <piece position="title" draw_ops="title_focused" /> <piece position="overlay" draw_ops="border_focused" /> <button function="close" state="normal" draw_ops="close_focused" /> <button function="close" state="prelight" draw_ops="close_focused_prelight" /> <button function="close" state="pressed" draw_ops="close_focused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_focused" /> <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_focused" /> <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> <button function="menu" state="normal" draw_ops="menu_focused" /> <button function="menu" state="prelight" draw_ops="menu_focused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> <button function="shade" state="normal" draw_ops="shade_focused" /> <button function="shade" state="prelight" draw_ops="shade_focused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_focused" /> <button function="unshade" state="prelight" draw_ops="unshade_focused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_focused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button><button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="modal_dialog_unfocused" geometry="modal"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> <piece position="title" draw_ops="title_unfocused" /> <piece position="overlay" draw_ops="border_unfocused" /> <button function="close" state="normal" draw_ops="close_unfocused" /> <button function="close" state="prelight" draw_ops="close_unfocused_prelight" /> <button function="close" state="pressed" draw_ops="close_unfocused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_unfocused" /> <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_unfocused" /> <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed" /> <button function="menu" state="normal" draw_ops="menu_unfocused" /> <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> <button function="shade" state="normal" draw_ops="shade_unfocused" /> <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_unfocused" /> <button function="unshade" state="prelight" draw_ops="unshade_unfocused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_unfocused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="utility_focused" geometry="small"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="titlebar_focused" /> <piece position="title" draw_ops="title_focused" /> <piece position="overlay" draw_ops="border_focused" /> <button function="close" state="normal" draw_ops="close_focused" /> <button function="close" state="prelight" draw_ops="close_focused_prelight" /> <button function="close" state="pressed" draw_ops="close_focused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_focused" /> <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_focused" /> <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> <button function="menu" state="normal" draw_ops="menu_focused" /> <button function="menu" state="prelight" draw_ops="menu_focused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> <button function="shade" state="normal" draw_ops="shade_focused" /> <button function="shade" state="prelight" draw_ops="shade_focused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_focused" /> <button function="unshade" state="prelight" draw_ops="unshade_focused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_focused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="utility_unfocused" geometry="small_unfocused"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> <piece position="title" draw_ops="title_unfocused" /> <piece position="overlay" draw_ops="border_unfocused" /> <button function="close" state="normal" draw_ops="close_unfocused" /> <button function="close" state="prelight" draw_ops="close_unfocused_prelight" /> <button function="close" state="pressed" draw_ops="close_unfocused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_unfocused" /> <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_unfocused" /> <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed" /> <button function="menu" state="normal" draw_ops="menu_unfocused" /> <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> <button function="shade" state="normal" draw_ops="shade_unfocused" /> <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_unfocused" /> <button function="unshade" state="prelight" draw_ops="unshade_unfocused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_unfocused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="border_focused" geometry="border"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="overlay" draw_ops="border_focused" /> <button function="close" state="normal"><draw_ops></draw_ops></button> <button function="close" state="pressed"><draw_ops></draw_ops></button> <button function="maximize" state="normal"><draw_ops></draw_ops></button> <button function="maximize" state="pressed"><draw_ops></draw_ops></button> <button function="minimize" state="normal"><draw_ops></draw_ops></button> <button function="minimize" state="pressed"><draw_ops></draw_ops></button> <button function="menu" state="normal"><draw_ops></draw_ops></button> <button function="menu" state="pressed"><draw_ops></draw_ops></button> <button function="shade" state="normal"><draw_ops></draw_ops></button> <button function="shade" state="prelight"><draw_ops></draw_ops></button> <button function="shade" state="pressed"><draw_ops></draw_ops></button> <button function="unshade" state="normal"><draw_ops></draw_ops></button> <button function="unshade" state="prelight"><draw_ops></draw_ops></button> <button function="unshade" state="pressed"><draw_ops></draw_ops></button> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="border_unfocused" geometry="border"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="overlay" draw_ops="border_unfocused" /> <button function="close" state="normal"><draw_ops></draw_ops></button> <button function="close" state="pressed"><draw_ops></draw_ops></button> <button function="maximize" state="normal"><draw_ops></draw_ops></button> <button function="maximize" state="pressed"><draw_ops></draw_ops></button> <button function="minimize" state="normal"><draw_ops></draw_ops></button> <button function="minimize" state="pressed"><draw_ops></draw_ops></button> <button function="menu" state="normal"><draw_ops></draw_ops></button> <button function="menu" state="pressed"><draw_ops></draw_ops></button> <button function="shade" state="normal"><draw_ops></draw_ops></button> <button function="shade" state="prelight"><draw_ops></draw_ops></button> <button function="shade" state="pressed"><draw_ops></draw_ops></button> <button function="unshade" state="normal"><draw_ops></draw_ops></button> <button function="unshade" state="prelight"><draw_ops></draw_ops></button> <button function="unshade" state="pressed"><draw_ops></draw_ops></button> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="borderless" geometry="borderless"> <button function="close" state="normal"><draw_ops></draw_ops></button> <button function="close" state="pressed"><draw_ops></draw_ops></button> <button function="maximize" state="normal"><draw_ops></draw_ops></button> <button function="maximize" state="pressed"><draw_ops></draw_ops></button> <button function="minimize" state="normal"><draw_ops></draw_ops></button> <button function="minimize" state="pressed"><draw_ops></draw_ops></button> <button function="menu" state="normal"><draw_ops></draw_ops></button> <button function="menu" state="pressed"><draw_ops></draw_ops></button> <button function="shade" state="normal"><draw_ops></draw_ops></button> <button function="shade" state="prelight"><draw_ops></draw_ops></button> <button function="shade" state="pressed"><draw_ops></draw_ops></button> <button function="unshade" state="normal"><draw_ops></draw_ops></button> <button function="unshade" state="prelight"><draw_ops></draw_ops></button> <button function="unshade" state="pressed"><draw_ops></draw_ops></button> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="attached_focused" geometry="attached"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="titlebar_attached_focused" /> <piece position="title" draw_ops="title_focused" /> <piece position="overlay" draw_ops="border_focused" /> <button function="close" state="normal"><draw_ops></draw_ops></button> <button function="close" state="pressed"><draw_ops></draw_ops></button> <button function="maximize" state="normal"><draw_ops></draw_ops></button> <button function="maximize" state="pressed"><draw_ops></draw_ops></button> <button function="minimize" state="normal"><draw_ops></draw_ops></button> <button function="minimize" state="pressed"><draw_ops></draw_ops></button> <button function="menu" state="normal"><draw_ops></draw_ops></button> <button function="menu" state="pressed"><draw_ops></draw_ops></button> <button function="shade" state="normal"><draw_ops></draw_ops></button> <button function="shade" state="prelight"><draw_ops></draw_ops></button> <button function="shade" state="pressed"><draw_ops></draw_ops></button> <button function="unshade" state="normal"><draw_ops></draw_ops></button> <button function="unshade" state="prelight"><draw_ops></draw_ops></button> <button function="unshade" state="pressed"><draw_ops></draw_ops></button> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="attached_unfocused" geometry="attached"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_attached_focused" /> <piece position="title" draw_ops="title_unfocused" /> <piece position="overlay" draw_ops="border_unfocused" /> <button function="close" state="normal"><draw_ops></draw_ops></button> <button function="close" state="pressed"><draw_ops></draw_ops></button> <button function="maximize" state="normal"><draw_ops></draw_ops></button> <button function="maximize" state="pressed"><draw_ops></draw_ops></button> <button function="minimize" state="normal"><draw_ops></draw_ops></button> <button function="minimize" state="pressed"><draw_ops></draw_ops></button> <button function="menu" state="normal"><draw_ops></draw_ops></button> <button function="menu" state="pressed"><draw_ops></draw_ops></button> <button function="shade" state="normal"><draw_ops></draw_ops></button> <button function="shade" state="prelight"><draw_ops></draw_ops></button> <button function="shade" state="pressed"><draw_ops></draw_ops></button> <button function="unshade" state="normal"><draw_ops></draw_ops></button> <button function="unshade" state="prelight"><draw_ops></draw_ops></button> <button function="unshade" state="pressed"><draw_ops></draw_ops></button> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="tiled_left_focused" geometry="tiled_left"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="titlebar_fill_focused" /> <piece position="title" draw_ops="title_focused" /> <piece position="overlay" draw_ops="border_right_focused" /> <button function="close" state="normal" draw_ops="close_focused" /> <button function="close" state="prelight" draw_ops="close_focused_prelight" /> <button function="close" state="pressed" draw_ops="close_focused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_focused" /> <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_focused" /> <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> <button function="menu" state="normal" draw_ops="menu_focused" /> <button function="menu" state="prelight" draw_ops="menu_focused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> <button function="shade" state="normal" draw_ops="shade_focused" /> <button function="shade" state="prelight" draw_ops="shade_focused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_focused" /> <button function="unshade" state="prelight" draw_ops="unshade_focused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_focused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="tiled_left_unfocused" geometry="tiled_left"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> <piece position="title" draw_ops="title_unfocused" /> <piece position="overlay" draw_ops="border_right_unfocused" /> <button function="close" state="normal" draw_ops="close_unfocused" /> <button function="close" state="prelight" draw_ops="close_unfocused_prelight" /> <button function="close" state="pressed" draw_ops="close_unfocused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_unfocused" /> <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_unfocused" /> <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed" /> <button function="menu" state="normal" draw_ops="menu_unfocused" /> <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> <button function="shade" state="normal" draw_ops="shade_unfocused" /> <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_unfocused" /> <button function="unshade" state="prelight" draw_ops="unshade_unfocused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_unfocused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="tiled_right_focused" geometry="tiled_right"> <piece position="entire_background" draw_ops="entire_background_focused" /> <piece position="titlebar" draw_ops="titlebar_fill_focused" /> <piece position="title" draw_ops="title_focused" /> <piece position="overlay" draw_ops="border_left_focused" /> <button function="close" state="normal" draw_ops="close_focused" /> <button function="close" state="prelight" draw_ops="close_focused_prelight" /> <button function="close" state="pressed" draw_ops="close_focused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_focused" /> <button function="maximize" state="prelight" draw_ops="maximize_focused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_focused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_focused" /> <button function="minimize" state="prelight" draw_ops="minimize_focused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_focused_pressed" /> <button function="menu" state="normal" draw_ops="menu_focused" /> <button function="menu" state="prelight" draw_ops="menu_focused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_focused_pressed" /> <button function="shade" state="normal" draw_ops="shade_focused" /> <button function="shade" state="prelight" draw_ops="shade_focused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_focused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_focused" /> <button function="unshade" state="prelight" draw_ops="unshade_focused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_focused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <frame_style name="tiled_right_unfocused" geometry="tiled_right"> <piece position="entire_background" draw_ops="entire_background_unfocused" /> <piece position="titlebar" draw_ops="titlebar_fill_unfocused" /> <piece position="title" draw_ops="title_unfocused" /> <piece position="overlay" draw_ops="border_left_unfocused" /> <button function="close" state="normal" draw_ops="close_unfocused" /> <button function="close" state="prelight" draw_ops="close_unfocused_prelight" /> <button function="close" state="pressed" draw_ops="close_unfocused_pressed" /> <button function="maximize" state="normal" draw_ops="maximize_unfocused" /> <button function="maximize" state="prelight" draw_ops="maximize_unfocused_prelight" /> <button function="maximize" state="pressed" draw_ops="maximize_unfocused_pressed" /> <button function="minimize" state="normal" draw_ops="minimize_unfocused" /> <button function="minimize" state="prelight" draw_ops="minimize_unfocused_prelight" /> <button function="minimize" state="pressed" draw_ops="minimize_unfocused_pressed" /> <button function="menu" state="normal" draw_ops="menu_unfocused" /> <button function="menu" state="prelight" draw_ops="menu_unfocused_prelight" /> <button function="menu" state="pressed" draw_ops="menu_unfocused_pressed" /> <button function="shade" state="normal" draw_ops="shade_unfocused" /> <button function="shade" state="prelight" draw_ops="shade_unfocused_prelight" /> <button function="shade" state="pressed" draw_ops="shade_unfocused_pressed" /> <button function="unshade" state="normal" draw_ops="unshade_unfocused" /> <button function="unshade" state="prelight" draw_ops="unshade_unfocused_prelight" /> <button function="unshade" state="pressed" draw_ops="unshade_unfocused_pressed" /> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <!-- placeholder for unimplementated styles--> <frame_style name="blank" geometry="normal"> <button function="close" state="normal"><draw_ops></draw_ops></button> <button function="close" state="pressed"><draw_ops></draw_ops></button> <button function="maximize" state="normal"><draw_ops></draw_ops></button> <button function="maximize" state="pressed"><draw_ops></draw_ops></button> <button function="minimize" state="normal"><draw_ops></draw_ops></button> <button function="minimize" state="pressed"><draw_ops></draw_ops></button> <button function="menu" state="normal"><draw_ops></draw_ops></button> <button function="menu" state="pressed"><draw_ops></draw_ops></button> <button function="shade" state="normal"><draw_ops></draw_ops></button> <button function="shade" state="prelight"><draw_ops></draw_ops></button> <button function="shade" state="pressed"><draw_ops></draw_ops></button> <button function="unshade" state="normal"><draw_ops></draw_ops></button> <button function="unshade" state="prelight"><draw_ops></draw_ops></button> <button function="unshade" state="pressed"><draw_ops></draw_ops></button> <button function="above" state="normal"><draw_ops></draw_ops></button> <button function="above" state="pressed"><draw_ops></draw_ops></button> <button function="unabove" state="normal"><draw_ops></draw_ops></button> <button function="unabove" state="pressed"><draw_ops></draw_ops></button> <button function="stick" state="normal"><draw_ops></draw_ops></button> <button function="stick" state="pressed"><draw_ops></draw_ops></button> <button function="unstick" state="normal"><draw_ops></draw_ops></button> <button function="unstick" state="pressed"><draw_ops></draw_ops></button> </frame_style> <!-- ::: FRAME STYLE SETS ::: --> <frame_style_set name="normal_style_set"> <frame focus="yes" state="normal" resize="both" style="normal_focused" /> <frame focus="no" state="normal" resize="both" style="normal_unfocused" /> <frame focus="yes" state="maximized" style="normal_max_focused" /> <frame focus="no" state="maximized" style="normal_max_unfocused" /> <frame focus="yes" state="shaded" style="normal_focused" /> <frame focus="no" state="shaded" style="normal_unfocused" /> <frame focus="yes" state="maximized_and_shaded" style="normal_max_shaded_focused" /> <frame focus="no" state="maximized_and_shaded" style="normal_max_shaded_unfocused" /> <frame version=">= 3.3" focus="yes" state="tiled_left" style="tiled_left_focused" /> <frame version=">= 3.3" focus="no" state="tiled_left" style="tiled_left_unfocused" /> <frame version=">= 3.3" focus="yes" state="tiled_right" style="tiled_right_focused" /> <frame version=">= 3.3" focus="no" state="tiled_right" style="tiled_right_unfocused" /> <frame version=">= 3.3" focus="yes" state="tiled_left_and_shaded" style="tiled_left_focused" /> <frame version=">= 3.3" focus="no" state="tiled_left_and_shaded" style="tiled_left_unfocused" /> <frame version=">= 3.3" focus="yes" state="tiled_right_and_shaded" style="tiled_right_focused" /> <frame version=">= 3.3" focus="no" state="tiled_right_and_shaded" style="tiled_right_unfocused" /> </frame_style_set> <frame_style_set name="dialog_style_set"> <frame focus="yes" state="normal" resize="both" style="dialog_focused" /> <frame focus="no" state="normal" resize="both" style="dialog_unfocused" /> <frame focus="yes" state="maximized" style="blank" /> <frame focus="no" state="maximized" style="blank" /> <frame focus="yes" state="shaded" style="dialog_focused" /> <frame focus="no" state="shaded" style="dialog_unfocused" /> <frame focus="yes" state="maximized_and_shaded" style="blank" /> <frame focus="no" state="maximized_and_shaded" style="blank" /> </frame_style_set> <frame_style_set name="modal_dialog_style_set"> <frame focus="yes" state="normal" resize="both" style="modal_dialog_focused" /> <frame focus="no" state="normal" resize="both" style="modal_dialog_unfocused" /> <frame focus="yes" state="maximized" style="blank" /> <frame focus="no" state="maximized" style="blank" /> <frame focus="yes" state="shaded" style="modal_dialog_focused" /> <frame focus="no" state="shaded" style="modal_dialog_unfocused" /> <frame focus="yes" state="maximized_and_shaded" style="blank" /> <frame focus="no" state="maximized_and_shaded" style="blank" /> </frame_style_set> <frame_style_set name="utility_style_set"> <frame focus="yes" state="normal" resize="both" style="utility_focused" /> <frame focus="no" state="normal" resize="both" style="utility_unfocused" /> <frame focus="yes" state="maximized" style="blank" /> <frame focus="no" state="maximized" style="blank" /> <frame focus="yes" state="shaded" style="utility_focused" /> <frame focus="no" state="shaded" style="utility_unfocused" /> <frame focus="yes" state="maximized_and_shaded" style="blank" /> <frame focus="no" state="maximized_and_shaded" style="blank" /> </frame_style_set> <frame_style_set name="border_style_set"> <frame focus="yes" state="normal" resize="both" style="border_focused" /> <frame focus="no" state="normal" resize="both" style="border_unfocused" /> <frame focus="yes" state="maximized" style="borderless" /> <frame focus="no" state="maximized" style="borderless" /> <frame focus="yes" state="shaded" style="blank" /> <frame focus="no" state="shaded" style="blank" /> <frame focus="yes" state="maximized_and_shaded" style="blank" /> <frame focus="no" state="maximized_and_shaded" style="blank" /> </frame_style_set> <frame_style_set name="attached_style_set"> <frame focus="yes" state="normal" resize="both" style="attached_focused" /> <frame focus="no" state="normal" resize="both" style="attached_unfocused" /> <frame focus="yes" state="maximized" style="blank" /> <frame focus="no" state="maximized" style="blank" /> <frame focus="yes" state="shaded" style="blank" /> <frame focus="no" state="shaded" style="blank" /> <frame focus="yes" state="maximized_and_shaded" style="blank" /> <frame focus="no" state="maximized_and_shaded" style="blank" /> </frame_style_set> <!-- ::: WINDOWS ::: --> <window type="normal" style_set="normal_style_set" /> <window type="dialog" style_set="dialog_style_set" /> <window type="modal_dialog" style_set="modal_dialog_style_set" /> <window type="menu" style_set="utility_style_set" /> <window type="utility" style_set="utility_style_set" /> <window type="border" style_set="border_style_set" /> <window version=">= 3.2" type="attached" style_set="attached_style_set" /> </metacity_theme> ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mime/testdata/data.txt���������������������������������������������������������������000664 �000000 �000000 �00000000007 13753517240 017240� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������123456 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mime/theme.go������������������������������������������������������������������������000664 �000000 �000000 �00000004615 13753517240 015417� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package mime import ( "fmt" "path" dutils "pkg.deepin.io/lib/utils" ) const ( mimeTypeXCursor = "image/x-xcursor" ) func queryThemeMime(file string) (string, error) { gtk, _ := isGtkTheme(file) if gtk { return MimeTypeGtk, nil } icon, _ := isIconTheme(file) if icon { return MimeTypeIcon, nil } cursor, _ := isCursorTheme(file) if cursor { return MimeTypeCursor, nil } return "", fmt.Errorf("The mime of '%s' not supported", file) } // file: ex "/usr/share/themes/Deepin/index.theme" func isGtkTheme(file string) (bool, error) { var conditions = []string{ "gtk-2.0", "gtk-3.0", "metacity-1", } dir := path.Dir(file) return isFilesInDir(conditions, dir) } // file: ex "/usr/share/icons/Deepin/index.theme" func isIconTheme(file string) (bool, error) { kfile, err := dutils.NewKeyFileFromFile(file) if err != nil { return false, err } defer kfile.Free() _, err = kfile.GetString("Icon Theme", "Directories") if err != nil { return false, err } return true, nil } // file: ex "/usr/share/icons/Deepin/index.theme" func isCursorTheme(file string) (bool, error) { parent := path.Dir(file) tmp := path.Join(parent, "cursors", "left_ptr") mime, err := doQueryFile(tmp) if err != nil { return false, err } if mime != mimeTypeXCursor { return false, fmt.Errorf("Invalid xcursor file '%s'", tmp) } return true, nil } func isFilesInDir(files []string, dir string) (bool, error) { if !dutils.IsDir(dir) { return false, fmt.Errorf("'%s' not a dir", dir) } for _, file := range files { tmp := path.Join(dir, file) if !dutils.IsFileExist(tmp) { return false, fmt.Errorf("Not found the file: '%s'", tmp) } } return true, nil } �������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mime/theme_test.go�������������������������������������������������������������������000664 �000000 �000000 �00000002641 13753517240 016453� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package mime import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestIsGtkTheme(t *testing.T) { Convey("Deepin is gtk theme", t, func(c C) { ok, err := isGtkTheme("testdata/Deepin/index.theme") c.So(ok, ShouldEqual, true) c.So(err, ShouldBeNil) }) } func TestIsIconTheme(t *testing.T) { Convey("Deepin is icon theme", t, func(c C) { ok, err := isIconTheme("testdata/Deepin/index.theme") c.So(ok, ShouldEqual, true) c.So(err, ShouldBeNil) }) } func TestIsCursorTheme(t *testing.T) { Convey("Deepin is cursor theme", t, func(c C) { ok, err := isCursorTheme("testdata/Deepin/index.theme") c.So(ok, ShouldEqual, true) c.So(err, ShouldBeNil) }) } �����������������������������������������������������������������������������������������������go-lib-5.6.0.9/misc.go������������������������������������������������������������������������������000664 �000000 �000000 �00000002461 13753517240 014316� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package lib import "github.com/godbus/dbus" const ( SystemBus = 1 SessionBus = 2 ) func UniqueOnSession(name string) bool { con, err := dbus.SessionBus() if err != nil { return false } return uniqueOnAny(con, name) } func UniqueOnSystem(name string) bool { con, err := dbus.SystemBus() if err != nil { return false } return uniqueOnAny(con, name) } func uniqueOnAny(bus *dbus.Conn, name string) bool { reply, err := bus.RequestName(name, dbus.NameFlagDoNotQueue) if err != nil || reply != dbus.RequestNameReplyPrimaryOwner { return false } return true } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mobileprovider/����������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 016053� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mobileprovider/README.md�������������������������������������������������������������000664 �000000 �000000 �00000000315 13753517240 017331� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������mobile-broadband-provider-info XML 配置解析库, 默认配置文件是 /usr/share/mobile-broadband-provider-info/serviceproviders.xml, 可以提 供各国家和地区的移动运营商信息(GSM/CDMA). �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mobileprovider/mobileprovider.go�����������������������������������������������������000664 �000000 �000000 �00000013472 13753517240 021433� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package mobileprovider import ( "encoding/xml" "fmt" "io/ioutil" "strings" "sync" ) const mobileServiceProvidersXMLFile = "/usr/share/mobile-broadband-provider-info/serviceproviders.xml" var ( errCountryNotFound = fmt.Errorf("country not found") errProviderNotFound = fmt.Errorf("provider not found") errGSMNotFound = fmt.Errorf("gsm not found") errCDMANotFound = fmt.Errorf("cdma not found") errAPNNotFound = fmt.Errorf("apn not found") errPlanNotFound = fmt.Errorf("plan not found") ) var mobileProviderDatabase *MobileServiceProviderDatabase var mobileProviderDatabaseLock sync.Mutex // GetMobileProviderDatabase return mobile service provider's database // that marshaled from serviceproviders.xml. func GetMobileProviderDatabase() (*MobileServiceProviderDatabase, error) { mobileProviderDatabaseLock.Lock() defer mobileProviderDatabaseLock.Unlock() if mobileProviderDatabase != nil { return mobileProviderDatabase, nil } mobileProviderDatabase = &MobileServiceProviderDatabase{} xmlContent, err := ioutil.ReadFile(mobileServiceProvidersXMLFile) if err != nil { return mobileProviderDatabase, err } err = xml.Unmarshal(xmlContent, mobileProviderDatabase) return mobileProviderDatabase, err } // GetAllCountryCode return all country code that provide mobile // service. func GetAllCountryCode() (codeList []string, err error) { database, err := GetMobileProviderDatabase() if err != nil { return } for _, c := range database.Countries { codeList = append(codeList, strings.ToUpper(c.Code)) } return } // GetProviders return all providers in target country. func GetProviders(countryCode string) (providers []*Provider, err error) { database, err := GetMobileProviderDatabase() if err != nil { return } found := false for _, c := range database.Countries { if strings.EqualFold(c.Code, countryCode) { found = true providers = c.Providers break } } if !found { err = errCountryNotFound } return } // GetProvider return the provider information that matched the provided country // code and provider name. func GetProvider(countryCode, providerName string) (provider *Provider, err error) { providers, err := GetProviders(countryCode) if err != nil { return } found := false for _, p := range providers { if p.Name.Body == providerName { found = true provider = p break } } if !found { err = errProviderNotFound } return } // GetGSM return the gsm information that matched the provided country // code and provider name. func GetGSM(countryCode, providerName string) (gsm *GSM, err error) { provider, err := GetProvider(countryCode, providerName) if err != nil { return } gsm = provider.GSM if gsm == nil { err = errGSMNotFound } return } // GetCDMA return the cdma information that match the provided // country code and provider name. func GetCDMA(countryCode, providerName string) (cdma *CDMA, err error) { provider, err := GetProvider(countryCode, providerName) if err != nil { return } cdma = provider.CDMA if cdma == nil { err = errCDMANotFound } return } // GetGSMForNetworkID return the gsm information that match the mcc // and mnc. func GetGSMForNetworkID(mcc, mnc string) (gsm *GSM, err error) { database, err := GetMobileProviderDatabase() if err != nil { return } found := false outside: for _, c := range database.Countries { for _, p := range c.Providers { if p.GSM != nil { for _, id := range p.GSM.NetworkID { if id.MCC == mcc && id.MNC == mnc { found = true gsm = p.GSM break outside } } } } } if !found { err = errGSMNotFound } return } // GetAPN return the apn information that match the provided // country code, provider name and apn value. func GetAPN(countryCode, providerName, apnValue, apnUsageType string) (apn *APN, err error) { gsm, err := GetGSM(countryCode, providerName) if err != nil { return } found := false for _, a := range gsm.APN { if a.Value == apnValue && GetAPNUsageType(a) == apnUsageType { found = true apn = a } } if !found { err = errAPNNotFound } return } // GetAPNName return apn's default name, if not exist, return empty // string. func GetAPNName(apn *APN) (name string) { if len(apn.Name) == 0 { return } name = apn.Name[0].Body return } // GetAPNUsageType return apn's usage type, if not exist, return empty // string. func GetAPNUsageType(apn *APN) (usageType string) { if apn.Usage == nil { return } usageType = apn.Usage.Type return } // GetProviderNames return all provider names in target country. func GetProviderNames(countryCode string) (names []string, err error) { providers, err := GetProviders(countryCode) if err != nil { return } for _, p := range providers { names = append(names, p.Name.Body) } return } // GetDefaultProvider return the default provider in target country, // usually is the first provider. func GetDefaultProvider(countryCode string) (defaultProvider string, err error) { providers, err := GetProviderNames(countryCode) if err != nil { return } if len(providers) > 0 { defaultProvider = providers[0] } else { err = errProviderNotFound } return } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mobileprovider/mobileprovider_plan.go������������������������������������������������000664 �000000 �000000 �00000010232 13753517240 022434� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package mobileprovider import ( "encoding/json" ) // Plan defines the unique information for each plan(gsm or cdma) in // provider. type Plan struct { IsGSM bool Name string // apn names for gsm or provider name for cdma ProviderName string APNValue string APNUsageType string } func MarshalPlan(plan Plan) (jsonStr string) { bytes, _ := json.Marshal(plan) jsonStr = string(bytes) return } func UnmarshalPlan(jsonStr string) (plan *Plan, err error) { plan = &Plan{} err = json.Unmarshal([]byte(jsonStr), plan) return } // GetPlans return all plans(apn names for gsm and provider name for // cdma) under target provider. func GetPlans(countryCode, providerName string) (plans []Plan, err error) { provider, err := GetProvider(countryCode, providerName) if err != nil { return } if provider.GSM != nil { for _, a := range provider.GSM.APN { plans = append(plans, Plan{ IsGSM: true, Name: GetAPNName(a), ProviderName: provider.Name.Body, APNValue: a.Value, APNUsageType: GetAPNUsageType(a), }) } } if provider.CDMA != nil { plans = append(plans, Plan{ IsGSM: false, Name: provider.Name.Body, ProviderName: provider.Name.Body, }) } return } // GetDefaultPlan return default plan for taget provider, usually is // the first plan. func GetDefaultPlan(countryCode, providerName string) (defaultPlan Plan, err error) { plans, err := GetPlans(countryCode, providerName) if err != nil { return } if len(plans) > 0 { defaultPlan = plans[0] } else { err = errPlanNotFound } return } // GetDefaultGSMPlanForCountry return default gsm plan in target country. func GetDefaultGSMPlanForCountry(countryCode string) (defaultGSMPlan Plan, err error) { providerNames, err := GetProviderNames(countryCode) if err != nil { return } // plans which apn usage type is "internet" owns higher priority defaultGSMInternetPlan, err := getDefaultGSMInternetPlanForCountry(countryCode) if err == nil { defaultGSMPlan = defaultGSMInternetPlan return } found := false outside: for _, providerName := range providerNames { plans, err := GetPlans(countryCode, providerName) if err != nil { continue } for _, p := range plans { if p.IsGSM { found = true defaultGSMPlan = p break outside } } } if !found { err = errPlanNotFound } return } func getDefaultGSMInternetPlanForCountry(countryCode string) (defaultGSMInternetPlan Plan, err error) { providerNames, err := GetProviderNames(countryCode) if err != nil { return } found := false outside: for _, providerName := range providerNames { plans, err := GetPlans(countryCode, providerName) if err != nil { continue } for _, p := range plans { if p.IsGSM && p.APNUsageType == "internet" { found = true defaultGSMInternetPlan = p break outside } } } if !found { err = errPlanNotFound } return } // GetDefaultCDMAPlanForCountry return default gsm plan in target country. func GetDefaultCDMAPlanForCountry(countryCode string) (defaultCDMAPlan Plan, err error) { providerNames, err := GetProviderNames(countryCode) if err != nil { return } found := false for _, providerName := range providerNames { plans, err := GetPlans(countryCode, providerName) if err != nil { continue } for _, p := range plans { if !p.IsGSM { found = true defaultCDMAPlan = p break } } } if !found { err = errPlanNotFound } return } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mobileprovider/mobileprovider_test.go������������������������������������������������000664 �000000 �000000 �00000011226 13753517240 022465� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package mobileprovider import ( C "gopkg.in/check.v1" "testing" ) type testWrapper struct{} func Test(t *testing.T) { C.TestingT(t) } func init() { C.Suite(&testWrapper{}) } func (*testWrapper) TestMobileProvider(c *C.C) { database, err := GetMobileProviderDatabase() c.Check(database, C.NotNil) c.Check(err, C.Equals, nil) } func (*testWrapper) TestGetProviders(c *C.C) { providers, err := GetProviders("cn") c.Check(len(providers), C.Equals, 3) c.Check(err, C.Equals, nil) providers, err = GetProviders("<invalid>") c.Check(providers == nil, C.Equals, true) c.Check(err, C.NotNil) } func (*testWrapper) TestGetProvider(c *C.C) { provider, err := GetProvider("cn", "China Mobile") c.Check(len(provider.GSM.APN), C.Equals, 3) c.Check(err, C.Equals, nil) provider, err = GetProvider("cn", "<invalid>") c.Check(provider == nil, C.Equals, true) c.Check(err, C.NotNil) } func (*testWrapper) TestGetGSM(c *C.C) { gsm, err := GetGSM("cn", "China Mobile") c.Check(len(gsm.APN), C.Equals, 3) c.Check(err, C.Equals, nil) gsm, err = GetGSM("cn", "<invalid>") c.Check(gsm == nil, C.Equals, true) c.Check(err, C.NotNil) } func (*testWrapper) TestGetCDMA(c *C.C) { cdma, err := GetCDMA("cn", "China Telecom") c.Check(cdma.Username, C.Equals, "ctnet@mycdma.cn") c.Check(err, C.Equals, nil) cdma, err = GetCDMA("cn", "<invalid>") c.Check(cdma == nil, C.Equals, true) c.Check(err, C.NotNil) cdma, err = GetCDMA("cn", "China Mobile") c.Check(cdma == nil, C.Equals, true) c.Check(err, C.NotNil) } func (*testWrapper) TestGetAPN(c *C.C) { apn, err := GetAPN("cn", "China Mobile", "cmnet", "internet") c.Check(GetAPNName(apn), C.Equals, "Internet") c.Check(err, C.Equals, nil) apn, err = GetAPN("cn", "China Mobile", "cmnet", "<invalid>") c.Check(apn == nil, C.Equals, true) c.Check(err, C.NotNil) apn, err = GetAPN("au", "Amaysim", "internet", "") c.Check(GetAPNName(apn), C.Equals, "") c.Check(GetAPNUsageType(apn), C.Equals, "") c.Check(err, C.Equals, nil) } func (*testWrapper) TestGetGSMForNetworkID(c *C.C) { gsm, err := GetGSMForNetworkID("460", "00") c.Check(len(gsm.APN), C.Equals, 3) c.Check(err, C.Equals, nil) gsm, err = GetGSMForNetworkID("460", "<invalid>") c.Check(gsm == nil, C.Equals, true) c.Check(err, C.NotNil) } func (*testWrapper) TestGetProviderNames(c *C.C) { names, err := GetProviderNames("cn") c.Check(names[0], C.Equals, "China Mobile") c.Check(names[1], C.Equals, "China Unicom") c.Check(names[2], C.Equals, "China Telecom") c.Check(err, C.Equals, nil) names, err = GetProviderNames("<invalid>") c.Check(len(names) == 0, C.Equals, true) c.Check(err, C.NotNil) } func (*testWrapper) TestGetPlans(c *C.C) { plans, err := GetPlans("cn", "China Mobile") c.Check(len(plans), C.Equals, 3) c.Check(err, C.Equals, nil) plans, err = GetPlans("ca", "Bell Mobility") c.Check(len(plans), C.Equals, 5) c.Check(err, C.Equals, nil) plans, err = GetPlans("cn", "<invalid>") c.Check(len(plans) == 0, C.Equals, true) c.Check(err, C.NotNil) } func (*testWrapper) TestGetDefaultPlan(c *C.C) { plan, err := GetDefaultPlan("cn", "China Mobile") c.Check(plan.Name, C.Equals, "WAP") c.Check(plan.ProviderName, C.Equals, "China Mobile") c.Check(err, C.Equals, nil) plan, err = GetDefaultPlan("cn", "<invalid>") c.Check(plan.Name, C.Equals, "") c.Check(err, C.NotNil) } func (*testWrapper) TestGetDefaultGSMPlanForCountry(c *C.C) { plan, err := GetDefaultGSMPlanForCountry("cn") c.Check(plan.Name, C.Equals, "Internet") c.Check(plan.ProviderName, C.Equals, "China Mobile") c.Check(err, C.Equals, nil) plan, err = GetDefaultGSMPlanForCountry("<invalid>") c.Check(plan.Name, C.Equals, "") c.Check(err, C.NotNil) } func (*testWrapper) TestGetDefaultCDMAPlanForCountry(c *C.C) { plan, err := GetDefaultCDMAPlanForCountry("cn") c.Check(plan.Name, C.Equals, "China Telecom") c.Check(err, C.Equals, nil) plan, err = GetDefaultCDMAPlanForCountry("<invalid>") c.Check(plan.Name, C.Equals, "") c.Check(err, C.NotNil) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/mobileprovider/mobileprovider_type.go������������������������������������������������000664 �000000 �000000 �00000006504 13753517240 022472� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package mobileprovider // map mobile-broadband-provider-info/serviceproviders.2.dtd to go // structures type MobileServiceProviderDatabase struct { Format string `xml:"format,attr"` Countries []*Country `xml:"country"` } type Country struct { Code string `xml:"code,attr"` Providers []*Provider `xml:"provider"` } type Provider struct { Primary ProviderPrimaryValue `xml:"primary,attr"` Name *Name `xml:"name"` GSM *GSM `xml:"gsm"` CDMA *CDMA `xml:"cdma"` } type ProviderPrimaryValue string const ( ProviderPrimaryValueTrue ProviderPrimaryValue = "true" ProviderPrimaryValueFalse ProviderPrimaryValue = "false" ) type GSM struct { NetworkID []*NetworkID `xml:"network-id"` MsisdnQuery []*MsisdnQuery `xml:"msisdn-query"` Voicemail []string `xml:"voicemail"` BalanceCheck []*BalanceCheck `xml:"balance-check"` BalanceTopUp []*BalanceTopUp `xml:"balance-top-up"` APN []*APN `xml:"apn"` } type APN struct { Value string `xml:"value,attr"` Plan []*APNPlan `xml:"plan"` Usage *Usage `xml:"usage"` Name []*Name `xml:"name"` Gateway string `xml:"gateway"` Username string `xml:"username"` Password string `xml:"password"` DNS []string `xml:"dns"` MMSC string `xml:"mmsc"` MMSproxy string `xml:"mmsproxy"` } type MsisdnQuery struct { USSD []*USSD `xml:"ussd"` SMS []*SMS `xml:"sms"` } type BalanceCheck struct { USSD []*USSD `xml:"ussd"` DTMF []string `xml:"dtmf"` SMS []*SMS `xml:"sms"` USSDResponse []string `xml:"ussd-response"` } type USSD struct { Replacement string `xml:"replacement,attr"` Body string `xml:",chardata"` } type SMS struct { Text string `xml:"text,attr"` Body string `xml:",chardata"` } type BalanceTopUp struct { USSD []*USSD `xml:"ussd"` SMS []*SMS `xml:"sms"` } type NetworkID struct { MCC string `xml:"mcc,attr"` MNC string `xml:"mnc,attr"` } type APNPlan struct { Type string `xml:"type,attr"` } const ( PlanTypeValuePrepaid = "prepaid" PlanTypeValuePostpaid = "postpaid" ) type Usage struct { Type string `xml:"type,attr"` } const ( UsageTypeInternet = "internet" UsageTypeMMS = "mms" UsageTypeWAP = "wap" ) type CDMA struct { Name []*Name `xml:"name"` Username string `xml:"username"` Password string `xml:"password"` DNS []string `xml:"dns"` SID []*SID `xml:"sid"` } type SID struct { Value string `xml:"value,attr"` } type Name struct { XMLLang string `xml:"xml:lang,attr"` Body string `xml:",chardata"` } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/multierr/����������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014674� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/multierr/append.go�������������������������������������������������������������������000664 �000000 �000000 �00000001700 13753517240 016470� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package multierr // Append is a helper function that will append more errors // onto an Error in order to create a larger multi-error. // // If err is not a multierror.Error, then it will be turned into // one. If any of the errs are multierr.Error, they will be flattened // one level into err. func Append(err error, errs ...error) *Error { switch err := err.(type) { case *Error: // Typed nils can reach here, so initialize if we are nil if err == nil { err = new(Error) } // Go through each error and flatten for _, e := range errs { switch e := e.(type) { case *Error: if e != nil { err.Errors = append(err.Errors, e.Errors...) } default: if e != nil { err.Errors = append(err.Errors, e) } } } return err default: newErrs := make([]error, 0, len(errs)+1) if err != nil { newErrs = append(newErrs, err) } newErrs = append(newErrs, errs...) return Append(&Error{}, newErrs...) } } ����������������������������������������������������������������go-lib-5.6.0.9/multierr/append_test.go��������������������������������������������������������������000664 �000000 �000000 �00000003461 13753517240 017535� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package multierr import ( "errors" "testing" ) func TestAppend_Error(t *testing.T) { original := &Error{ Errors: []error{errors.New("foo")}, } result := Append(original, errors.New("bar")) if len(result.Errors) != 2 { t.Fatalf("wrong len: %d", len(result.Errors)) } original = &Error{} result = Append(original, errors.New("bar")) if len(result.Errors) != 1 { t.Fatalf("wrong len: %d", len(result.Errors)) } // Test when a typed nil is passed var e *Error result = Append(e, errors.New("baz")) if len(result.Errors) != 1 { t.Fatalf("wrong len: %d", len(result.Errors)) } // Test flattening original = &Error{ Errors: []error{errors.New("foo")}, } result = Append(original, Append(nil, errors.New("foo"), errors.New("bar"))) if len(result.Errors) != 3 { t.Fatalf("wrong len: %d", len(result.Errors)) } } func TestAppend_NilError(t *testing.T) { var err error result := Append(err, errors.New("bar")) if len(result.Errors) != 1 { t.Fatalf("wrong len: %d", len(result.Errors)) } } func TestAppend_NilErrorArg(t *testing.T) { var err error var nilErr *Error result := Append(err, nilErr) if len(result.Errors) != 0 { t.Fatalf("wrong len: %d", len(result.Errors)) } } func TestAppend_NilErrorIfaceArg(t *testing.T) { var err error var nilErr error result := Append(err, nilErr) if len(result.Errors) != 0 { t.Fatalf("wrong len: %d", len(result.Errors)) } } func TestAppend_NonError(t *testing.T) { original := errors.New("foo") result := Append(original, errors.New("bar")) if len(result.Errors) != 2 { t.Fatalf("wrong len: %d", len(result.Errors)) } } func TestAppend_NonError_Error(t *testing.T) { original := errors.New("foo") result := Append(original, Append(nil, errors.New("bar"))) if len(result.Errors) != 2 { t.Fatalf("wrong len: %d", len(result.Errors)) } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/multierr/format.go�������������������������������������������������������������������000664 �000000 �000000 �00000001222 13753517240 016510� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package multierr import ( "fmt" "strings" ) // ErrorFormatFunc is a function callback that is called by Error to // turn the list of errors into a string. type ErrorFormatFunc func([]error) string // ListFormatFunc is a basic formatter that outputs the number of errors // that occurred along with a bullet point list of the errors. func ListFormatFunc(es []error) string { if len(es) == 1 { return fmt.Sprintf("1 error occurred:\n\t* %s", es[0]) } points := make([]string, len(es)) for i, err := range es { points[i] = fmt.Sprintf("* %s", err) } return fmt.Sprintf( "%d errors occurred:\n\t%s", len(es), strings.Join(points, "\n\t")) } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/multierr/format_test.go��������������������������������������������������������������000664 �000000 �000000 �00000001021 13753517240 017544� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package multierr import ( "errors" "testing" ) func TestListFormatFuncSingle(t *testing.T) { expected := `1 error occurred: * foo` errs := []error{ errors.New("foo"), } actual := ListFormatFunc(errs) if actual != expected { t.Fatalf("bad: %#v", actual) } } func TestListFormatFuncMultiple(t *testing.T) { expected := `2 errors occurred: * foo * bar` errs := []error{ errors.New("foo"), errors.New("bar"), } actual := ListFormatFunc(errs) if actual != expected { t.Fatalf("bad: %#v", actual) } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/multierr/multierr.go�����������������������������������������������������������������000664 �000000 �000000 �00000003205 13753517240 017066� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package multierr import ( "fmt" ) // code copy from github.com/hashicorp/go-multierror // Error is an error type to track multiple errors. This is used to // accumulate errors in cases and return them as a single "error". type Error struct { Errors []error ErrorFormat ErrorFormatFunc } func (e *Error) Error() string { fn := e.ErrorFormat if fn == nil { fn = ListFormatFunc } return fn(e.Errors) } // ErrorOrNil returns an error interface if this Error represents // a list of errors, or returns nil if the list of errors is empty. This // function is useful at the end of accumulation to make sure that the value // returned represents the existence of errors. func (e *Error) ErrorOrNil() error { if e == nil { return nil } if len(e.Errors) == 0 { return nil } return e } func (e *Error) GoString() string { return fmt.Sprintf("*%#v", *e) } // WrappedErrors returns the list of errors that this Error is wrapping. // It is an implementation of the errwrap.Wrapper interface so that // multierror.Error can be used with that library. // // This method is not safe to be called concurrently and is no different // than accessing the Errors field directly. It is implemented only to // satisfy the errwrap.Wrapper interface. func (e *Error) WrappedErrors() []error { return e.Errors } func New() *Error { return &Error{} } func (e *Error) Append(errs ...error) { // Go through each error and flatten for _, item := range errs { switch item := item.(type) { case *Error: if item != nil { e.Errors = append(e.Errors, item.Errors...) } default: if item != nil { e.Errors = append(e.Errors, item) } } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/multierr/multierr_test.go������������������������������������������������������������000664 �000000 �000000 �00000002341 13753517240 020125� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package multierr import ( "errors" "reflect" "testing" ) func TestError_Impl(t *testing.T) { var _ error = new(Error) } func TestErrorError_custom(t *testing.T) { errors := []error{ errors.New("foo"), errors.New("bar"), } fn := func(es []error) string { return "foo" } multi := &Error{Errors: errors, ErrorFormat: fn} if multi.Error() != "foo" { t.Fatalf("bad: %s", multi.Error()) } } func TestErrorError_default(t *testing.T) { expected := `2 errors occurred: * foo * bar` errors := []error{ errors.New("foo"), errors.New("bar"), } multi := &Error{Errors: errors} if multi.Error() != expected { t.Fatalf("bad: %s", multi.Error()) } } func TestErrorErrorOrNil(t *testing.T) { err := new(Error) if err.ErrorOrNil() != nil { t.Fatalf("bad: %#v", err.ErrorOrNil()) } err.Errors = []error{errors.New("foo")} if v := err.ErrorOrNil(); v == nil { t.Fatal("should not be nil") } else if !reflect.DeepEqual(v, err) { t.Fatalf("bad: %#v", v) } } func TestErrorWrappedErrors(t *testing.T) { errors := []error{ errors.New("foo"), errors.New("bar"), } multi := &Error{Errors: errors} if !reflect.DeepEqual(multi.Errors, multi.WrappedErrors()) { t.Fatalf("bad: %s", multi.WrappedErrors()) } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014341� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/const.go����������������������������������������������������������������������000664 �000000 �000000 �00000010404 13753517240 016015� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package notify const ( dbusDest = "org.freedesktop.Notifications" dbusPath = "/org/freedesktop/Notifications" ) const ( ExpiresDefault = -1 ExpiresNever = 0 ExpiresMillisecond = 1 ExpiresSecond = 1000 ) // hints const ( // When set, a server that has the "action-icons" capability will attempt to interpret // any action identifier as a named icon. The localized display name will be used to // annotate the icon for accessibility purposes. // The icon name should be compliant with the Freedesktop.org Icon Naming Specification. // type: bool HintActionIcons = "action-icons" // The type of notification this is. // type: string HintCategory = "category" // This specifies the name of the desktop filename representing the calling program. // This should be the same as the prefix used for the application's .desktop file. // An example would be "rhythmbox" from "rhythmbox.desktop". // This can be used by the daemon to retrieve the correct icon for the application, // for logging purposes, etc. // type: string HintDesktopEntry = "desktop-entry" // This is a raw data image format which describes the width, height, rowstride, // has alpha, bits per sample, channels and image data respectively. // type: (iiibiiay) HintImageData = "image-data" // Alternative way to define the notification image. // type: string HintImagePath = "image-path" // When set the server will not automatically remove the notification when an action // has been invoked. The notification will remain resident in the server until it is // explicitly removed by the user or by the sender. This hint is likely only useful // when the server has the "persistence" capability. // type: bool HintResident = "resident" // The path to a sound file to play when the notification pops up. // type: string HintSoundFile = "sound-file" // A themeable named sound from the freedesktop.org sound naming specification to play // when the notification pops up. Similar to icon-name, only for sounds. // An example would be "message-new-instant". // type: string HintSoundName = "sound-name" // Causes the server to suppress playing any sounds, if it has that ability. // This is usually set when the client itself is going to play its own sound. // type: bool HintSuppressSound = "suppress-sound" // When set the server will treat the notification as transient and by-pass the server's // persistence capability, if it should exist. // type: bool HintTransient = "transient" // Specifies the X location on the screen that the notification should point to. // The "y" hint must also be specified. // type: int32 HintX = "x" // Specifies the Y location on the screen that the notification should point to. // The "x" hint must also be specified. // type: int32 HintY = "y" // The urgency level. // type: byte HintUrgency = "urgency" ) type ClosedReason int const ( ClosedReasonInvalid = -1 ClosedReasonExpired = 1 ClosedReasonDismissedByUser = 2 ClosedReasonCallCloseNotification = 3 ClosedReasonUnknown = 4 ) func (i ClosedReason) String() string { switch i { case ClosedReasonInvalid: return "Invalid reason" case ClosedReasonExpired: return "The notification expired" case ClosedReasonDismissedByUser: return "The notification was dismissed by the user" case ClosedReasonCallCloseNotification: return "The notification was closed by a call to CloseNotification" default: return "Unknown reason" } } const ( UrgencyLow = 0 UrgencyNormal = 1 UrgencyCritical = 2 ) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/dbusnotify/�������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 016527� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/dbusnotify/init.go������������������������������������������������������������000664 �000000 �000000 �00000004152 13753517240 020023� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package dbusnotify import ( "fmt" "sync" "github.com/godbus/dbus" ) var __conn *dbus.Conn = nil var __connLock sync.Mutex var __ruleCounter map[string]int = nil var __ruleCounterLock sync.Mutex func getBus() *dbus.Conn { __connLock.Lock() defer __connLock.Unlock() if __conn == nil { var err error __conn, err = dbus.SessionBus() if err != nil { panic(err) } } return __conn } func getRuleCounter() map[string]int { __ruleCounterLock.Lock() defer __ruleCounterLock.Unlock() if __ruleCounter == nil { __ruleCounter = make(map[string]int) } return __ruleCounter } func dbusCall(method string, flags dbus.Flags, args ...interface{}) (err error) { err = getBus().BusObject().Call(method, flags, args...).Err if err != nil { fmt.Println(err) } return } func dbusAddMatch(rule string) (err error) { ruleCounter := getRuleCounter() __ruleCounterLock.Lock() defer __ruleCounterLock.Unlock() if _, ok := ruleCounter[rule]; !ok { err = dbusCall("org.freedesktop.DBus.AddMatch", 0, rule) } ruleCounter[rule]++ return } func dbusRemoveMatch(rule string) (err error) { ruleCounter := getRuleCounter() __ruleCounterLock.Lock() defer __ruleCounterLock.Unlock() if _, ok := ruleCounter[rule]; !ok { return } ruleCounter[rule]-- if ruleCounter[rule] == 0 { delete(ruleCounter, rule) err = dbusCall("org.freedesktop.DBus.RemoveMatch", 0, rule) } return } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/dbusnotify/notify.go����������������������������������������������������������000664 �000000 �000000 �00000012611 13753517240 020367� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package dbusnotify import ( "errors" "fmt" "reflect" "runtime" "sync" "github.com/godbus/dbus" ) /*prevent compile error*/ var _ = fmt.Println var _ = runtime.SetFinalizer var _ = sync.NewCond var _ = reflect.TypeOf type Notifier struct { Path dbus.ObjectPath DestName string core dbus.BusObject signals map[chan *dbus.Signal]struct{} signalsLocker sync.Mutex } func (obj *Notifier) _createSignalChan() chan *dbus.Signal { obj.signalsLocker.Lock() ch := make(chan *dbus.Signal, 10) getBus().Signal(ch) obj.signals[ch] = struct{}{} obj.signalsLocker.Unlock() return ch } func (obj *Notifier) _deleteSignalChan(ch chan *dbus.Signal) { obj.signalsLocker.Lock() delete(obj.signals, ch) getBus().RemoveSignal(ch) obj.signalsLocker.Unlock() } func DestroyNotifier(obj *Notifier) { obj.signalsLocker.Lock() defer obj.signalsLocker.Unlock() if obj.signals == nil { return } for ch := range obj.signals { getBus().RemoveSignal(ch) } obj.signals = nil runtime.SetFinalizer(obj, nil) _ = dbusRemoveMatch("type='signal',path='" + string(obj.Path) + "',interface='org.freedesktop.DBus.Properties',sender='" + obj.DestName + "',member='PropertiesChanged'") _ = dbusRemoveMatch("type='signal',path='" + string(obj.Path) + "',interface='org.freedesktop.Notifications',sender='" + obj.DestName + "',member='PropertiesChanged'") _ = dbusRemoveMatch("type='signal',path='" + string(obj.Path) + "',interface='org.freedesktop.Notifications',sender='" + obj.DestName + "',member='NotificationClosed'") _ = dbusRemoveMatch("type='signal',path='" + string(obj.Path) + "',interface='org.freedesktop.Notifications',sender='" + obj.DestName + "',member='ActionInvoked'") } func (obj *Notifier) CloseNotification(id uint32) (_err error) { _err = obj.core.Call("org.freedesktop.Notifications.CloseNotification", 0, id).Store() if _err != nil { fmt.Println(_err) } return } func (obj *Notifier) GetCapabilities() (caps []string, _err error) { _err = obj.core.Call("org.freedesktop.Notifications.GetCapabilities", 0).Store(&caps) if _err != nil { fmt.Println(_err) } return } func (obj *Notifier) GetServerInformation() (name string, vendor string, version string, spec_version string, _err error) { _err = obj.core.Call("org.freedesktop.Notifications.GetServerInformation", 0).Store(&name, &vendor, &version, &spec_version) if _err != nil { fmt.Println(_err) } return } func (obj *Notifier) Notify(app_name string, id uint32, icon string, summary string, body string, actions []string, hints map[string]dbus.Variant, timeout int32) (id_ uint32, _err error) { _err = obj.core.Call("org.freedesktop.Notifications.Notify", 0, app_name, id, icon, summary, body, actions, hints, timeout).Store(&id_) if _err != nil { fmt.Println(_err) } return } func (obj *Notifier) ConnectNotificationClosed(callback func(id uint32, reason uint32)) func() { sigChan := obj._createSignalChan() go func() { for v := range sigChan { if v.Path != obj.Path || v.Name != "org.freedesktop.Notifications.NotificationClosed" || 2 != len(v.Body) { continue } if reflect.TypeOf(v.Body[0]) != reflect.TypeOf((*uint32)(nil)).Elem() { continue } if reflect.TypeOf(v.Body[1]) != reflect.TypeOf((*uint32)(nil)).Elem() { continue } callback(v.Body[0].(uint32), v.Body[1].(uint32)) } }() return func() { obj._deleteSignalChan(sigChan) } } func (obj *Notifier) ConnectActionInvoked(callback func(id uint32, action_key string)) func() { sigChan := obj._createSignalChan() go func() { for v := range sigChan { if v.Path != obj.Path || v.Name != "org.freedesktop.Notifications.ActionInvoked" || 2 != len(v.Body) { continue } if reflect.TypeOf(v.Body[0]) != reflect.TypeOf((*uint32)(nil)).Elem() { continue } if reflect.TypeOf(v.Body[1]) != reflect.TypeOf((*string)(nil)).Elem() { continue } callback(v.Body[0].(uint32), v.Body[1].(string)) } }() return func() { obj._deleteSignalChan(sigChan) } } func NewNotifier(destName string, path dbus.ObjectPath) (*Notifier, error) { if !path.IsValid() { return nil, errors.New("The path of '" + string(path) + "' is invalid.") } core := getBus().Object(destName, path) obj := &Notifier{Path: path, DestName: destName, core: core, signals: make(map[chan *dbus.Signal]struct{})} _ = dbusAddMatch("type='signal',path='" + string(obj.Path) + "',interface='org.freedesktop.Notifications',sender='" + obj.DestName + "',member='NotificationClosed'") _ = dbusAddMatch("type='signal',path='" + string(obj.Path) + "',interface='org.freedesktop.Notifications',sender='" + obj.DestName + "',member='ActionInvoked'") runtime.SetFinalizer(obj, func(_obj *Notifier) { DestroyNotifier(_obj) }) return obj, nil } �����������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/examples/���������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 016157� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/examples/action.go������������������������������������������������������������000664 �000000 �000000 �00000002676 13753517240 017776� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������// +build ignore /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package main import ( "log" "pkg.deepin.io/lib/notify" "time" ) func init() { notify.Init("notify-example-action") } func show() { n := notify.NewNotification("summary", "body", "icon") n.Timeout = notify.ExpiresSecond * 5 n.AddAction("x", "XXX", func(_n *notify.Notification, action string) { log.Println("action", action, "invoked") _n.Summary = n.Summary + "!" _n.Show() }) n.AddAction("close", "Close", func(_n *notify.Notification, action string) { log.Println("close it") }) n.Closed().On(func(_n *notify.Notification, reason notify.ClosedReason) { log.Printf("reason: %d %s\n", reason, reason) }) n.Show() } func main() { go show() time.Sleep(time.Second * 100) } ������������������������������������������������������������������go-lib-5.6.0.9/notify/examples/desktop-icon.jpeg����������������������������������������������������000664 �000000 �000000 �00000007434 13753517240 021435� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������JFIF��H�H���Created with GIMP�C�     �C   ��N�K������������������������������ ���j͉D&GGeic Pk i1wo%Pr{I{:3bYD14IͶy]nɻZp7 <gid4!OZZw2Ye2DN<e*'c:'D(5If1H@gD;�fT7/=/@DWd_cx&#u/qYD�%�����������!4"5��2KQ'+LfI'6:SW;sps]P5O_ڰPxkiMBWưN$P}wum'dp2i6"f4x5F+i†d.3wG{<\qcA`iFTT[txU<H/ᷱ"'y1gYڎՅYG_[.5yg ή t,]+adHL&TI�0���������!AQ1q#23"4�?j53�qipk G#D!P>6{vLW:u_/ChPEM6\!oMԬgoƆRF?o%ZR22[9p*5fr:{Lf3XAt9˴2+*_-;.%1.ݫt3333uY+ /)r)G|rhp[%4]!5ZLmt-,:ݿRcnE3XrZ*fEG;Y*̱ײ.:gbjIL(d#21Ţ`6sIr&'#ӄ�3���������!Q12Aab "0Rq�?Y*ufV+rr ,S[E;b$&i#�hm44 oOB<okbfюaFhʺ5Eu]WSJY?K� B`pmu?8¹4O 9 ;q܀�M h:b4Z><>y+2u\T 26ޑ6窘t.DB@Uw!f!?.Oy"8fGj]Cy~sa)MV\48: +n[役 'L:a+�:��������1!"2 #34ABQRatq0bdr��?! k`m^gׅh^k'ׅwFѫdfZ6+JAi�%x8Zq|kwp�"?T5_lAer7W&bmIV=!r>L,ױc?SM_+/XYR Yֵf9c9dF 5�i8W^?Sx�N$2sE"e٠I!l}|ҵN̻ZCE4pa0r E'3`NRjƫl(*Y,+_/X8h#u5)1,buH{_D-( ~Ĩm uyzfǔݳ9CٖNF#<|4 nA:;ʸI3H iDq mOy:wν{-b8 皁uW@B}tk+Jҿ�%��������!1AQaqё��?!̹Jn\%@ :xKLj1){@C$Hʒb?{ Ɓ acp37r*+ _Tzy銤41d@R৩;VV7LrVP XܑH>CgQgG }7=G5t K/ F-V[8\UF"W뙵¢0qIC%4=law2H1k)Cm@o2n * >؆`<8Aߴ^`l߸AmXfL1<Q5pܼ+�*=\Y}@Yp5aEܢ{@Ěh'g� �����#)Ihch,R~%�8S�&���������!1AQaq�?4ġ-wQIdzH#l9H%dL׀垼?&5x\=3v�y} 74/ "|<3"íI+GH~N0\+hF$a+Q }X/YwTDd~!?~{G-"$ EM°eGв1h ?گ*u1Ak Jeܟ&eFN5p1Ył1- *ͭzo树*.s~ѓpViRűYBy9~z; NL$j_ZA�%���������!1AQaq�?9x"wp 0J,)80K-Hh&F4`nh\57Fa~TWEgb$xH3mi"L.e6yhu{�@#tG X3;@ -a=_Xj*c_U307r%Z1,,s_Ą43\VAիU|� _+˟<bMWX"u/B1 ;D0pWVg7XsR�"���������!1AQaq��?; e]&B xzv}Msl{[QX#b^jT 5$/0 7xbx(˼C8Z9IKQ vѶU!Ñ2~0neiCY>_?r"_Z"Q;:?z,%zyJb\8-v=zׂF_j%h %p�Hn\2d6|-̽R멀ɅmZrE4/|JAqJ- ~/n¡Yyp0)ՑשʻS=Wϗ)s7/>Ƣ:P˝0KpWī Mt2,'lP `'ۤ툉\/8UmAV%()FSjm\ey�`ՖW=w *68FHGFVb2p Q>!*P0Eڦ#RToHZpLh42(Z @ʹGa}An]X(y8w54BC* Zao6߉������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/examples/image.go�������������������������������������������������������������000664 �000000 �000000 �00000002737 13753517240 017601� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������// +build ignore /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package main import ( "image" _ "image/jpeg" _ "image/png" "log" "os" "pkg.deepin.io/lib/notify" ) func init() { notify.Init("notify-example-image") } func loadImage(filename string) (image.Image, error) { infile, err := os.Open(filename) if err != nil { return nil, err } defer infile.Close() img, _, err := image.Decode(infile) if err != nil { return nil, err } return img, nil } func show(filename string) { n := notify.NewNotification("image test", "file "+filename, "") img, err := loadImage(filename) if err != nil { log.Fatal(err) } n.SetImage(img) n.Show() n.Destroy() } func main() { // opaque show("./desktop-icon.jpeg") // not opaque show("./libreoffice-base.png") notify.Destroy() } ���������������������������������go-lib-5.6.0.9/notify/examples/libreoffice-base.png�������������������������������������������������000664 �000000 �000000 �00000020376 13753517240 022056� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������PNG  ��� IHDR���������>a���sBIT|d��� pHYs�� �� B(x���tEXtSoftware�www.inkscape.org<�� {IDATxy$WuED.UյuzQPWdԭp0 b Bv$!-l#5`0Kg=>XVK̈ޝ?"2++ά%^̎^(a6unvYG{6o=8ۃ}ƿ|8g[o.h˪]�|ƿ/|xn>|Ri(3Kz)n|nƿ/&\ IeA �A.N_Ok n5�`WQf~d�@k/Z`]3mp:7o9%~Ր >kǛܡKg�skgi-R!|RC&Ƽ;萎g�lm˛򏟏U/'g1D@ )o| [;mo;aTؔ >6WoQXt�5t͚5KEj@r[:wo1ھx\k.h?nz|5M6gt-@5 TZ:js/E^@ 8lC&OC&η ͓GPv`Aoooݡ㼷md0 |w6m꿎sͫt>R�@&T^v6nMN A1s Y PSMm�e28_ncL_>YC||s0LDT>(Pٲ,u`L0F|?2ż8G!:5 rb``�cL lb+{?1i0䁏_hϘˆyayфs�w0@%1\Ϋ^kw1xh Gs6"\a� bkgu.>c1O_+Hai0@0cRrZ0 k/ew2q"L& c{-,3@ Xr%B zC6d;?iۏQ:,/ؓ yj===^BP ߳}15d6/*Իa0O-ϳj*&''ai]CDM!~ �b ֬Y^;ޗqDSy}& ~U# YS߯XzVT`bb .zv{G" v_Tp#63;i�˙gD }xQ؄ nkOu`;N(Qcڵ`fUrH#lw7G&]$T0ӎ*An:LP/<' 4G./PpTuN��A_ŗ|SV?p+ ;Aᡎ*{vZFFFja;KAc#M@p q.)Ws"EPX~=###L=\];Nv{ AG�� q�@044T߱!9Jo?ݣP #<('f,k[bӔJmppgy^<ϛ�/> sb[ްHRAq:3@%6lp \ݼ0Դs>9Z@cK1E7w: � XL_Z&.v|F䁛?u&/o[ 5Lpuc~n',K ֭c|| ]o> FqM&sK[cK ]|.\6aR"`ڵuS7m= :vgu5mߍ8M[O89Lf͚n7n҄ n?XfYbXi޸q EXimן$`u'~;a3D+\:�8f' ޸ް<#l7 4CQt\t~m+Ed(`@P9 ܩ޴ec⛤qu9JKM:xkG鵋\tϿq `fW7+�ZaVCW%H ~/P)C25wn�<3s^cP#†*LB6d#Gyތ.7�3{|`~ttFԺ]g4xWP"*BqQGEk]O|ny@+hāHdkTd|y=FrkZK[ *AB۸ PBi�;S-}?GF@0W2@N;ǎ9WwA@= |}G8:qUpM-W:{nA! b'Ѕ8QmJw [gA xi4%'vwtT) @iNIʯͱReqDBA"i<f: WW�[TD TkNҬ3�c.hˋΑHQ"yGPJA{#=:qq)),E DgAB+Zk<)ۧgsz X>O ^EtXj1@r6p3Qg~^#S=(MFh ~Z#665΀1jx 8(#<7P3Y^cW0c7%oV : 5x+,fL_5$S' 2?3 ~>'ΦЁF>^e<O |D 0DфL̤N:̤&_(s`N9&z6?an:@ffⵆw�?~:&3֘1ǃx}\ltΒ[gCV FCR]B<Ժ"H-)?*X e_A+TPB0B&ԁa5?^</cug9MUGVqݠt Nz跏~JN"�vts~#w^/FnV<d%D鼒@q؂̤T�JS>;W0 �tZ38|G&</_`mgc7M!a Pa# QGm`0@�4H* A:4xAGSto͗g˯m=\Vbo݂88P"(PB!Jb[+pSؙ)W^@^E *r\Hxy爎D|ΟqGwvz̈` [ਨB�4( ;T]GV;x/{bI/3^( 6Cإ^|pNpSR=o/ּXUqNbSlyz^!^x?Wcm]z_#X܂&fYA{? D!�}-N] %@tDC4d!YPe UY ~@p6�FR ^Js�hrk߅ P+{ۃqGy5EfNh U*4~.kYC@O KT կU:т ]Vd* .P7V}dL�pQōWIoMq4(Ī&TY\(yu2RI,g(]&�tFc#ቯc߇0P:��:NAʡr1Oqݳ ^KD&pbPP8%bP@g|y/rab1~#P(}{tj\p& 5Qswc Riӂrӫf+Ǿ$Os =:̏1ހ]YCRY!#$:(`:7V|:О?yh&_,0D'y,!Vr>^,_g0ޚ( �¢6#WWuT0kM$pf^T-5[8c<O1qx [0L0N84G3A it:VU}% `јe c?C9Z=?׭QPiU:ON ؿ@š5wC+cCȓC=7LqxWcXPql�kr&vJ,|^i ˧kUܖnuӻ#80^4l%��>TT h1-pk؋jb!xtɣD!f,Ѥ'Z8hy?|O7M]l{m]Ρ`FI!QA;<@@s l`0|*q`,vcP/}�-("B|z^A\w (@?qOt0Qgj p 8TX(8wg! \_ bbJR6%0 g@BJtBu\_Z&^PI@!FR Z{Qc_8il0&4o:m6Ed1`6�_?0 HtZ[+n݋@@[`cxSJY�% $@@ OҠ|Ё�R �AqvP7 Pa�t S`�Y Ps- "~s^{֢Nz㉗A961{qA�  q$ b�:CCh4 �ZWp<{ALl*kA�FTQº|Y, |&x侟|a+";؍+ bJ;B2Z�?� )� `@SxuxV>:S_}85S*߮5Uڴ^m:v66+V(U<y1S!#SdRt%3%͒YKq8Obr<ۂX.6N'cy::0#O3tgL>Y8Y!85gq֫7ޏ (rTk^U�}l^MM{8OiDxd(X8=~.]Qڋ y׫Gk3a&"[naC,pDP𘁨Կ3׭gk>Rs?, Ȝ�]1\7 X+ePU A]\p.Աq_8</ IK4V>'#)е&ÊsݞgŶ.\T_R((/~X( ' (!hv>@Ri'8ן) A I!ɮҵҠN $SGG:2N4a")G8epS. AqWϏt Kѽ95BP4XXyv*l. dW Aq_0S5a RqF)M~:Gwm2!гg*&NTj!HX)p cJh? EMmZ2Q@D @jOs3 AH]]0{&AvLʅxYD#e`Z,i~߆ KA;|tEPr .@nMO<f 1ଢ W]|!H8(QQ4A:M M[;H*%8 (?]ާZ:#cdYw NE�J�[BC9I'c`)lrhǩ'8TOBDT>ACgl!kSSJU'|:fJK!H 30ʋ[ch -6p.4 hpYUBw<`["$鴦2U+_c& Q8:A8bh(B 9K�u8T.մY` d\0cB37A%U)tF]=qF EL!)A4*U{_oc.& x)-:ЇHHLÊ L <z@F-RPpX\]<<tq+q)UxE-t C@iUF _9@ -bÐT>D`xoR$F~\9̘ӨnAMI<dT>@Bw_Ku>ViJ!"R6LP�Քq% $szd7 D;|AC+,fw/Qo}rӾj㯬w� A3�J'. &5{pG APA:tW23]0E("8OB bk{`8v.!(-Q@5eF tc`јG88.&š&|Au9ѽAJ' g!$vJ [!H\KW_4| UtA]ߩKU�jQ.P`苗[3>^IuHHw麤TF PP;1AWu*xJ 2>^oK2ͅ @[r; sd2iT.E r:!+A0)*9`U2>F8<?޴/h-.8܋/ }&d?0N`@>?Qw8[罪'I@a9$퐬\-*Xy *$ T2L)XW:+LiR$AA\R8y#EZ2/72N2X p.DT*QɦbA2o*N&h_^9ztb(A;BRVT2*V C\�_7,zx%گjeKHH.YY6EX1.^TWZʕANjE)sSD#UF}GӨ.En4؟JH2Z\c)J`O^?YVQjZ' +FDe{NM7XG$Vo=%=6%z,� v]mb [V(d㫘`Ǧf_Iҍ_nZ{ժ'q@h}vp0D\i1�$A4Q @;|_оCqE lC;ug} q %"et\l(" D J [5@@-~`Dhզ3O'1$8QE" "'4~C)X-hVpS}�jG�y/u2@峃 A`̀o|C5[1~)TMwH. tf=ZRv iQ P}LP S!:kצh(t\4 A 6<\'k'_żKu<4{Ap2|I0BK۩i\@& <`_h/�%'ܿJ&6JȪ[L4*lG+%`TK*\K= J,lUEBT BNE,e;(tq_qTDAaz>@% *gu,6nȩڭ^tx衇JYO^ dU~^Y+}糵:,9,ߵΐ:{Xnm~Y,`Y}3~(Sy"WٶO!]iR~}gDXQM~(jߌ|_8ҬX^x 7-zFjXc&B0om_nsp3_{~�sXr+ߖئuy|w.V`S=pk)Y:;j~����IENDB`������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/examples/simple.go������������������������������������������������������������000664 �000000 �000000 �00000001727 13753517240 020006� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������// +build ignore /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package main import ( "pkg.deepin.io/lib/notify" ) func init() { notify.Init("notify-example-simple") } func main() { n := notify.NewNotification("x", "y", "player") n.Show() n.Destroy() notify.Destroy() } �����������������������������������������go-lib-5.6.0.9/notify/examples/update.go������������������������������������������������������������000664 �000000 �000000 �00000002537 13753517240 017777� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������// +build ignore /* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package main import ( "log" "time" "pkg.deepin.io/lib/notify" ) func init() { notify.Init("notify-example-update") } func main() { serverInfo, err := notify.GetServerInfo() if err != nil { log.Fatal(err) } log.Printf("serverInfo: %#v\n", serverInfo) caps, err := notify.GetServerCaps() if err != nil { log.Println(err) } log.Println("server caps:", caps) n := notify.NewNotification("s1", "b1", "deepin-music") n.Show() time.Sleep(time.Second * 2) n.Update("s2", "b2", "deepin-terminal") n.Show() time.Sleep(time.Second * 2) n.Update("s3", "b3", "deepin-terminal") n.Show() } �����������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/image.go����������������������������������������������������������������������000664 �000000 �000000 �00000004443 13753517240 015757� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package notify import ( "image" "image/draw" ) // This is a raw data image format which describes the width, height, rowstride, // has alpha, bits per sample, channels and image data respectively. type Image struct { Width int32 Height int32 RowStride int32 HasAlpha bool BitsPerSample int32 Channels int32 Pix []byte } func (n *Notification) SetImage(img image.Image) { n.SetHint(HintImageData, NewImage(img)) } func toRGBA(src image.Image) *image.RGBA { b := src.Bounds() m := image.NewRGBA(image.Rect(0, 0, b.Dx(), b.Dy())) draw.Draw(m, m.Bounds(), src, b.Min, draw.Src) return m } func NewImage(src image.Image) *Image { return newImageFromRGBA(toRGBA(src)) } func newImageFromRGBA(img *image.RGBA) *Image { opaque := img.Opaque() b := img.Bounds() w := b.Dx() h := b.Dy() nchan := 4 if opaque { nchan = 3 } stride := w * nchan pix := make([]byte, stride*h) // fill data to pix // img.Pix idx i := 0 // pix idx p := 0 if opaque { for y := 0; y < h; y++ { // copy one row for x := 0; x < w; x++ { pix[p] = img.Pix[i] // R pix[p+1] = img.Pix[i+1] // G pix[p+2] = img.Pix[i+2] // B // skip A p += nchan i += (nchan + 1) } } } else { for y := 0; y < h; y++ { // copy one row copy(pix[p:], img.Pix[i:i+stride]) p += stride i += img.Stride } } return &Image{ Width: int32(w), Height: int32(h), RowStride: int32(stride), HasAlpha: !opaque, BitsPerSample: 8, Channels: int32(nchan), Pix: pix, } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/notification.go���������������������������������������������������������������000664 �000000 �000000 �00000011053 13753517240 017356� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package notify import ( "errors" "runtime" "sync" "github.com/godbus/dbus" "pkg.deepin.io/lib/event" ) type ActionCallback func(n *Notification, action string) type _HintMap map[string]dbus.Variant type Notification struct { id uint32 AppName string Summary string Body string Icon string Timeout int32 closedReason ClosedReason mu sync.Mutex actions []string actionMap map[string]ActionCallback hints _HintMap // event closed (n *Notification, reason ClosedReason) closed *event.Event actionInvokedConnectRet func() notificationClosedConnectRet func() } // Create a new Notification. // summary text is required, but all other paramters are optional. func NewNotification(summary, body, icon string) *Notification { n := &Notification{ Summary: summary, Body: body, Icon: icon, Timeout: ExpiresDefault, hints: make(_HintMap), closedReason: ClosedReasonInvalid, actionMap: make(map[string]ActionCallback), closed: event.New(func(_n *Notification, reason ClosedReason) {}), } runtime.SetFinalizer(n, func(_n *Notification) { _n.Destroy() }) return n } func (n *Notification) Closed() *event.Event { return n.closed } func (n *Notification) Destroy() { if n.actionInvokedConnectRet != nil { n.actionInvokedConnectRet() n.actionInvokedConnectRet = nil } if n.notificationClosedConnectRet != nil { n.notificationClosedConnectRet() n.notificationClosedConnectRet = nil } runtime.SetFinalizer(n, nil) } // Updates the notification text and icon. // This won't send the update out and display it on the screen. // For that, you will need to call Show() func (n *Notification) Update(summary, body, icon string) { n.Summary = summary n.Body = body n.Icon = icon } func (n *Notification) getAppName() string { if n.AppName == "" { return defaultAppName } return n.AppName } // Tells the notification server to display the notification on the screen. func (n *Notification) Show() error { n.mu.Lock() defer n.mu.Unlock() if n.actionInvokedConnectRet == nil { n.actionInvokedConnectRet = notifier.ConnectActionInvoked(func(id uint32, action string) { if n.id != id { return } callback := n.actionMap[action] if callback != nil { callback(n, action) } }) } if n.notificationClosedConnectRet == nil { n.notificationClosedConnectRet = notifier.ConnectNotificationClosed(func(id, reason uint32) { if n.id != id { return } n.closedReason = ClosedReason(reason) _ = n.closed.Trigger(n, ClosedReason(reason)) }) } id, err := notifier.Notify(n.getAppName(), n.id, n.Icon, n.Summary, n.Body, n.actions, n.hints, n.Timeout) if err != nil { return err } n.id = id return nil } func (n *Notification) SetHint(key string, value interface{}) { n.hints[key] = dbus.MakeVariant(value) } func (n *Notification) ClearHints() { n.hints = make(_HintMap) } func (n *Notification) AddAction(action, label string, callback ActionCallback) { if action == "" || label == "" || callback == nil { return } n.actions = append(n.actions, action, label) n.actionMap[action] = callback } func (n *Notification) ClearActions() { n.actions = nil n.actionMap = make(map[string]ActionCallback) } // Sets the category of this notification. // This can be used by the notification server to filter or display the data in a certain way. func (n *Notification) SetCategory(category string) { n.SetHint(HintCategory, category) } // Sets the urgency level of this notification. func (n *Notification) SetUrgency(urgency byte) { n.SetHint(HintUrgency, urgency) } func (n *Notification) Close() error { if n.id == 0 { return errors.New("notification id is 0") } return notifier.CloseNotification(n.id) } func (n *Notification) GetClosedReason() ClosedReason { return n.closedReason } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/notify/notify.go���������������������������������������������������������������������000664 �000000 �000000 �00000004166 13753517240 016207� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package notify import ( "pkg.deepin.io/lib/notify/dbusnotify" ) var ( defaultAppName string notifier *dbusnotify.Notifier isInitted bool ) // This must be called before anny other functions. func Init(appName string) bool { if appName == "" { return false } if isInitted { return true } defaultAppName = appName var err error notifier, err = dbusnotify.NewNotifier(dbusDest, dbusPath) if err != nil { panic(err) } isInitted = true return true } // Gets whether or not libnotify is initialized. func IsInitted() bool { return isInitted } // This should be called when the program no longer needs libnotify for // the rest of its lifecycle, typically just before exitting. func Destroy() { dbusnotify.DestroyNotifier(notifier) notifier = nil isInitted = false } func GetAppName() string { return defaultAppName } func SetAppName(name string) { defaultAppName = name } func GetServerCaps() ([]string, error) { return notifier.GetCapabilities() } type ServerInfo struct { Name, Vendor, Version, SpecVersion string } //name string, vendor string, version string, spec_version string func GetServerInfo() (*ServerInfo, error) { name, vendor, version, specVersion, err := notifier.GetServerInformation() if err != nil { return nil, err } return &ServerInfo{ Name: name, Vendor: vendor, Version: version, SpecVersion: specVersion, }, nil } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pam/���������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 013606� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pam/handler.go�����������������������������������������������������������������������000664 �000000 �000000 �00000002726 13753517240 015561� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package pam import "sync" // ConversationHandler is an interface for objects that can be used as // conversation callbacks during PAM authentication. type ConversationHandler interface { // RespondPAM receives a message style and a message string. If the // message Style is PromptEchoOff or PromptEchoOn then the function // should return a response string. RespondPAM(Style, string) (string, error) } // ConversationFunc is an adapter to allow the use of ordinary functions as // conversation callbacks. type ConversationFunc func(Style, string) (string, error) func (f ConversationFunc) RespondPAM(s Style, msg string) (string, error) { return f(s, msg) } var globalHandlers struct { sync.Mutex m map[handlerId]ConversationHandler nextId handlerId } type handlerId int func init() { globalHandlers.m = make(map[handlerId]ConversationHandler) globalHandlers.nextId = 1 } func addHandler(handler ConversationHandler) handlerId { globalHandlers.Lock() defer globalHandlers.Unlock() id := globalHandlers.nextId globalHandlers.nextId++ globalHandlers.m[id] = handler return id } func getHandler(id handlerId) ConversationHandler { globalHandlers.Lock() defer globalHandlers.Unlock() v := globalHandlers.m[id] if v != nil { return v } panic("handler not found") } func deleteHandler(id handlerId) { globalHandlers.Lock() defer globalHandlers.Unlock() if _, ok := globalHandlers.m[id]; !ok { panic("handler not found") } delete(globalHandlers.m, id) } ������������������������������������������go-lib-5.6.0.9/pam/pam.go���������������������������������������������������������������������������000664 �000000 �000000 �00000017266 13753517240 014726� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package pam /* #cgo LDFLAGS: -lpam #include <security/pam_appl.h> #include <stdlib.h> void init_pam_conv(struct pam_conv *conv, long c); */ import "C" import ( "fmt" "strings" "unsafe" ) // Style is the type of message that the conversation handler should display. type Style int // Coversation handler style types. const ( // PromptEchoOff indicates the conversation handler should obtain a // string without echoing any text. PromptEchoOff Style = C.PAM_PROMPT_ECHO_OFF // PromptEchoOn indicates the conversation handler should obtain a // string while echoing text. PromptEchoOn = C.PAM_PROMPT_ECHO_ON // ErrorMsg indicates the conversation handler should display an // error message. ErrorMsg = C.PAM_ERROR_MSG // TextInfo indicates the conversation handler should display some // text. TextInfo = C.PAM_TEXT_INFO ) // return values // const ( // Success = C.PAM_SUCCESS // SystemErr = C.PAM_SYSTEM_ERR // BadItem = C.PAM_BAD_ITEM // BufErr = C.PAM_BUF_ERR // PermDenied = C.PAM_PERM_DENIED // Abort = C.PAM_ABORT // AuthErr = C.PAM_AUTH_ERR // CredInsufficient = C.PAM_CRED_INSUFFICIENT // // AuthInfoUnavailable = C.PAM_AUTHINFO_UNVAIL // MaxTries = C.PAM_MAXTRIES // UserUnknown = C.PAM_USER_UNKNOWN // CredErr = C.PAM_CRED_ERR // CredExpired = C.PAM_CRED_EXPIRED // CredUnavailable = C.PAM_CRED_UNAVAIL // AccountExpired = C.PAM_ACCT_EXPIRED // NewAuthTokenRequired = C.PAM_NEW_AUTHTOK_REQD // AuthTokenErr = C.PAM_AUTHTOK_ERR // AuthTokenRecoveryErr = C.PAM_AUTHTOK_RECOVERY_ERR // AuthTokenLockBusy = C.PAM_AUTHTOK_LOCK_BUSY // AuthTokenDisableAging = C.PAM_AUTHTOK_DISABLE_AGING // TryAgain = C.PAM_TRY_AGAIN // SessionErr = C.PAM_SESSION_ERR // ) type Error struct { Code int Msg string } func (err Error) Error() string { return fmt.Sprintf("pam error(%d): %s", err.Code, err.Msg) } type Transaction struct { ptr *C.pam_handle_t handlerId handlerId status C.int } func Start(service, user string, handler ConversationHandler) (*Transaction, error) { t := &Transaction{ handlerId: addHandler(handler), } service0 := C.CString(service) var user0 *C.char if user != "" { user0 = C.CString(user) } var conv C.struct_pam_conv C.init_pam_conv(&conv, C.long(t.handlerId)) ret := C.pam_start(service0, user0, &conv, &t.ptr) // clean C.free(unsafe.Pointer(service0)) if user0 != nil { C.free(unsafe.Pointer(user0)) } err := t.toErr(ret) if err != nil { deleteHandler(t.handlerId) return nil, err } return t, nil } func StartFunc(service, user string, handler func(Style, string) (string, error)) (*Transaction, error) { return Start(service, user, ConversationFunc(handler)) } func (h *Transaction) End(lastStatus int) error { deleteHandler(h.handlerId) ret := C.pam_end(h.ptr, C.int(lastStatus)) return h.toErr(ret) } func (h *Transaction) LastStatus() int { return int(h.status) } func (h *Transaction) toErr(errNum C.int) error { if errNum == C.PAM_SUCCESS { return nil } msg := C.GoString(C.pam_strerror(h.ptr, errNum)) return Error{ Code: int(errNum), Msg: msg, } } // Item is a an PAM information type. type Item int // PAM Item types. const ( // Service is the name which identifies the PAM stack. Service Item = C.PAM_SERVICE // User identifies the username identity used by a service. User = C.PAM_USER // Tty is the terminal name. Tty = C.PAM_TTY // Rhost is the requesting host name. Rhost = C.PAM_RHOST // Authtok is the currently active authentication token. Authtok = C.PAM_AUTHTOK // Oldauthtok is the old authentication token. Oldauthtok = C.PAM_OLDAUTHTOK // Ruser is the requesting user name. Ruser = C.PAM_RUSER // UserPrompt is the string use to prompt for a username. UserPrompt = C.PAM_USER_PROMPT ) func (h *Transaction) SetItemStr(itemType Item, item string) error { item0 := unsafe.Pointer(C.CString(item)) ret := C.pam_set_item(h.ptr, C.int(itemType), item0) C.free(item0) return h.toErr(ret) } func (h *Transaction) GetItemStr(itemType Item) (string, error) { var item0 unsafe.Pointer ret := C.pam_get_item(h.ptr, C.int(itemType), &item0) err := h.toErr(ret) if err != nil { return "", err } item := C.GoString((*C.char)(item0)) return item, nil } // Flags are inputs to various PAM functions than be combined with a bitwise // or. Refer to the official PAM documentation for which flags are accepted // by which functions. type Flags int // PAM Flag types. const ( // Silent indicates that no messages should be emitted. Silent Flags = C.PAM_SILENT // DisallowNullAuthtok indicates that authorization should fail // if the user does not have a registered authentication token. DisallowNullAuthtok = C.PAM_DISALLOW_NULL_AUTHTOK // EstablishCred indicates that credentials should be established // for the user. EstablishCred = C.PAM_ESTABLISH_CRED // DeleteCred inidicates that credentials should be deleted. DeleteCred = C.PAM_DELETE_CRED // ReinitializeCred indicates that credentials should be fully // reinitialized. ReinitializeCred = C.PAM_REINITIALIZE_CRED // RefreshCred indicates that the lifetime of existing credentials // should be extended. RefreshCred = C.PAM_REFRESH_CRED // ChangeExpiredAuthtok indicates that the authentication token // should be changed if it has expired. ChangeExpiredAuthtok = C.PAM_CHANGE_EXPIRED_AUTHTOK ) func (h *Transaction) Authenticate(flags Flags) error { ret := C.pam_authenticate(h.ptr, C.int(flags)) h.status = ret return h.toErr(ret) } func (h *Transaction) SetCredentials(flags Flags) error { ret := C.pam_setcred(h.ptr, C.int(flags)) h.status = ret return h.toErr(ret) } func (h *Transaction) AccountValidManagement(flags Flags) error { ret := C.pam_acct_mgmt(h.ptr, C.int(flags)) h.status = ret return h.toErr(ret) } func (h *Transaction) ChangeAuthToken(flags Flags) error { ret := C.pam_chauthtok(h.ptr, C.int(flags)) h.status = ret return h.toErr(ret) } func (h *Transaction) OpenSession(flags Flags) error { ret := C.pam_open_session(h.ptr, C.int(flags)) h.status = ret return h.toErr(ret) } func (h *Transaction) CloseSession(flags Flags) error { ret := C.pam_close_session(h.ptr, C.int(flags)) h.status = ret return h.toErr(ret) } func (h *Transaction) PutEnv(name, value string) error { env := C.CString(name + "=" + value) ret := C.pam_putenv(h.ptr, env) C.free(unsafe.Pointer(env)) h.status = ret return h.toErr(ret) } func (h *Transaction) DeleteEnv(name string) error { name0 := C.CString(name) ret := C.pam_putenv(h.ptr, name0) C.free(unsafe.Pointer(name0)) h.status = ret return h.toErr(ret) } func (h *Transaction) GetEnv(name string) string { name0 := C.CString(name) ret := C.pam_getenv(h.ptr, name0) C.free(unsafe.Pointer(name0)) return C.GoString(ret) } func next(p **C.char) **C.char { return (**C.char)(unsafe.Pointer(uintptr(unsafe.Pointer(p)) + unsafe.Sizeof(p))) } // GetEnvList returns a copy of the PAM environment as a map. func (h *Transaction) GetEnvList() map[string]string { envMap := make(map[string]string) p := C.pam_getenvlist(h.ptr) if p == nil { return nil } for q := p; *q != nil; q = next(q) { chunks := strings.SplitN(C.GoString(*q), "=", 2) if len(chunks) == 2 { envMap[chunks[0]] = chunks[1] } C.free(unsafe.Pointer(*q)) } C.free(unsafe.Pointer(p)) return envMap } // cbPAMConv is a wrapper for the conversation callback function. //export cbPAMConv func cbPAMConv(style C.int, msg *C.char, id C.long, resp **C.char) C.int { var r string var err error handler := getHandler(handlerId(id)) r, err = handler.RespondPAM(Style(style), C.GoString(msg)) if err != nil { return C.PAM_CONV_ERR } *resp = C.CString(r) return C.PAM_SUCCESS } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pam/transaction.c��������������������������������������������������������������������000664 �000000 �000000 �00000002030 13753517240 016272� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "_cgo_export.h" #include <security/pam_appl.h> #include <string.h> int cb_pam_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { *resp = calloc(num_msg, sizeof **resp); if (num_msg <= 0 || num_msg > PAM_MAX_NUM_MSG) { return PAM_CONV_ERR; } if (!*resp) { return PAM_BUF_ERR; } char *resp_str = NULL; for (size_t i = 0; i < num_msg; ++i) { int result = cbPAMConv(msg[i]->msg_style, (char *)msg[i]->msg, (long)appdata_ptr, &resp_str); if (result != PAM_SUCCESS) { goto error; } (*resp)[i].resp = resp_str; (*resp)[i].resp_retcode = 0; } return PAM_SUCCESS; error: for (size_t i = 0; i < num_msg; ++i) { if ((*resp)[i].resp) { memset((*resp)[i].resp, 0, strlen((*resp)[i].resp)); free((*resp)[i].resp); } } memset(*resp, 0, num_msg * sizeof *resp); free(*resp); *resp = NULL; return PAM_CONV_ERR; } void init_pam_conv(struct pam_conv *conv, long c) { conv->conv = cb_pam_conv; conv->appdata_ptr = (void *)c; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pinyin/������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014337� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pinyin/datas.go����������������������������������������������������������������������000664 �000000 �000000 �00001235563 13753517240 016001� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pinyin var PinyinDataMap = map[string]string{ "50CA": "xian", "5EBA": "song", "5EEB": "liao", "718C": "kao", "5130": "wei", "5E0F": "wei", "697C": "lou", "6B5F": "yu", "6E47": "qi", "75C3": "xuan;xian", "79A4": "xuan", "8EF2": "gu", "90F2": "lai", "56A2": "nang", "6A48": "rao;nao", "74B1": "se", "7634": "zhang", "7A64": "nuo", "7D00": "ji", "671D": "chao;zhao", "7C5B": "jian", "8027": "lou", "9460": "shuo", "6B9A": "dan", "6E0B": "se", "6FB0": "lian", "704B": "fa", "732C": "wei", "7530": "tian", "7C9A": "li", "84D9": "none", "9376": "si", "9AFE": "shao", "5A45": "ju", "640D": "sun", "734C": "man", "7833": "le", "5A1A": "nan", "7260": "ta", "7C8C": "yin", "80FD": "neng", "83B5": "tu", "8790": "wu", "98DB": "fei", "6926": "none", "8463": "dong", "8DA4": "dang", "9CC4": "e", "5F42": "fa", "60C9": "chan", "6EBF": "pan", "70BA": "wei", "8C79": "bao", "95FA": "gui", "5C06": "jiang;qiang", "6207": "zhuang", "8270": "jian", "8A68": "jiao", "93FF": "cheng", "97C2": "chan", "4F7B": "tiao", "5C05": "ke", "64DE": "sou", "934F": "wei", "9828": "pian", "9A4C": "su", "9B8C": "gun", "9D75": "tu", "56D9": "yin", "68C8": "qian", "86B7": "ju", "963E": "ling", "97DF": "gao", "988E": "jiong", "5282": "jue", "59B6": "xuan", "5B0A": "yan", "7603": "zhu", "7D77": "zhi", "8066": "cong", "9F4F": "ji", "4F84": "zhi", "52AE": "yi", "5E96": "pao", "67A4": "none", "7CCB": "jian", "7D73": "jiang", "818D": "pi", "84A5": "liu", "86A7": "jie", "9DF5": "tu", "6898": "jian", "6D3E": "pai", "74BD": "xi", "7999": "none", "95C0": "xiang", "9831": "le", "9908": "ci", "990C": "er", "561A": "de;dei", "99AA": "bin", "4F56": "bi", "6936": "zong", "797E": "ling", "86FA": "jia", "8F59": "yi", "9C60": "kuai", "589E": "zeng", "65CC": "jing", "65F5": "chan", "75FA": "bi", "7BC4": "fan", "85ED": "qiong", "871A": "fei", "9EB3": "lai", "64C4": "lu", "6D9E": "lai", "7146": "ya", "80D6": "pang", "9496": "yang", "9F89": "yu", "750B": "di", "858F": "yi", "6306": "duo", "69B7": "que", "7169": "fan", "7D5A": "geng", "6442": "she", "6E77": "chui", "7666": "none", "7EF8": "chou", "80C7": "fei", "982A": "lei", "9A41": "ao", "6FBD": "ju", "8AEA": "ting", "9275": "tong", "60D0": "yu", "67AE": "xian", "77DD": "lin", "5301": "none", "5CF8": "cheng", "90C9": "xing", "9C28": "ta", "632A": "nuo", "648E": "yi", "7CEF": "nuo", "7FC5": "chi", "843B": "an", "85FA": "lin", "8E6B": "ju", "9821": "jie;xie", "9C14": "jian", "52A5": "keng", "5F4D": "kuo", "4E64": "none", "730C": "yin", "9EFE": "min;mian", "6425": "chui", "682A": "zhu", "6A9D": "ji", "76B1": "zhou", "786E": "que", "8366": "luo", "9CFF": "yu", "553B": "lai", "572D": "gui", "5F7F": "fu", "6E7F": "shi", "729F": "jiang", "942D": "yu", "97D8": "she", "6B04": "lan", "888E": "yao", "50D7": "lao", "6506": "nian", "69F3": "jiang", "7367": "juan", "82ED": "yao", "9A00": "e", "6934": "duan", "8922": "huai", "8A53": "qu", "9039": "da", "94BB": "zuan", "8960": "dang", "8A64": "huang", "8A9C": "shua", "90FE": "yan", "6620": "ying", "7C60": "long", "4ED8": "fu", "59D1": "gu", "62A4": "hu", "746F": "lang", "7FA0": "yi", "85BE": "er", "8974": "lan", "8B22": "hu", "8EF8": "zhou;zhu", "9BF1": "none", "5683": "ta", "6250": "le", "6712": "nu", "86E6": "yi", "9456": "mie", "9611": "lan", "9E55": "hu", "6A1C": "shu", "6A63": "ning", "6F0F": "lou", "733E": "hua", "7981": "jin", "800A": "die", "89D6": "jue", "8C23": "yao", "9957": "xiang", "9B58": "yan", "7DBC": "bei", "8709": "fu", "56FB": "guo", "615B": "cui", "8F5C": "er", "5F76": "ji", "6CC3": "ju", "6D3D": "qia;xia", "6D68": "lan", "7591": "yi", "4E6D": "shi", "86F1": "jia", "8B3B": "yi", "9D89": "chun", "52AC": "qu", "589D": "qiao", "596B": "yun", "6271": "xi", "8299": "fu", "8759": "bian", "9D52": "yu", "5184": "ran", "536B": "wei", "8DB8": "dun", "97D7": "xun", "5B7A": "ru", "6864": "qi", "6C84": "yun", "6F8E": "peng", "70F4": "jing;ting", "83FB": "lin", "9578": "chang;zhang", "9DB5": "chu", "5037": "nai", "5EA6": "du;duo", "6A47": "qiao;cui", "99F4": "xie", "54B1": "zan", "559B": "huan", "5FE7": "you", "9B51": "chi", "5404": "ge", "5503": "gu", "67F1": "zhu", "6C2B": "qing", "6EC1": "chu", "78FA": "huang", "790A": "huo", "8F33": "cou", "91D5": "liao", "518F": "jiong", "5EBD": "yu", "643D": "cha", "6922": "kui", "6B28": "xu", "7D1F": "jin", "8121": "ting", "887D": "ren", "94A5": "yao;yue", "5C21": "none", "6B2D": "yi", "7BDF": "qian", "88D1": "shen", "89B2": "jin", "8ED8": "tun", "9AC8": "bang", "53A3": "yan", "88EA": "tao", "930F": "ya", "9387": "mei", "984F": "yan", "9986": "guan", "9F4A": "qi;zhai", "8AC1": "chuo", "8ECC": "gui", "9A5D": "tuo", "9B08": "quan;qian", "71CD": "si", "850B": "di", "8E1D": "huai", "950C": "xin", "96CC": "ci", "4E4B": "zhi", "8210": "shi", "8400": "hu", "5685": "ru", "627E": "zhao", "713F": "none", "75DD": "mang", "85B4": "neng", "8E0E": "none", "98BD": "kai", "4E07": "wan;mo", "7FC8": "xia", "8ED0": "xin", "62AD": "yao", "8016": "chao", "9666": "zhi", "9867": "gu", "5F6C": "bin", "7179": "wei", "7FE0": "cui", "80CE": "tai", "8143": "juan", "875F": "wei", "9228": "none", "6A76": "ji", "8011": "zhuan;duan", "8B61": "dang", "9627": "dou", "9A42": "can", "4E10": "gai", "5191": "zhou", "5DC9": "chan", "7AC1": "cui", "8384": "geng", "86B6": "han", "927B": "ge", "9CE1": "gan", "9F0E": "ding", "4F00": "zhong", "6877": "jue", "71A0": "yi", "824E": "huang", "50FC": "feng", "5147": "xiong", "7FB8": "lei", "9B37": "zong", "6288": "yue", "938E": "xi", "9C6E": "xu", "6788": "bi", "70D3": "wei", "8184": "shou", "59AE": "ni", "6228": "ge", "6A87": "zui", "8C3D": "han", "91F1": "di", "5070": "xie", "73C1": "ci", "8815": "ru;ruan", "9288": "ji", "940C": "xiang", "4FFA": "an", "5D70": "qian", "662A": "bian", "8B23": "yu", "94B9": "bo", "568B": "chou", "60ED": "can", "780D": "kan", "8B16": "su", "9213": "ren", "9849": "qin", "4E62": "gai", "785D": "xiao", "8F3F": "yu", "9DD2": "zhuan", "58DB": "yan", "59B1": "zhao", "78AD": "dang", "84AF": "kuai", "8872": "na", "9497": "chai", "9594": "min", "9822": "gua", "5422": "qin", "568E": "hao", "5C52": "chen", "869B": "zhong", "5785": "long", "5314": "qiong", "5327": "qie", "5707": "lun", "85F4": "yun", "95F7": "men", "5343": "qian", "7A71": "jue", "840E": "wei", "8F77": "hu", "9678": "lu;liu", "9702": "mu", "983B": "pin", "52B8": "wa", "63AA": "cuo", "65AA": "qu;ju", "796E": "gao", "834A": "jing", "8DF7": "qiao", "52C9": "mian", "707B": "chi", "7392": "hong", "7A3E": "gao", "7F7A": "chao", "8BCA": "zhen", "6210": "cheng", "7D53": "gua", "8329": "gou", "6457": "none", "67B7": "jia", "6A5F": "ji", "6F4C": "zhi", "7C4C": "chou", "8CEA": "zhi", "8FF4": "hui", "59C1": "xu", "5A31": "yu", "64B3": "qin", "6BD3": "yu", "76C0": "qi", "792A": "li", "7BCC": "hou", "84C7": "gu", "8554": "bao", "8D39": "fei", "8F10": "huan", "71D6": "xun", "71E1": "yi", "786F": "yan", "80BE": "shen", "5452": "m", "607B": "ce", "631E": "ta", "812C": "pao", "9B6F": "lu", "5F75": "tuo", "61A4": "fen", "7476": "yao", "77EE": "ai", "7E60": "rui", "9181": "lu", "93F6": "ji", "9DC6": "tian", "5BC9": "he", "9E0D": "mi", "6525": "zuan", "804B": "long", "9419": "deng", "7375": "lie", "8BF6": "ei;ai", "9ADC": "qiao", "5DEF": "qiu", "5F3B": "bi", "7138": "yan", "91FC": "jian", "9DEC": "huang", "57B3": "none", "5BD5": "ning", "66E8": "long", "778A": "dang", "7B34": "ge", "83EF": "hua", "86E8": "mo", "51E3": "fan", "907B": "wu", "9109": "xiang", "9E46": "yu", "94B8": "bu", "5F62": "xing", "8B2F": "zha", "9B7D": "han", "566E": "yuan", "679F": "yun", "7259": "ya", "79E5": "nian", "8CBC": "tie", "9C4F": "xun", "4F04": "diao", "54D6": "none", "6667": "hao", "743A": "fa", "7704": "mian", "8020": "huo", "9120": "hu", "97EA": "wei", "5D25": "pi", "6177": "kang", "6DA7": "jian", "708B": "pi", "804C": "zhi", "873C": "wei", "8B1B": "jiang", "9E92": "qi", "6A6D": "gu;ku", "90C3": "he", "732A": "zhu", "75C8": "yong", "7886": "bo", "7E61": "xiu", "8B8D": "e", "55EA": "qin", "5EE7": "qiang", "6244": "shang", "86C0": "zhu", "89E8": "huan", "8C12": "ye", "635F": "sun", "7D28": "fu", "9423": "none", "9DD4": "ao", "508C": "ma", "5D38": "dun", "6ED5": "teng", "9385": "jie", "4F64": "wa", "63C9": "rou", "7C67": "qu", "8295": "sui", "82C0": "hang", "8D46": "jin", "9100": "ruo", "9A54": "tan", "9D8B": "ju", "514D": "mian;wen", "4EDA": "xian", "5AB5": "ying", "7CC6": "mian", "89B9": "wei", "9567": "lan", "99E0": "liu", "6AA1": "zhe", "7ECE": "yi", "8DBC": "jian", "9811": "wan", "705C": "none", "7170": "gao", "9787": "yin", "502D": "wo", "5627": "mi", "6B97": "ye", "6FCD": "song", "7338": "mei", "74A7": "bi", "7756": "ling", "7056": "mi", "70DD": "zheng", "788B": "he", "85BC": "chen", "85D3": "xian;li", "897F": "xi", "8CF0": "shun", "95D8": "dou", "51F2": "gan", "5953": "she", "5F13": "gong", "7894": "wu", "7E5A": "liao", "8838": "quan", "4E11": "chou", "5281": "qiao", "7CD0": "fu", "7F29": "suo", "83B9": "ying", "96EC": "fou", "58D0": "mi", "6756": "zhang", "7C25": "qiao", "8B18": "chi", "5DBF": "none", "6AC9": "chu", "6F09": "lu", "70CF": "wu", "7ACA": "qie", "7C3E": "lian", "81CA": "sao", "90E7": "yun", "978A": "ji", "570A": "qing", "5BDD": "qin", "7903": "zhang", "7EE6": "tao", "98E9": "tun", "58C2": "dian", "72A1": "li", "7678": "gui", "7773": "hui", "82F9": "ping", "91B9": "ru", "5EEA": "lin", "648A": "xian", "7238": "ba", "7EA1": "yu", "93DC": "tang", "54DA": "duo", "5916": "wai", "6191": "ping", "7212": "liao", "75BF": "fei", "7C38": "bo", "54E5": "ge", "7649": "dan", "7FB1": "yuan", "912E": "mao", "95D4": "he", "9F3C": "yao", "5BF7": "feng", "5D39": "ti", "9531": "zi", "9835": "jun", "9940": "tao", "5FB3": "de", "812E": "nei", "828D": "shao", "8527": "hui", "8787": "xi", "8CD5": "qiu", "9B34": "fu", "5341": "shi", "8DBD": "fang", "972F": "deng", "4EF4": "wan", "596E": "fen", "5A2B": "yan", "6417": "dao", "747C": "zhuan", "77DE": "yu", "7AE0": "zhang", "7E09": "jin", "8132": "niao", "9246": "zhan", "5695": "lu", "5772": "fo", "6275": "yu", "7D84": "wan", "9E91": "ni", "5330": "dan", "56D1": "zhu", "7A4A": "ji", "8478": "xi", "89EB": "su", "98CD": "biao", "7B3E": "bian", "9B8A": "ba", "88B0": "none", "8E66": "beng", "8E6D": "ceng", "63F4": "yuan", "7624": "liu", "7D0F": "tou", "944A": "huo", "543F": "gao;gu", "795B": "qu", "8D9F": "tang", "92A1": "ji", "57ED": "dai", "7B70": "zuo", "8A83": "chi", "8E15": "jie", "522C": "chan", "5DE1": "xun", "6C44": "ze", "6D4B": "ce", "7008": "hui", "73FB": "mei", "943B": "ju", "4F03": "yu", "588A": "dian", "6A2A": "heng", "7018": "lu", "735A": "huang", "76CB": "bo", "7EEA": "xu", "9A4A": "hua", "9B2D": "dou", "522F": "gen", "5EA7": "zuo", "63CD": "zou", "8388": "mo", "534C": "xi", "5F25": "mi", "78D8": "qing", "7AE4": "hong", "8B63": "qian", "6683": "none", "6B3D": "qin", "7FBE": "gong", "583E": "chuan", "592B": "fu", "6DCA": "han", "6E5C": "shi", "4E39": "dan", "7B8F": "zheng", "8313": "xue", "848A": "none", "8D6C": "cheng", "92CD": "bo", "9591": "xian", "9868": "xun", "989B": "zhuan", "5382": "chang", "6446": "bai", "6478": "mo", "7EC0": "gan", "932E": "gu", "9C09": "huang", "53C2": "can;cen;shen", "6725": "none", "5EDD": "si", "6274": "jia", "66BB": "jing", "7B85": "bi", "8851": "ling", "9C51": "huang", "6AEA": "li", "6F3E": "yang", "7D9E": "duo", "96A0": "yin", "9758": "qing", "5141": "yun", "5CDB": "li", "65A0": "jiao", "66B2": "zhang", "79F4": "he", "8B4F": "ji", "59CF": "qian", "653D": "ban", "6984": "lan", "95C8": "wei", "7077": "zhuan", "71B9": "xi", "7739": "zhen", "8E0A": "yong", "91AA": "lao", "9311": "lei", "9486": "ga", "61AB": "min", "7CEA": "bo", "885B": "wei", "886B": "shan", "5AC4": "yuan", "610B": "xuan", "68C9": "mian", "7134": "yu", "722B": "lan", "7714": "da", "8E89": "dun", "5B1A": "lian", "62D8": "ju", "8832": "juan", "9175": "jiao;xiao", "6916": "peng", "8069": "kui", "821B": "chuan", "836A": "sun", "88F1": "biao", "8F60": "lei", "8FE0": "che", "971A": "wu", "9D47": "none", "6DAD": "shou", "79CA": "nian", "5607": "san", "9865": "hao", "6542": "kou", "69EE": "sen", "7A87": "bao", "7FC2": "fen", "4FC2": "xi", "57DC": "ye", "8BB7": "ne", "6C77": "zhong", "6C8F": "qi", "744E": "xie", "8256": "cha", "5FB5": "zhi;zheng", "81D2": "huo", "8B56": "jian;zen", "9590": "san", "9D9B": "jie", "9E30": "ling", "9ECC": "hong", "5347": "sheng", "5E93": "ku", "64F1": "ge", "6C3F": "gui", "7CE0": "kang", "8819": "bin", "6571": "ai", "6CCA": "bo;po", "8F62": "li", "9D00": "fou", "9D72": "que;qiao", "6A6A": "ran", "7263": "ren", "7E03": "xu", "59C8": "ling", "62D3": "tuo;ta", "6668": "chen", "8D3B": "yi", "594D": "none", "75ED": "peng", "7F0C": "si", "8863": "yi", "57A6": "ken", "5C9A": "lan", "6115": "e", "7C15": "le", "5274": "kai", "5E46": "yi", "7518": "gan", "9D8D": "none", "9E1D": "li", "687C": "qi", "7CC8": "xu", "7DCA": "jin", "57E0": "bu", "6508": "jun", "65A9": "zhan", "66E5": "lu", "7DD0": "fan", "88D9": "qun", "8FBC": "none", "9282": "zhou", "50F0": "bo", "51CD": "dong", "5B20": "can", "5EF7": "ting", "6305": "duo", "55EB": "nie", "60A5": "yi", "6655": "yun", "739A": "yang;chang", "7754": "hun", "787D": "yan", "7A28": "bian", "7CE3": "san", "96F5": "yang", "9BD3": "ni", "9EF9": "zhi", "5033": "zi", "539E": "fei", "5562": "liang", "662E": "zong", "6ED2": "ge", "7750": "lai", "833D": "zhong", "8818": "jie", "9C19": "ruo", "5097": "chu", "7A0B": "cheng", "59E7": "jian", "643C": "quan", "7775": "none", "7800": "dang", "9A29": "kui", "6CA2": "ze", "8D49": "lai", "9E7D": "yan", "5083": "su", "55C8": "yong", "6174": "zhe", "6A49": "lin", "75E0": "suan", "87BC": "qin", "8E2A": "zong", "52AB": "jie", "66EC": "shai", "7FA1": "xian", "5160": "dou", "56FD": "guo", "5924": "yin", "68F5": "ke", "6FC1": "zhuo", "8197": "chuai", "8659": "fu", "8CF3": "zai", "9C36": "ji", "9D67": "bing", "5CBD": "dong", "703F": "fan", "52B7": "yang", "81DC": "za", "9044": "chuan", "9412": "lao", "6902": "lu", "6EED": "bi", "7CAA": "fen", "7D41": "shi", "85C2": "cong", "9195": "chun", "972C": "yi", "6664": "wu", "67D9": "xia", "69FB": "gui", "6EFA": "you", "912F": "shan", "94F0": "jiao", "501F": "jie", "8C40": "xi", "501E": "jing;liang", "5073": "duan", "765D": "lin", "9A86": "luo", "51D4": "cang", "8B6E": "hua", "9F95": "kan", "570B": "guo", "5C0A": "zun", "7717": "ju", "920C": "jue", "9A83": "yin", "70C7": "quan", "8092": "huan", "8FC9": "qi", "5CE2": "li", "6085": "yue", "7D4C": "jing", "8078": "dan", "9077": "qian", "93B2": "tang", "4FE0": "xia", "5C4E": "shi", "6E07": "ke", "77E3": "yi", "7ADC": "long", "82A6": "lu", "93C6": "guan", "668A": "fu", "6CB8": "fei", "74D8": "guan", "9563": "liao", "6533": "xin", "6B0A": "quan", "71B4": "none", "8FA3": "la", "714D": "jiao", "8FF0": "shu", "9F2D": "shi", "53B5": "yuan", "6155": "mu", "9E89": "jian;qian", "614B": "tai", "67FB": "cha;zha", "7127": "cong", "9BEC": "li", "5CE4": "jiao;qiao", "7C94": "ju", "83A4": "you", "6015": "pa", "7DA7": "zhun", "4FA1": "jia;jie", "5448": "cheng", "5965": "ao", "6245": "yi", "63D8": "heng", "649B": "lin", "797D": "zui", "4FD3": "jing", "54AB": "zhi", "66D0": "xing", "7036": "lin", "787E": "zhui", "7957": "zhi", "7F13": "huan", "4E05": "xia", "5044": "nuan", "568F": "ti", "5918": "mao", "5F31": "ruo", "64B8": "lu", "9034": "chuo", "6194": "qiao", "62F7": "kao", "640B": "chuai", "73EF": "none", "7747": "di", "9900": "hai", "57F7": "zhi", "5A2E": "yan", "62AB": "pi", "8ACD": "zheng", "95AF": "sha", "98DC": "fan", "58A6": "fan", "64E1": "tai", "6F00": "qing", "781A": "yan", "863E": "huai", "8CF5": "feng", "9191": "xu", "9699": "xi", "51BA": "min", "7786": "kui", "7829": "fu;fei", "7B43": "yin", "8200": "yao", "95BD": "hun", "9879": "xiang", "54F9": "fou", "6B03": "chan", "743F": "hun;hui", "9422": "none", "976C": "jian", "7E20": "hu", "91A9": "zao", "516F": "none", "51DB": "lin", "64AF": "zhuo", "689B": "nuo", "6A6B": "heng", "7012": "se", "79DE": "you", "9869": "qian", "9F42": "xi", "9F5D": "chi", "9F68": "jiu", "63BC": "guan", "6FF0": "wei", "7011": "pu;bao", "87CD": "li", "987C": "xu", "54B9": "e", "6E0C": "lu", "6E2A": "ru", "736E": "xian", "77F7": "zi", "8E29": "cai", "98A6": "pin", "9C8C": "ba;bo", "63B4": "guai;guo", "6965": "xuan", "7253": "bang", "8775": "qiu", "8FAC": "ban", "920E": "gou", "5391": "none", "844E": "lu", "8782": "lang", "9B23": "lie", "61AC": "jing", "6A85": "sui", "6F4A": "xu", "9698": "ai", "5178": "dian", "6606": "kun", "9539": "qiao", "6B24": "yu", "8F1A": "zhan", "9BD9": "chun", "6429": "jie", "7396": "jiu", "7DFD": "cheng", "830D": "gou", "93C5": "xiu", "4ECC": "bing", "58AA": "dun", "636A": "min", "7871": "kun", "7B52": "tong", "878C": "ban", "5A59": "jing", "6E90": "yuan", "82F7": "gan", "9D4F": "bu", "4EAB": "xiang", "5791": "chi", "740A": "ya;ye", "79BD": "qin", "86A8": "fu", "5C00": "po", "5EFC": "nai", "6435": "wen", "6DAB": "guan", "6E2E": "ge", "7EAC": "wei", "89BF": "di", "92D7": "xuan", "94F4": "tang", "9657": "qiao", "5028": "ju", "62F9": "xie", "6ED8": "jiao", "8B81": "zhe", "5704": "yu", "5A68": "lun", "6BD7": "pi", "7925": "xian", "7DDE": "duan", "8007": "gou", "85E1": "di", "8F96": "xia", "921D": "yin", "4FE1": "xin;shen", "5F9C": "chang", "6BD5": "bi", "6D61": "bo", "931F": "tan", "971E": "xia", "8114": "luan", "85C5": "fa", "53D0": "ba", "53D1": "fa", "5B3F": "yan", "5E81": "ting", "5FC2": "qu", "64F7": "xie", "6E32": "xuan", "710F": "qi", "7AC2": "piao", "9305": "li", "99EE": "bo", "70D4": "tong", "770B": "kan", "95E9": "shuan", "5C65": "lu", "62C1": "jia", "6611": "qin", "6729": "deng", "673E": "ting", "6A34": "zhi", "6BAE": "lian", "7214": "xi", "7F9E": "xiu", "8D97": "cu", "916F": "zhi", "52C6": "lang", "5833": "mei", "5E51": "hui", "63FD": "lan", "85CF": "zang;cang", "91A3": "tang", "8827": "du", "8D62": "ying", "533F": "ni", "58E2": "li", "5925": "huo", "67AC": "nan", "8356": "lao;pei", "9118": "yong", "593E": "jia", "6DC3": "juan", "71B1": "re", "88A9": "chan", "90E4": "xi", "9C27": "teng", "4F32": "ni", "74FB": "chi", "874E": "xie;he", "98B0": "fa", "5801": "ke", "5904": "chu", "6344": "jiu", "66FB": "sheng", "6765": "lai", "7FA6": "huan", "9F45": "xiu", "535D": "kuang", "6D92": "tun", "713B": "chang", "92A8": "an", "97D4": "chang", "5AA3": "ran", "5B21": "ai", "620C": "xu;qu", "665C": "kun", "6C36": "zheng", "72B7": "guang", "88F0": "duo", "8AF8": "zhu", "925C": "fu", "970F": "fei", "4E1D": "si", "5859": "qiao", "6142": "yong", "72C9": "pi", "7866": "long", "9677": "xian", "5940": "en;mang", "75E9": "shou", "79AE": "li", "8582": "xi", "97A8": "he", "4FF2": "xiao", "549A": "dong", "68AB": "cen", "78AB": "duan", "95A3": "ge", "624A": "yan", "82B3": "fang", "8A06": "jiao", "9394": "rong", "9F52": "chi", "61F6": "lan", "68AC": "ying", "6C24": "yin", "8835": "xi", "52B0": "mo", "589C": "zhui", "8E63": "man;pan", "8ED1": "di", "7E9D": "lei", "99BC": "wen", "5966": "wu", "6005": "chang", "6B98": "can", "77C6": "huo", "867C": "ge", "57EB": "zhong", "966F": "lun", "9C9B": "jiao", "9FA2": "he", "8B79": "hao", "8E80": "kuang", "9A9B": "wu", "4F50": "zuo", "7B65": "ju", "93F4": "lu", "4F28": "xun", "6656": "hui", "8A48": "li", "8B2C": "miu", "90D7": "xi", "9AF4": "fu;fo", "60DC": "xi", "654D": "xu", "67FF": "shi", "6DB3": "kong", "80B6": "pi", "91E7": "chuan", "9F34": "yan", "73FE": "xian", "8383": "xi", "9144": "huan", "4F3A": "si;ci", "55B1": "li", "6F67": "zhen", "7AFE": "chi", "7CDB": "tang", "7E1E": "gao", "87C3": "wan", "5350": "wan", "703A": "chan", "83BC": "chun", "8F6D": "e", "8FC2": "yu", "9872": "lan", "5DF4": "ba", "62C3": "zha", "78FD": "qiao", "9232": "gu", "93B8": "juan", "5E30": "gui", "75AF": "feng", "7852": "xi", "7F99": "gao", "8B03": "none", "94C9": "xuan", "98F9": "liu", "5EF1": "yong", "8480": "yun", "88BA": "jie", "9BDC": "qie", "9C5F": "hou", "60D8": "wang", "78AE": "ti", "97CD": "fu", "9C61": "zei", "57C7": "yong", "634B": "lu;luo", "7574": "chou", "7605": "dan", "87C2": "jiao", "90B1": "qiu", "6D51": "hun", "7744": "shao", "7BF9": "cuan", "8B36": "zhuo", "6563": "san", "9EC7": "tian", "532A": "fei", "83E4": "juan", "8AF1": "hui", "92DA": "tiao", "943F": "yi", "94EE": "zheng", "5EFA": "jian", "6846": "kuang", "7715": "zhen", "7C7D": "zi", "8AD3": "jian", "8EF4": "zhu", "50D6": "xi", "5AFA": "xian", "60AD": "qian", "6DBB": "gan", "7677": "none", "7DC4": "gun", "8ACB": "qing", "8CFB": "fu", "56DC": "nin", "87EB": "yin", "9C5E": "guan", "5497": "zuo", "61BA": "dan", "6D27": "wei", "7113": "han", "8246": "lang", "835A": "jia", "92E2": "none", "58E4": "rang", "7158": "chan", "71C0": "chan", "7250": "tou", "8396": "jing", "916D": "you", "9995": "nang", "9AD3": "sui", "9B94": "ju", "5244": "jing", "6F97": "jian", "7B78": "gan", "963B": "zu", "9D13": "mie", "6A94": "dang", "9163": "han", "9948": "xiu", "645A": "cheng", "64B4": "dun", "6AD5": "cuan", "7C22": "min", "7F16": "bian", "9F92": "long", "5302": "none", "6E25": "wo", "70BC": "lian", "4FAB": "ning", "6297": "kang", "720E": "none", "7519": "dai", "8FFB": "yi", "90B7": "wa", "9560": "liu", "4E5F": "ye", "83D5": "lun", "5289": "liu", "575A": "jian", "5A25": "e", "62AA": "pu", "74F4": "ling", "7DB6": "guo", "838E": "sha;suo", "899A": "jue;jiao", "900F": "tou", "5EE3": "guang", "6C62": "none", "7B9C": "kong", "7CA9": "none", "93DA": "qi", "9773": "jin", "7D39": "shao", "9DAE": "ge", "9F1E": "tang", "4F34": "ban", "56E9": "yun", "63FF": "qin", "6970": "yu", "6A7C": "yuan", "6E91": "suo", "7D6D": "quan", "80B5": "jin", "8A10": "jie", "5E9E": "pang", "7A48": "men", "95F1": "wei", "759C": "xia", "81BC": "gua", "851A": "yu;wei", "5D83": "zhan", "6BF6": "none", "6E89": "gai", "76A8": "xing", "9A24": "kui", "688B": "xuan", "79DA": "ban", "8B41": "hua", "8FF6": "you", "5679": "dang", "750A": "lou", "87EF": "rao;nao", "8C1E": "xu", "55FD": "sou", "748F": "wei", "84D2": "xian", "53DE": "yu", "55AA": "sang", "67B1": "tai", "816F": "tu", "4F9E": "ru", "50DD": "chan", "52F8": "quan", "5356": "mai", "5CE8": "e", "5CF7": "shen", "6140": "xie", "6A3C": "zhen", "724B": "jian", "83B8": "you", "59BD": "shen", "6EA5": "pu", "8AE5": "zhong", "9086": "deng", "99F1": "luo", "5688": "yan", "5E62": "chuang;zhuang", "6038": "xi", "7642": "liao", "768A": "ling", "8DAD": "yao", "9E37": "zhi", "501C": "ti", "595B": "huang", "6560": "duo", "69BA": "sheng", "6DC8": "gu", "7EF3": "sheng", "930B": "peng", "7D4F": "xie", "7DAF": "tao", "86B4": "you", "86BE": "bo", "91E6": "kou", "5F4B": "hong", "654C": "di", "7114": "yan", "8C8E": "ni", "54EC": "he", "6FA2": "dang", "928C": "cun", "99F5": "liu", "6418": "zhi", "6EC7": "dian", "7078": "jiu", "70B5": "tong;dong", "7611": "gua", "7D60": "gai", "9202": "chen", "55DA": "wu", "673C": "bi", "6F79": "chan", "70D8": "hong", "8162": "ou", "8A32": "yi", "4E68": "shi", "5D40": "zhu", "6AF4": "lai", "6DF1": "shen", "78D0": "pan", "7B6D": "suan", "7EFD": "zhan", "8C93": "mao", "9814": "di", "9B28": "hong", "6071": "yue", "62F6": "zan", "7096": "dun", "7415": "bing", "7C32": "pai", "8C3A": "ya", "5B32": "niao", "68DB": "yu", "89D5": "cu", "656B": "jiao", "9C0E": "jian", "5CBB": "chi", "7C41": "lai", "9454": "cha", "94D5": "you", "51AD": "tai", "553F": "hu", "8A94": "ting", "9301": "guo", "98D6": "yao", "5478": "pei", "700A": "pan", "922F": "tu", "4E6A": "nang", "66DC": "yao;yue", "6D29": "xie", "7529": "shuai", "9B5A": "yu", "6158": "can", "735B": "bu", "7B9D": "qian", "7D42": "zhong", "9492": "fan", "611C": "qie", "7F05": "mian", "8CFF": "liao", "9D11": "nu", "9226": "tai", "52B5": "juan", "5A4A": "biao", "5CC6": "he", "7B57": "zhong", "86F9": "yong", "8A58": "chu;qu", "99CC": "yuan", "6866": "hua", "7105": "xun", "7140": "none", "866C": "qiu", "9E1B": "guan", "4E0D": "bu;fou", "5F37": "qiang;jiang", "6346": "kun", "6F78": "shan", "751D": "han", "9355": "rou", "653A": "gai", "6997": "jian", "756F": "jun", "7663": "xuan", "88D7": "liu", "8A77": "tong", "651C": "xie", "6A98": "bi", "7ADA": "zhu", "53A5": "jue", "5872": "chang", "6540": "bo", "6CC5": "qiu", "5B53": "jue", "5EF2": "li", "68B6": "wei", "6F8D": "shu", "811C": "you", "8A2B": "xin", "8AF3": "an", "588B": "chen", "5D2A": "zu", "627C": "e", "734A": "chuang", "76F5": "qi", "7F0A": "yun", "7FD4": "xiang", "8ECD": "jun", "7136": "ran", "76AC": "he", "8547": "dian", "9609": "yan", "5822": "bao", "59CD": "shan", "6FBC": "pi", "7B55": "hang", "5C14": "er", "6F55": "wu", "7D37": "ling", "56D8": "hui", "7319": "zheng", "8F57": "kan", "913D": "chan", "59C4": "ni", "6D62": "dou", "6DE3": "ni", "7DA8": "qi", "841F": "none", "9691": "gai", "97F8": "peng", "520F": "ji", "775D": "li", "8660": "jiao", "7A86": "bian", "9D3D": "ru", "5E47": "bang", "95A5": "fa", "99E6": "teng", "9BF3": "none", "5597": "yun", "71A8": "yun", "786D": "mang", "94AD": "tou", "95D3": "kai", "9ED2": "hei", "50B5": "zhai", "5979": "ta", "75CA": "quan", "7DCC": "rui", "8860": "zhun", "8C07": "sui", "9CA7": "gun", "5F99": "xi", "64EE": "ji", "5131": "long", "6998": "ju", "7802": "sha", "8B39": "jin", "5E1C": "zhi", "5FF1": "chen", "70A0": "xia", "851D": "mi", "88A7": "kou", "5B05": "hua", "9162": "zuo;cu", "9381": "ye", "958A": "none", "9C77": "e", "59FD": "gui", "610A": "bi", "834E": "chi", "61C9": "ying", "6316": "wa", "6C7C": "none", "8F0B": "ju", "9866": "qiao", "5042": "qian", "5864": "xun;xuan", "5B0E": "fan", "6A99": "ding", "8A3B": "zhu", "94A3": "ban", "9C15": "ha;xia", "508A": "yun", "66B4": "bao;pu", "675A": "gu", "7597": "liao", "7A68": "tui", "85C8": "kui", "5E65": "none", "8DF6": "da", "5813": "an", "5E66": "mi", "66AA": "men", "6AAD": "yin", "8265": "jie", "9767": "hui", "9DB3": "shi", "56C0": "zhuan", "638F": "tao", "6AF9": "xiao", "94BD": "tan", "6489": "dun", "9D2A": "yu", "5296": "chan", "5441": "jun", "5DA9": "nao", "62F1": "gong", "699A": "yao", "7B32": "fan", "7BBD": "dong", "80E2": "ke", "94C5": "qian;yan", "9564": "pu", "9D9D": "fu", "4E33": "chan", "5AE1": "di", "73F4": "e", "8F0A": "zhi", "938B": "xia", "9398": "ge", "5B81": "ning", "626E": "ban", "6974": "di", "6A3A": "hua", "8A90": "e", "8E5E": "kui", "959D": "ling", "975C": "jing", "6659": "jun", "6DEA": "lun", "6FD1": "lai", "50B3": "chuan;zhuan", "6954": "xie", "75AA": "bi", "8B6B": "zhan", "8FC7": "guo", "9E78": "jian", "5285": "zhuo", "5962": "she", "6688": "yun", "6BA6": "diao", "7FC9": "pen", "95E5": "ta", "9D17": "li", "6F1A": "ou", "88E0": "qun", "95EB": "yan", "502F": "song", "7BA3": "ce", "8885": "niao", "5540": "ai", "55F5": "tong", "5CCC": "die", "5FFA": "xian", "6BE6": "er", "8386": "pu", "83FD": "shu", "96B3": "hui", "9A11": "fei", "9CB4": "gu", "6B4C": "ge", "6FD4": "mi", "86D8": "yang", "9575": "chan", "9891": "pin", "4F15": "fu", "7C6B": "zuan", "7C77": "zhe", "96FB": "dian", "50D2": "jiong", "530B": "tao", "9A82": "ma", "5574": "tan;chan", "5C50": "ji", "610C": "huan", "7305": "han", "9A3E": "luo", "9D15": "tuo", "7EDD": "jue", "8B91": "yao", "9DA8": "dun", "9ED9": "mo", "6B0C": "none", "71AD": "wei", "8259": "cang", "6E0D": "zi", "6E35": "mao", "78D5": "ke", "8546": "chan", "9135": "cao", "56AD": "pi", "58EB": "shi", "5692": "none", "87EA": "hui", "69FD": "cao", "7D43": "xian", "81C5": "chu", "8C5B": "yi", "59D7": "shan", "5C3A": "chi;che", "61CF": "jun", "7B4D": "sun", "84B4": "shuo", "5FDA": "xi", "64E9": "ru", "65FF": "wu", "9544": "fei", "9B85": "bi", "4EA9": "mu", "56E1": "nan", "63FE": "wen", "8041": "none", "9C3B": "man", "7899": "gang", "7E78": "sui", "8B01": "ye", "8CD4": "bin", "5263": "jian", "560A": "none", "5C0C": "shu", "63EA": "jiu", "81F3": "zhi", "50A6": "none", "51B2": "chong", "5CBA": "ling", "6D53": "nong", "7293": "chu", "7AC5": "qiao", "818C": "ji", "840D": "ping", "84F0": "xi", "89EF": "zhi", "8BC2": "gu", "4FF7": "fei", "7DFB": "zhi", "803C": "dan", "93EF": "none", "5492": "zhou", "54A1": "er", "88E5": "jian", "9071": "lou", "92F7": "zui", "9854": "yan", "9B93": "zha", "9F59": "bao", "614C": "huang", "643F": "ge", "6DCD": "zhou", "83F1": "ling", "8F3A": "zi", "9685": "yu", "528A": "gui", "5A82": "ti", "5B47": "shuang", "5BFE": "dui", "6963": "mei", "6B9D": "none", "7CC2": "san;shen", "7D8C": "xi", "9B46": "xu", "5A83": "rou", "5B25": "tiao", "7AE7": "jing", "9722": "mo", "5522": "suo", "7DCD": "min", "5752": "bi", "6A04": "chen", "6A4D": "run", "774E": "xi", "787A": "zhuo", "84D3": "bei", "8C91": "jia", "92F1": "te", "5648": "cu", "8573": "jian", "6492": "sa", "72E6": "shan", "843F": "huo", "86C2": "bie", "8ADD": "xu", "842D": "yu", "8BBE": "she", "5DC5": "dian", "641B": "jian", "82EC": "qiu", "8946": "pu", "8E09": "liang", "9844": "han", "9C90": "tai", "54F4": "liang", "81D9": "yan", "8FB8": "reng", "5F3F": "jian", "6599": "liao", "6ABA": "gao", "71A9": "hu", "79A3": "none", "7A54": "huang", "8526": "niao", "864D": "hu", "8B15": "si", "59C3": "zheng", "6648": "jiao", "79D2": "miao", "9B64": "e", "53AA": "qin;jin", "8430": "lian", "8F31": "xian", "568D": "jin", "66D2": "jiao", "6C7D": "qi", "6ECC": "di", "8EB0": "ti", "8F6B": "ren", "79BB": "li", "8AE6": "di", "8CE8": "cong", "9AE1": "kun", "5080": "kui;gui", "5DF6": "zhao", "6604": "ban", "6BFE": "ta", "73B7": "dian", "8F40": "wen", "92B8": "zhe", "54DE": "mou", "5DE7": "qiao", "64FA": "bai", "75C2": "jia", "77F4": "ding", "7B7E": "qian", "8606": "lu", "94CC": "ni", "6422": "jin", "6CFC": "po", "702E": "none", "79BC": "xie", "83CF": "he", "855E": "zui", "5053": "wo", "526E": "gua", "576F": "pi", "676F": "bei", "7ECD": "shao", "8505": "yan", "96AA": "xian", "5D09": "ta", "82AE": "rui", "86E0": "li", "8DFB": "ji", "9DDB": "rong", "53F2": "shi", "8071": "ao", "972A": "yin", "9D9F": "tu", "5059": "di", "5C3D": "jin", "6C47": "hui", "8AB2": "ke", "9AD0": "nao", "521E": "qu", "6603": "ze", "8370": "du", "86A2": "hang", "8A02": "ding", "9A33": "du", "5BD9": "yu", "77FE": "fan", "8009": "gou", "8A27": "you", "9970": "shi", "4F06": "wen", "6A7D": "ta", "7071": "xiao", "99C5": "yi", "9A37": "sao", "9C3E": "biao", "9E82": "ji", "551C": "none", "57E3": "sui", "8160": "cou", "8B87": "chan", "909A": "ru", "90C2": "gai", "90CB": "xi", "96B0": "xi", "9B29": "xi", "5B4F": "lan", "67D4": "rou", "941A": "lou;lue", "96ED": "se", "9DC8": "ti", "54FD": "geng", "551B": "ma", "5865": "ge", "5884": "ce", "6337": "peng", "6821": "xiao;jiao", "7DA4": "shao", "85A5": "shu", "89C9": "jue;jiao", "8C7F": "gou", "998A": "sou", "9B68": "tun", "9E3F": "hong", "9274": "jian", "599C": "yue", "5AE0": "li", "7042": "zhuo", "7C61": "none", "85FC": "xuan", "8674": "zhe", "4E35": "zhuo", "6007": "ju", "65D7": "qi", "6A69": "qiong", "74A1": "jin", "8976": "dai", "8C36": "chen", "5212": "hua;huai", "8AF4": "xian", "8ED2": "xuan", "583A": "jie", "761E": "yi", "7A90": "gui", "55CA": "hong", "693A": "xi", "76DE": "zhan", "8171": "jian", "8E28": "zong", "974C": "bao", "6647": "xu;kua", "683B": "chi", "741E": "sheng", "7E49": "hun", "84B3": "na", "922E": "ni", "80CB": "tian", "6218": "zhan", "64D7": "pi", "7DB3": "beng", "7FCD": "pi;po", "878A": "lian", "9CD7": "man", "67B6": "jia", "827B": "le", "8DDA": "shan", "93D0": "liu", "95F3": "hong", "695A": "chu", "6EB5": "yin", "79B2": "li", "881B": "mie", "947A": "qu", "6169": "lian", "66E9": "nang", "9179": "lei", "97C0": "jian", "9BFD": "ji", "533D": "yan", "5E3A": "qi", "69F8": "yi", "8B59": "qiao", "6246": "yi", "76E8": "xu", "8584": "bo;bao", "9AB8": "hai", "5934": "tou", "7691": "ai", "89BE": "shen", "64E3": "dao", "6766": "shan", "7222": "mi", "77E4": "shen", "81D4": "xian", "99BD": "zhi", "5978": "jian", "7E97": "zui", "8F2A": "lun", "7B35": "fan", "845D": "jing", "9459": "ji", "945B": "kuang", "9BB0": "hui", "9BBB": "suo", "56BE": "huan", "5CA6": "li", "6501": "yang", "8E24": "zu", "96DC": "za", "5107": "xuan", "7686": "jie", "8173": "jiao", "9272": "ka", "9660": "pu", "7FBB": "qiang", "84E7": "diao", "9D69": "fu", "4F5F": "tong", "5133": "chan", "5354": "xie", "56CF": "jian", "5CE5": "zheng", "71F6": "none", "760A": "hou", "9DA7": "ying", "55EE": "sai", "561D": "hu", "6D2D": "kuang", "6F01": "yu", "7442": "mei", "78B0": "peng", "823D": "pang", "8F15": "qing", "9DF9": "ying", "527C": "shan", "56CB": "zan", "6700": "zui", "7A3F": "gao", "7A43": "none", "5F51": "ji", "71DA": "yi", "98F3": "zhu", "4FFE": "bi;bei", "5411": "xiang", "5604": "jiao", "5671": "xue;jue", "7CF1": "nie", "7EA7": "ji", "806F": "lian", "82C4": "bian", "8862": "qu", "9371": "ye", "98B7": "biao", "5134": "rang", "5D86": "cao", "6BAB": "dan", "6BF0": "pei", "8B94": "yin", "8C69": "bin", "99AF": "han", "5323": "xia", "554C": "xiang", "658D": "jue", "7040": "shuang", "862D": "lan", "95F8": "zha", "97F6": "shao", "5547": "di", "6C53": "qiu", "6EE3": "chun", "8FA6": "ban", "995D": "mo", "5195": "mian", "7421": "chu", "520C": "cun", "5349": "hui", "6A8D": "yi", "83BD": "mang", "87CA": "mao", "8B8A": "bian", "6AE3": "lian", "756B": "hua", "7CC7": "hou", "834F": "ren", "882B": "li", "8B12": "qiang", "8D28": "zhi", "92C2": "mei", "9DFB": "tuan", "5809": "yu", "5828": "e;ai", "5FB0": "zheng", "7CD5": "gao", "861D": "lian", "983A": "tui", "9C06": "chun", "5275": "chuang", "721C": "cong", "8A52": "yi", "8AC4": "zhun", "4E6C": "none", "5736": "qia", "5E33": "zhang", "7019": "qin", "7B5E": "ce", "87D3": "xiang", "8874": "dan", "954A": "nie", "584B": "ying", "6732": "ren", "5FF2": "tai", "6082": "mang", "7EEF": "fei", "86DD": "xian", "9147": "zan", "9C35": "min", "9F97": "ling", "509B": "yong", "51A0": "guan", "59DA": "yao", "5ACF": "lang", "6B95": "fou", "7351": "chan", "7A13": "zuo", "8852": "xuan", "8F44": "xia", "4F3C": "si;shi", "5EFD": "hui", "7F22": "yi", "85AA": "xin", "9444": "zhu", "4EC3": "ding", "7967": "tiao", "5046": "chun", "57FC": "qi", "6976": "jie", "765B": "lin", "8B45": "se", "8FC1": "qian", "60F3": "xiang", "6AFF": "ying", "718E": "yao", "7352": "ao", "789F": "die", "85C1": "gao", "918B": "cu", "927C": "bing", "8063": "none", "81A0": "jiao", "8984": "none", "8E11": "qi", "9B89": "diao", "609A": "song", "998B": "chan", "9EC6": "guang", "5055": "xie;jie", "58BA": "ao", "6030": "xuan", "611B": "ai", "937D": "bian", "6DB0": "chuo", "715E": "sha", "77F2": "bai;pai", "55B8": "none", "5B96": "hong", "6B10": "li", "869A": "qi", "92EB": "li", "948E": "qian", "5A7E": "tou", "6AFC": "jian", "6D43": "jia", "8409": "fei", "8DAF": "yue", "50B7": "shang", "5E82": "ze", "7FED": "hou", "58E5": "chan", "597D": "hao", "78FC": "za", "7F33": "huan", "88EF": "chou", "52F4": "lu", "7A9B": "kou", "7B1F": "gu", "7D1E": "dan", "872D": "han", "8CB0": "shi", "92E1": "han", "9988": "kui", "6E70": "long", "8AA8": "hui", "9159": "zhen", "95D6": "chuang", "51A3": "zui", "5818": "cheng", "8BC6": "shi;zhi", "9252": "zhu", "5142": "zan", "5603": "chong", "58BD": "qiao", "6661": "bu", "70AC": "ju", "7BAF": "bian", "8A1F": "song", "7749": "cuo", "7BE1": "cuan", "829D": "zhi", "532C": "yu", "5388": "an;chang", "65EB": "tiao", "66F9": "cao", "7E83": "qi", "9D16": "wen", "9E8F": "jun;qun", "65CF": "zu", "792C": "fan", "8CF4": "lai", "97F1": "xian", "5F8A": "huai;hui", "6EC9": "huang", "7EBC": "zhen", "7F5C": "zhu", "9ED4": "qian", "4FA2": "zai", "9349": "di", "99D2": "ju", "9A5F": "zou;zhou", "5BBD": "kuan", "71C3": "ran", "7DB5": "cai", "92BA": "zang", "9400": "kui", "53EF": "ke", "8C2E": "jian;zen", "9EBF": "none", "565D": "si", "6027": "xing", "681D": "gua;kuo", "685B": "none", "6F73": "tu", "7F79": "li", "8CF8": "sheng", "8F01": "qiong", "9996": "shou", "6113": "dang", "6A26": "zhu", "6E00": "ben", "9247": "ta;tuo", "58FD": "shou", "6B31": "xia", "70A3": "ke", "82F0": "hong", "8A4E": "ju", "8E71": "zhong", "9026": "li", "9779": "ren", "5100": "yi", "51DF": "du", "5926": "chen", "64A7": "jue", "9054": "da", "56B4": "yan", "587E": "shu", "5D41": "kan", "7AC6": "qiong", "7E74": "bo", "9F75": "yu", "579D": "gui", "66DE": "li", "6C2C": "ya", "7EAF": "chun", "8BB1": "ren", "5B97": "zong", "5DBE": "yin", "6E22": "feng", "7D66": "gei;ji", "8A13": "xun", "52DF": "mu", "5551": "jie", "7126": "jiao", "899E": "yao", "9F38": "xian", "5C0E": "dao", "5CF6": "dao", "6A64": "rui", "6F4B": "lian", "8302": "mao", "8F94": "pei", "98E5": "tuo", "9EDF": "yi", "9F91": "yan", "5FBE": "mei", "693F": "chun", "821E": "wu", "64EB": "ye", "6CD0": "le", "71F4": "hui", "7C07": "cu", "51D6": "zhun", "659E": "yu", "6C18": "dao", "615D": "ni;te", "62EB": "hen", "8B29": "mo", "920B": "e", "9533": "ying", "6748": "cha", "9A76": "shi", "9E2D": "ya", "515D": "fen", "5248": "yuan", "53B4": "yan", "6F26": "li", "720D": "shuo", "7B45": "xian", "8403": "cui", "8535": "cang;zang", "8828": "xiao", "9C29": "yao", "5D5A": "qin", "6A80": "tan", "845E": "mi", "95EA": "shan", "9D4E": "tuo", "563A": "qiao", "687A": "liu", "71BE": "chi", "7FA3": "qun", "897E": "ya", "903F": "dang", "4EDC": "hong", "5909": "bian", "7E15": "yun", "8FC4": "qi", "58C3": "jiang", "5E5C": "jiong", "64B2": "pu", "75E5": "duo", "7B9F": "jun", "8408": "huan", "92A3": "ru", "73F2": "hun;hui", "7F5E": "mao", "8D5A": "zhuan;zuan", "4EFE": "di", "5A5C": "qian", "62FA": "ce", "6CC8": "zhong", "8414": "tiao", "96BA": "he", "9D56": "bi", "5488": "fu", "60A0": "you", "6636": "chang", "7C63": "lan", "8BD1": "yi", "4FCD": "lang", "6E4D": "tuan", "855D": "jue", "977F": "yao", "6ACA": "none", "7EB1": "sha", "8699": "qian", "8EAF": "qu", "9717": "none", "5EA5": "xiu", "669B": "suo", "6A82": "nong", "6EDF": "yan", "6FD2": "bin", "8D80": "ci", "925E": "yue", "92B2": "han", "9D81": "jing", "571A": "hui", "5BD1": "qin", "5A11": "suo", "7D1C": "yun", "949C": "ju", "94C6": "mao", "9889": "jie;xie", "59C6": "mu", "681E": "kan", "78BB": "que", "99C1": "bo", "9ED6": "xi", "532B": "hu", "54AF": "ge;ka;lo;luo", "7E5B": "chuo", "8BF2": "hui", "7186": "he", "815D": "ruan", "872B": "kun", "518D": "zai", "5401": "yu;xu", "7157": "nuan", "7F9D": "di", "8E42": "rou", "98AF": "sa", "9D3E": "mou", "53D5": "zhui", "6759": "yi", "678A": "ang", "98AB": "fu", "581C": "lian", "59D4": "wei", "6348": "tu", "7190": "ming", "8DD4": "ju", "9A7C": "tuo", "6ECB": "zi", "73B4": "yi", "762E": "shen", "845A": "shen;ren", "8EC7": "dao", "93AF": "luo", "96C7": "gu", "9997": "kui", "9726": "bin", "4E31": "guan", "57D5": "cheng", "727C": "keng", "53EE": "ding", "579F": "yang", "616A": "ou", "74F1": "none", "7EF9": "tao", "8115": "wan", "8949": "jian", "7876": "chen", "7A3C": "jia", "7AE8": "diao", "8CD8": "zang", "9388": "cha", "985A": "dian", "519D": "yi", "5436": "na", "7941": "qi", "83EA": "dang", "9061": "su", "9731": "yu", "9892": "hui", "9E74": "shuang", "540F": "li", "68C2": "ling", "856E": "xi", "85EA": "sou", "90A8": "cun", "945D": "peng", "9BB7": "ti", "6208": "ge", "748D": "none", "75DE": "pi", "7A47": "shan", "833E": "none", "950D": "liu", "9EAF": "qu", "52ED": "tong", "53AC": "gui", "624B": "shou", "87E9": "jue", "50EF": "lin", "540A": "diao", "613C": "shen", "6805": "zha;shan", "698A": "none", "5E0A": "pa", "5DC2": "sui;xi", "6189": "peng", "6E80": "man", "88DE": "shui", "97C4": "huo", "5898": "qi", "66A7": "ai", "7B96": "lin", "85F5": "none", "514A": "dui", "5545": "zhuo", "656C": "jing", "6B27": "ou", "7D54": "bai", "8A9F": "xiao", "9216": "fen", "7C0C": "su", "9187": "chun", "7617": "yi", "8A8D": "ren", "5F58": "zhi", "6374": "zong", "81AB": "liao", "8572": "qi", "8701": "xuan", "9008": "jiong", "59F7": "you", "5D74": "ji", "5FDC": "ying", "683E": "luan", "701D": "li", "7C3C": "gou", "7EE1": "xiao", "8615": "none", "8B3E": "man", "70B9": "dian", "7107": "xiao", "7E80": "pu", "7F73": "si", "9DF4": "xian", "5C67": "xie", "5F1F": "di", "6C71": "quan", "6F5B": "qian", "74DE": "die", "9668": "yun", "99CE": "zhou", "4EE1": "ge;yi", "6167": "hui", "62E9": "ze;zhai", "699F": "zi", "6F42": "hong", "7507": "ying", "837E": "sui", "880C": "ze", "8F4D": "che;zhe", "9B77": "you", "58DD": "wei", "6AB8": "ning", "7EEC": "yin", "85C3": "xiao", "6DF9": "yan", "86F0": "zhe", "89E4": "gui", "5004": "yao", "53BC": "none", "53EA": "zhi", "5764": "kun", "5A1C": "na;nuo", "5BFA": "si", "650E": "lu", "781D": "fa", "8224": "none", "888A": "ling", "94E5": "diu", "99D9": "fu", "51AC": "dong", "71D1": "tong", "8D85": "chao", "4F37": "zhou", "6182": "you", "84B8": "zheng", "94D9": "nao", "9E8E": "chen", "6955": "tuo", "7453": "lian", "8722": "meng", "55C9": "su", "7B46": "bi", "7D23": "cui", "8503": "qiang", "539F": "yuan", "573C": "nie", "6950": "jie", "7575": "hua", "75C4": "zha", "8167": "shu", "8A88": "wu", "4EFF": "fang", "54BB": "xiu", "956D": "lei", "9EDA": "qian", "616B": "song", "7A36": "yu", "85C6": "jian", "8C3F": "qi;xi", "94D4": "ya", "5AC5": "cha", "5BA7": "yi", "6BD8": "pi", "7409": "liu", "839E": "guan;wan", "869D": "hao", "996E": "yin", "5638": "fu;m", "75A3": "you", "76F2": "mang", "8A72": "gai", "92E5": "zeng", "5CAF": "pei", "9D28": "ya", "9E96": "jing", "52E1": "piao", "5386": "li", "5E01": "bi", "7AD7": "miao", "85BD": "zhen", "8900": "ji", "9131": "po", "9829": "ping", "98B2": "lie", "5BBC": "kou", "5CD8": "hu", "5EC7": "liu", "680E": "li;yue", "94D1": "lao", "6654": "ye", "6817": "li", "6D5C": "bang", "7BA8": "tuo", "88D6": "chen", "51F7": "kuai", "5F09": "zang;zhuang", "6CD9": "ping", "732E": "xian", "7360": "liao", "4E8D": "chu", "5117": "ni", "5DCA": "ying", "67F6": "si", "6EB3": "yun", "93B1": "yuan", "981C": "he;han", "9852": "yong", "51E2": "fan", "5539": "yu", "617F": "ping", "82D8": "qing", "9489": "ding", "5D43": "yan", "6F8F": "han", "70B1": "tai", "7111": "none", "7490": "lu", "8C75": "zong", "8CA2": "gong", "5CEA": "yu", "69CD": "qiang", "6CF8": "lu", "7EE8": "ti;di", "855F": "fa", "998C": "ye", "5536": "jie", "7DC6": "yi", "9509": "cuo", "97FB": "yun", "9989": "gu", "7CFD": "zheng", "8E75": "zu", "954C": "juan", "5776": "mu", "8F0E": "shao", "952F": "ju", "598A": "ren", "5BC3": "yuan", "6FE5": "yin", "521B": "chuang", "78B2": "di", "89F2": "xing", "97D1": "wei", "9A6B": "biao", "4EEC": "men", "5440": "ya", "58F8": "kun", "7498": "lin", "8DC5": "tuo", "99DF": "si", "6AD6": "lu", "81E7": "zang", "97ED": "jiu", "5768": "tuo", "5B14": "fan", "5B7D": "nie", "5D84": "zhan", "7333": "jia", "7BBE": "shuo", "9242": "shi", "534E": "hua", "6800": "zhi", "7A30": "xu", "9BE0": "lai", "623D": "hu", "659D": "jia", "7C9B": "su", "52A9": "zhu", "5BFD": "lu;luo", "711A": "fen", "75B8": "dan", "6C3C": "ni", "7625": "chai;cuo", "7BAB": "xiao", "88D8": "qiu", "890E": "xiu", "9234": "ling", "9739": "pi", "92D9": "wu", "7313": "guo", "73BA": "xi", "5286": "lian", "537F": "qing", "59BF": "e", "6862": "zhen", "8A03": "fu", "8C11": "xue", "9BAB": "jiao", "5B1C": "none", "5B4B": "li", "5ED8": "lu", "809F": "wo", "959A": "none", "4E40": "fu", "5E08": "shi", "64F8": "lie", "67AB": "feng", "69A4": "jie", "722F": "zhao", "7859": "wei", "9B9C": "hou", "5CFC": "hao", "602C": "xi", "65D4": "jian", "6FF8": "none", "8CE7": "dan", "9B17": "man", "9C48": "xue", "75C7": "zheng", "81E4": "qian", "8743": "zhuo", "9436": "huan", "85D6": "xian", "8D59": "fu", "9206": "yan", "963D": "dian;yan", "623B": "li", "725A": "cheng", "9307": "pei", "50D4": "zun", "5317": "bei", "5A08": "luan", "5D4B": "mei", "5F73": "chi", "750E": "zhuan", "7A10": "lun", "8800": "zi", "8F21": "kan", "9231": "min", "9AF1": "pao", "5CCA": "fu", "5F11": "shi", "5F2B": "zhen", "6480": "gou", "6917": "ding", "905C": "xun", "9903": "jiao", "9D9C": "mao", "6A20": "men", "6E92": "yuan", "7A21": "zui", "859E": "sun", "8A2A": "fang", "6C7F": "xu", "8EDF": "ruan", "5BAF": "xiao", "7166": "xu", "55B2": "yo", "5891": "di", "67F7": "zhu", "9093": "deng", "519C": "nong", "6F5F": "xi", "7FD1": "qu", "872C": "gan", "59A7": "yuan", "6D8D": "xiao", "7075": "ling", "7711": "yao", "81C4": "jue", "92FD": "diao", "7173": "hu", "849C": "suan", "8FD5": "wu", "587C": "zhuan", "6E1D": "yu", "71D9": "tang", "7209": "lu", "740E": "jin", "8FC6": "yi", "9F5E": "nian", "54EB": "zu", "5D6B": "zi", "6263": "kou", "7BDA": "fei", "87B5": "piao", "517C": "jian", "56F4": "wei", "5A3F": "e", "5CE7": "jiao", "67C4": "bing", "6ACF": "qian", "722A": "zhua;zhao", "9C8D": "bao", "9E49": "wu", "670C": "ban", "8283": "peng", "84F7": "tui", "856A": "wu", "9735": "ji", "5C08": "zhuan", "63A3": "che", "9E05": "zhe", "4F76": "ji", "79E9": "zhi", "949F": "zhong", "61CC": "yi", "670D": "fu", "7CD6": "tang", "856F": "yong", "97B7": "ge", "99BB": "yin", "53D6": "qu", "6A12": "mi", "87D1": "zhang", "8BA9": "rang", "97C9": "jian", "9B53": "bi", "56CE": "none", "7BB9": "yue", "7DF7": "yun", "812A": "xin", "8BFD": "fei", "9198": "ke", "9340": "de", "97DD": "gou", "644F": "chong", "6908": "ju", "726B": "fa", "79F3": "huo", "832E": "jiao", "838A": "zhuang", "79CE": "fen", "8233": "zhu", "83AD": "jie", "540D": "ming", "58D8": "lei", "5DDB": "chuan", "7CBA": "bai", "8703": "shen", "8EBC": "none", "8EC8": "none", "934B": "guo", "546A": "zhou", "68DD": "gu", "96BB": "zhi", "97CB": "wei", "4E98": "gen", "5239": "cha;sha", "628E": "yun", "6C5B": "xun", "7819": "pan", "8514": "bo;bu", "8E94": "chan", "4F9D": "yi", "5E76": "bing", "61B0": "jue", "75B0": "zhu", "9224": "ri", "933C": "nai", "984E": "e", "5165": "ru", "541B": "jun", "58F0": "sheng", "9A05": "zhui", "9C94": "wei", "6128": "que", "6742": "za", "7C85": "wu", "8A0C": "hong", "918D": "ti", "5F53": "dang", "736A": "kuai", "8BD3": "kuang", "4E2C": "qiang;pan", "5ADF": "ni", "80E6": "yang", "92D2": "feng", "9EA0": "jing", "4F6C": "lao", "626D": "niu", "6AAB": "cha", "8402": "he", "5693": "ca;cha", "985E": "lei", "4F2F": "bo;bai", "5372": "shao", "5608": "cao", "7E6E": "jiang", "7F7C": "bi", "994C": "zhuan", "6981": "none", "78C2": "liu", "831E": "chen", "8867": "yu", "8C52": "zhi", "9715": "tun", "9759": "jing", "7363": "shou", "8241": "zao", "90B4": "bing", "91CC": "li", "7F5F": "gu", "819B": "tang", "828B": "yu", "57B1": "dang", "5FA2": "xie", "7BE5": "li", "78CA": "lei", "7FBF": "yi", "8181": "qian", "827D": "jiao", "96CB": "jun;juan", "9874": "quan", "64CF": "jing", "6C41": "zhi", "79FA": "du", "8574": "yun", "8621": "ying", "9025": "hui", "54D1": "ya", "5A8B": "chun", "5CD2": "tong;dong", "649C": "zheng", "690C": "qiang", "72A6": "bao", "7AD2": "qi;ji", "7C1D": "liao", "7E57": "lin", "8CAC": "ze;zhai", "8E04": "bo", "71EA": "cong", "6231": "xi", "666B": "zhuo", "6F8C": "si", "8BF9": "zou", "8D08": "zeng", "9C9C": "xian", "6E08": "ji", "8D44": "zi", "9ACC": "bin", "5784": "long", "5793": "gai", "6A3E": "yue", "7CFC": "gong", "8D72": "li", "9895": "ying", "9C5C": "xiang", "9DEE": "jiao", "6847": "ru", "6EEA": "yu", "6F4F": "yu", "87F3": "xun", "9B70": "wen", "9BDB": "diao", "60E7": "ju", "6372": "juan", "6441": "en", "7724": "yi", "8CB3": "er", "905E": "di", "9EF4": "mei", "6154": "mo", "6CE7": "yue", "8118": "wan", "92AF": "none", "98A1": "sang", "9917": "su", "5187": "mao;mou", "6088": "jie", "6FA9": "xue", "5E8F": "xu", "71A3": "sui", "7898": "dian", "7FD7": "qi", "823A": "jia;xia", "8449": "xie;ye;she", "9AF2": "pi", "6104": "wei", "717C": "chao", "8EBA": "tang", "9DFD": "xue", "594B": "fen", "5DE9": "gong", "6351": "she", "6D15": "yin", "53BF": "xian", "5A6E": "none", "63D3": "shi", "6CF1": "yang", "7855": "shuo", "9518": "nuo", "9968": "tun", "9D1D": "qu", "9F21": "shu", "6AAC": "meng", "96C6": "ji", "97CC": "ren", "5BDE": "mo", "5EEC": "lu", "6813": "shuan", "76E6": "an", "88BB": "er", "53D9": "xu", "5755": "jing", "5D27": "song", "63F3": "xie", "7F06": "lan", "9185": "pei", "9BB9": "shao", "56B6": "ying", "6726": "meng", "6C13": "mang;meng", "8868": "biao", "5127": "zan", "5BE5": "liao", "5D64": "rong", "6D6D": "geng", "657D": "jiao", "74DC": "gua", "7F87": "ji", "8592": "can", "9AE0": "kun", "9F9F": "gui;jun;qiu", "816C": "rou", "8E7A": "qiao", "9319": "zi", "94A2": "gang", "963F": "a;e", "97BF": "ji", "5DB8": "rong", "638E": "ji", "70F3": "pu", "99B2": "tuo", "9C52": "zun", "9E67": "zhe", "63A6": "ti", "663D": "long", "742A": "qi", "8416": "wan", "8B72": "rang", "8D6F": "tang", "99ED": "hai;xie", "9C84": "ke", "9CA5": "shi", "578E": "ke", "5A7A": "wu", "69FA": "kang", "7596": "jie", "8AB7": "wang", "54A7": "lie", "7639": "diao", "8CC4": "hui", "921B": "guo", "53C6": "ai", "5B52": "jue", "6534": "po", "6DDD": "fei", "7593": "nai", "54FA": "bu", "55BE": "ku", "65E9": "zao", "79ED": "zi", "934C": "xian", "9842": "lai", "9D0E": "ou", "5D30": "zi", "5FAE": "wei", "687F": "gan", "6FAB": "man", "7032": "lian", "8151": "fu", "85DB": "xie", "4FB4": "chou", "5428": "dun", "58DA": "lu", "68E4": "xi", "6D34": "ping", "7616": "yin", "7956": "zu", "8242": "feng", "830A": "zi", "8562": "kui", "67D8": "zhe", "7AFD": "yu", "8AD1": "zhuo", "4E90": "yu", "5512": "miu", "62AF": "zha", "7BBB": "fu", "8CC0": "he", "9126": "xu", "57C0": "chui", "73DD": "xu", "8040": "zhi", "8217": "pu", "8836": "can", "9A2A": "sou", "60D3": "quan", "7E45": "sao", "8285": "yi", "913F": "qi", "9C81": "lu", "5F02": "yi", "6524": "tan", "4FC9": "wu", "545B": "qiang", "546C": "ling", "54A5": "xi;die", "57D7": "bu", "58AC": "zui", "670A": "ruan", "73AF": "huan", "93DF": "chan", "57DF": "yu", "5BEE": "liao", "6029": "ni", "8FF1": "tuo", "9A5B": "yi", "5F6D": "peng", "6B47": "xie", "6D58": "wei", "71CC": "fen", "98F7": "jie", "9A5E": "bin", "9B2E": "jiu", "9F90": "pang", "8A31": "xu;hu", "9751": "qing", "6DC6": "xiao;yao", "6F9B": "lu", "74D0": "lu", "7673": "luo", "87FB": "yi", "6594": "yu", "69BD": "xi", "7A2B": "bi", "82EE": "xian", "8D69": "xi", "8E3A": "jian", "58F5": "zhuang", "6754": "zhe", "500A": "zong", "5B40": "shuang", "663F": "kuang", "8144": "chui;zhui", "8DED": "xiang", "973B": "none", "6014": "zheng", "6476": "tuan", "70CB": "xiao", "8BA2": "ding", "5C61": "lu", "8338": "rong", "598D": "yan", "9B5B": "dao", "5270": "sheng", "5D36": "feng", "6AFD": "yin", "8588": "hui", "8F74": "zhou", "9D8C": "qu", "4FCE": "zu", "6E5E": "zhen", "5ADC": "zhang", "5B9C": "yi", "65ED": "xu", "66B8": "liao", "66C6": "li", "7B12": "cen", "84C2": "ming", "8948": "zhuan", "9945": "man", "9FA1": "chui", "5096": "cang", "5283": "hua", "642A": "tang", "68F0": "chui", "735D": "yu", "9659": "chun", "9848": "jiong", "5AD6": "piao", "7651": "nong", "612B": "su", "9D98": "hu", "5449": "wu", "61F2": "cheng", "6D63": "huan;wan", "765A": "dan", "8376": "yin", "7BD3": "lou", "7D19": "zhi", "81BA": "ying", "82DB": "ke", "9876": "ding", "67AA": "qiang", "6B49": "qian", "6E64": "shi", "94CE": "duo", "9EF5": "dan", "9F56": "ya", "52EC": "juan", "5899": "qiang", "6324": "ji", "6BF7": "mao", "9182": "lan", "50A9": "nuo", "617E": "yu", "8AAF": "chang", "8FE7": "chen", "7F53": "wang", "927D": "shi", "938C": "lian", "9F2A": "sheng", "6670": "xi", "6B08": "wei", "7571": "liu", "75DF": "xiao", "8D63": "gan", "9CFD": "jian", "563E": "dan", "6D1A": "jiang", "8D24": "xian", "90F5": "you", "9EC5": "jin", "6AD9": "ou", "7FCA": "yi", "816B": "zhong", "5164": "kuang", "6012": "nu", "80D5": "fu", "861A": "xian;li", "8713": "ting", "8CD1": "zhen", "93A3": "ying", "9EA6": "mai", "57DA": "guo", "5D0B": "hua", "611A": "yu", "8561": "fen", "9C8F": "pi", "660B": "gui", "69D9": "dian", "7015": "bin;pin", "802F": "huo", "9083": "sui", "98DF": "shi;si;yi", "9AFC": "peng", "51A4": "yuan", "54C1": "pin", "586D": "wen", "6D7B": "weng", "7A9D": "wo", "96B4": "long", "6083": "kun", "6A92": "feng", "7C98": "zhan;nian", "9C2C": "qian", "9F16": "fen", "5C0F": "xiao", "5B0D": "mei", "6CA3": "feng", "849B": "que", "8612": "none", "6BCF": "mei", "6EF8": "hu;xu", "72D7": "gou", "85E7": "huan", "8667": "kui", "8903": "ken", "897C": "yi", "504C": "ruo", "5162": "jing", "5B88": "shou", "777A": "hou", "7E5C": "zun", "8939": "yi", "5FDF": "min", "6432": "wa", "6A44": "gan", "6E60": "tan", "72DF": "huan", "77A1": "ji", "7AB9": "wu", "5A4F": "fu", "5B04": "none", "5BDC": "ning", "6AAF": "tai", "80A6": "ban", "8622": "long", "8E55": "bi", "91A4": "jiang", "5022": "jie", "55A6": "nie", "9141": "chan", "9433": "lei", "7856": "xia", "79A2": "ta", "5B33": "none", "5E20": "yi", "60A7": "li", "612F": "song", "6637": "wen", "8A89": "yu", "8D94": "lie", "6CE2": "bo;po", "73F8": "wu", "8578": "xia", "906F": "dun", "9D97": "ti", "7164": "mei", "86B8": "li", "881D": "lei", "4EF8": "yao", "7204": "li", "7669": "lai", "84A6": "huo", "8C73": "bin", "9DDD": "bi", "4F66": "none", "61DD": "ai", "68E0": "tang", "7340": "sou", "74DA": "zan", "752D": "beng", "8C81": "you", "8DAB": "qiao", "9A21": "quan", "9D48": "none", "7425": "hu", "80C9": "bo", "5230": "dao", "5BA6": "huan", "72E5": "huan", "8C66": "qu", "9390": "zu", "62B8": "za", "9A6A": "li", "9B69": "mo", "4E00": "yi", "595A": "xi", "5F00": "kai", "5FDE": "min", "6153": "piao", "72DD": "xian", "59F1": "kua", "5A73": "hua", "674F": "xing", "7613": "huan", "84DA": "xiu", "95B1": "yue", "9974": "yi", "544B": "fu", "7C1E": "dan", "81D5": "biao", "5723": "sheng", "6292": "shu", "73C9": "min", "93C4": "tuan", "9A25": "rou", "9A2E": "liu", "5634": "zui", "575F": "fen", "5E21": "ping", "5E53": "sen", "61F1": "mie", "70A8": "duo", "7161": "xin", "7376": "nao", "8A3E": "zi", "7794": "ze", "7AA1": "zhui", "7D50": "jie", "97BB": "lou", "9A87": "hai", "4EDD": "tong", "5816": "nao", "66CE": "yi", "74DD": "bao", "82B4": "wu", "8F9D": "ci", "5B0B": "chan", "718B": "nai", "77C3": "ning", "8829": "zhu", "9CE9": "jiu", "9F05": "zhi", "5F43": "bi", "639B": "gua", "672B": "mo", "870D": "chu", "8AE7": "xie", "9149": "you", "9373": "jian", "97AA": "mu", "6315": "die", "650F": "long", "7FBC": "chan", "9430": "qiao", "6793": "dou", "6D0B": "yang", "7A00": "xi", "82BE": "fei;fu", "8BF7": "qing", "9022": "feng", "9ABA": "hou", "59B3": "nai;ni", "5AC3": "zhen", "772E": "tong", "7A4B": "lu", "973A": "wei", "604F": "hao", "6326": "xian", "7719": "yi", "52F0": "xie", "5E74": "nian", "9F53": "chen", "562B": "ran", "58E3": "lin", "84E5": "ying", "9AFF": "sha", "5514": "wu;n;ng", "60CF": "lin", "6392": "pai", "6A4F": "zhan", "6AF5": "none", "73E8": "xia", "9325": "yu", "9538": "cha", "6C86": "hang", "907A": "yi;wei", "7D16": "yin", "80B9": "xi", "7977": "dao", "7D21": "fang", "4F8A": "guang", "50D0": "shan", "53AD": "yan", "578D": "ji", "5948": "nai", "5FFD": "hu", "6CEF": "min", "752C": "yong", "76EF": "ding", "7E47": "zhou;yao;you", "555D": "he", "7C2F": "none", "7E10": "zhou", "956C": "huo", "7595": "bi", "772C": "long", "895D": "lian", "4E5B": "none", "5F81": "zheng", "610D": "min", "62B4": "yi", "6650": "gai", "7508": "qi", "7632": "zong", "541D": "lin", "7296": "luo", "8A11": "yi", "9DEB": "su", "727A": "xi", "741A": "ju", "7723": "die", "77E5": "zhi", "7E7A": "shai", "9217": "yun", "9C7C": "yu", "5A54": "none", "6A67": "zeng", "79EA": "zhi", "7B9A": "zha", "9F96": "ta", "800E": "ruan", "8845": "xin", "8AD5": "hao", "517F": "yi", "6B92": "yun", "6BCB": "wu", "7D24": "jiu", "896D": "xie", "5714": "e", "9C59": "miao", "506B": "zhi", "6D12": "sa", "935E": "keng", "97E4": "wa", "999F": "tu", "5457": "bei;bai", "5BD4": "shi", "62CE": "lin", "824D": "ju", "9377": "kui", "5B22": "niang", "74B2": "sui", "7782": "fa", "7BDC": "zheng", "544C": "jiao", "5730": "di;de", "6A13": "lou", "6E15": "yuan", "7F3B": "fou", "845C": "qia", "886F": "fen", "95F0": "run", "58D3": "ya", "5ACE": "pang", "7965": "xiang", "9082": "xie", "6061": "lin", "6138": "zheng", "6150": "none", "6679": "yi", "9CFE": "shi", "50E1": "hui", "59BC": "bi", "59E8": "yi", "6FC5": "jin", "7410": "suo", "7B97": "suan", "7BD4": "yun", "82E6": "ku", "8BAF": "xun", "8DEF": "lu", "9132": "dan", "9559": "luo", "9CA4": "li", "4E7D": "none", "558C": "zhou", "5DB1": "ke", "6332": "suo;sa;sha", "860C": "yu", "8B0B": "huo", "9E59": "qiu", "63F8": "zha", "69CA": "shuo", "853B": "kou", "55D9": "pang", "615F": "tong", "692E": "sen", "6BA2": "ti", "776A": "gao", "8453": "hong", "89A5": "tian", "73A9": "wan", "7B02": "none", "8975": "zhe", "63FB": "none", "4FC0": "tui", "5494": "ka", "607E": "mang", "8500": "bu", "8EF0": "bei", "8F69": "xuan", "9742": "li", "993D": "kui", "51EE": "feng", "6BD9": "bi", "7AF9": "zhu", "8450": "pen", "8DA2": "lu", "9D85": "zi", "9E5B": "mei", "5B18": "sui", "953B": "duan", "9CC7": "huang", "5049": "wei", "5565": "sha", "5883": "jing", "6052": "heng", "85B1": "dui", "555A": "bi", "75D5": "hen", "7C17": "liang", "7C5A": "lu", "95B4": "qu", "71B8": "jian", "8716": "hui", "500F": "shu", "5504": "bai;bei", "5664": "jin", "5C62": "lu", "7702": "shi", "8CE4": "jian", "4FAA": "chai", "50E7": "seng", "6FAD": "yong", "705B": "chan", "83AE": "nan", "85C0": "ying", "8980": "xi", "9EE8": "dang", "5C27": "yao", "65F6": "shi", "727D": "qian", "75D9": "jing", "7DF1": "gou", "96D3": "yu", "97FA": "ying", "4F0C": "ai", "51B9": "fu", "5DEA": "none", "649F": "jiao", "6702": "xu", "8169": "nan", "8170": "yao", "8BCE": "qu", "8DFC": "ju", "5596": "hu", "5819": "yin", "5C12": "er", "69BF": "qi", "7417": "cui", "760C": "la", "8C26": "qian", "8C29": "man", "8EEF": "peng", "91E4": "shan", "50C1": "xi", "5502": "gu", "566A": "zao", "712F": "zhuo;chao", "8314": "ying", "9292": "xing", "5611": "hu", "7123": "ju", "85A8": "hong", "8CD3": "bin", "95C6": "ban", "976B": "ren", "6C6C": "jing", "73B8": "fu", "7994": "ti", "81DD": "luo", "8B48": "dui", "9337": "ga", "571D": "luan", "6100": "qiao", "788A": "jian", "52D9": "wu", "68E2": "wang", "8672": "none", "8B06": "shan", "686B": "suo", "7110": "wu", "87BE": "yin", "8D92": "tiao", "8ECB": "ya;zha;ga", "97EF": "xian", "5B30": "ying", "5BE4": "wu", "5E45": "fu", "5EA2": "zhi", "652E": "nang", "7E02": "zong", "897D": "none", "50DB": "qi", "5400": "mie", "597B": "nan", "5A23": "di", "6186": "cheng", "638C": "zhang", "6B38": "e;ai", "7106": "jue", "7D3C": "fu", "852A": "jian", "62C8": "nian", "676C": "yuan", "83C4": "dong", "72EE": "shi", "8842": "nu", "8C32": "jue", "8EC0": "qu", "68FB": "fen", "77EC": "cuo", "8E72": "dun;cun", "984A": "yi", "69DF": "bin;bing", "8004": "mao", "957F": "zhang;chang", "57F2": "beng", "5B16": "bi", "5C79": "yi;ge", "627F": "cheng", "7E2B": "feng", "95A4": "he;ge", "642F": "tao", "7741": "zheng", "7A96": "jiao", "9277": "hong", "4E60": "xi", "58FE": "mang", "59DC": "jiang", "5E94": "ying", "777D": "kui", "99E4": "zhi", "8431": "xuan", "51D8": "si", "5808": "gang", "60CA": "jing", "64CC": "se", "6DE0": "pi", "7A14": "ren", "7AE6": "song", "9464": "bao", "56E2": "tuan", "8A6E": "quan", "965C": "shan", "61D2": "lan", "6468": "nai", "712E": "xin", "7BCA": "hong", "9176": "mei", "4FBC": "bo", "51CE": "gan", "556F": "guo", "5E18": "lian", "6C5A": "wu", "8128": "cu", "95C5": "wen", "5124": "bao", "59EA": "zhi", "694F": "kui", "770F": "yang", "7B2F": "nu", "82FE": "bi", "8EFF": "ping", "5968": "jiang", "5A69": "yan", "6369": "lie", "75BD": "ju", "8033": "er", "82AB": "yan;yuan", "5D63": "dang", "60BD": "qi", "62D7": "ao;niu;yao", "68B7": "jing", "6FDB": "meng", "7A5B": "zhuo", "8C37": "gu;yu", "5A0C": "li", "5AD8": "lei", "714E": "jian", "7806": "fu", "7DA3": "quan", "8168": "shuan", "825D": "none", "8D30": "er", "5D62": "cang", "68D3": "pou;bang", "72B5": "jie", "76E4": "pan", "87AF": "ao", "946A": "lu", "9D35": "jiao", "59EC": "ji", "7CC5": "rou", "8392": "ju", "9740": "meng", "7C90": "none", "5304": "gai", "8125": "xie", "9CB6": "nian", "5228": "bao;pao", "6814": "qi", "6A78": "none", "6B3C": "chi", "8018": "yun", "4FD7": "su", "5B2D": "nai", "5D0D": "lai", "61AA": "xian", "8B07": "jian", "9262": "bo", "6F28": "feng", "7627": "nue;yao", "8C58": "tun", "5379": "xu", "5D95": "jiao", "6733": "ba", "6769": "ma", "6900": "wan", "72B3": "chuo", "7B8C": "zhao", "7FDC": "se", "8429": "qiu", "8486": "qiong", "89FC": "jue", "90FC": "yi", "92D8": "wu", "9F8D": "long", "6919": "shan", "6C42": "qiu", "7906": "jian", "8EF7": "ba", "5C8E": "fen", "62C7": "mu", "9692": "yan", "5672": "kuai", "6CB2": "duo", "4E4F": "fa", "60E4": "jian", "676B": "si", "679D": "zhi;qi", "946B": "xin", "693E": "zhan", "7EDC": "luo;lao", "8B66": "jing", "528C": "gui", "556E": "nie", "7061": "lan", "7469": "ying", "7B0F": "hu", "8243": "li", "4F0F": "fu", "5C4D": "shi", "727F": "gu", "738A": "su", "7C58": "teng", "83DF": "tu", "9CD5": "xue", "573E": "ji", "9066": "guan", "5EE6": "bi", "7435": "pi", "5701": "yin", "5C84": "yue", "5E6E": "chu", "6F5C": "qian", "79FC": "zhu", "9D4C": "yu", "6172": "man", "640A": "chou", "71E4": "tai", "7D3B": "yang", "8F81": "quan", "9104": "juan", "9366": "she", "9EDE": "dian", "8509": "gun", "8CAE": "er", "4F8B": "li", "55BB": "yu", "624D": "cai", "8467": "bo", "8489": "kui", "5D91": "xiang", "8140": "lun", "9267": "mu", "5120": "lie", "66F1": "yue", "69AE": "rong", "71E3": "lan", "7354": "hao", "7CF5": "nie", "9914": "bu", "4EF1": "qian", "5B5A": "fu", "5804": "ni", "7B2C": "di", "853A": "lin", "874F": "ting", "62F0": "nin", "6574": "zheng", "70CA": "yang", "79FB": "yi", "76E3": "jian", "9D62": "shen", "5359": "ji", "76D8": "pan", "7BC8": "feng", "96F2": "yun", "4E23": "you", "59E3": "jiao", "8849": "mie", "90DA": "wu", "972E": "dan", "9926": "zhang", "9015": "jing", "52EB": "fan", "8BE3": "yi", "8DE6": "chu", "9A9F": "shan", "7D93": "jing", "9C75": "zhen", "50EC": "jiao", "73C0": "po", "8BEB": "jie", "91B5": "ju", "7514": "dan", "83DE": "li", "89E6": "chu", "972B": "xi", "53B9": "qiu", "7767": "hun", "7F42": "ying", "955D": "di", "9F6F": "ni", "9F78": "yi", "662C": "hun", "69BC": "ke", "7D05": "hong;gong", "8AED": "yu", "5800": "ku;jue", "59F9": "cha", "5FDB": "fan", "8EB2": "duo", "52C8": "yong", "5506": "suo", "5C8A": "jie", "5E95": "di;de", "8099": "yuan", "883C": "qu", "8B2B": "zhe", "9A15": "yao", "7E8C": "xu", "83E7": "di", "950A": "lue", "995E": "chan", "4FCB": "yi", "86AC": "xian", "917E": "shi;shai", "91A8": "li", "941B": "ying", "9929": "e", "9BF5": "sao", "5A3A": "zhui", "5E07": "nie", "6C9E": "za", "7588": "bo", "7B89": "guai", "7FEB": "wan", "8F53": "fan", "60F0": "duo", "62E0": "ju", "87D7": "qiu", "9A88": "pian", "9CD4": "biao", "5CEE": "qun", "63E9": "kai", "7A12": "gu", "8BBD": "feng", "9781": "bei;tuo", "78A1": "zhou", "7EBB": "zhu", "845F": "huang", "9E42": "li", "60C3": "kun", "8D5E": "zan", "60A8": "nin", "6839": "gen", "6889": "zhuang", "7287": "ben", "77A0": "cheng", "80A0": "chang", "9438": "duo", "5437": "chuo", "6BC0": "hui", "849A": "he", "943D": "da", "95E2": "pi;bi", "57FB": "zhun", "5FA8": "huang", "7081": "qi", "7F00": "zhui", "9078": "xuan", "55AD": "yan", "5AD5": "yi", "6411": "rong", "8920": "gou", "994B": "kui", "54BF": "yi", "6021": "yi", "6B5A": "none", "77D5": "man", "889B": "di", "95EC": "han", "7045": "lei", "7C78": "shen", "7D34": "bei", "848D": "wei", "869F": "wang", "56EC": "hui", "6043": "shi", "69B8": "zhai", "76E7": "lu", "8448": "xi", "8649": "yi", "8C20": "dang", "8DCA": "mei", "933D": "wan", "6467": "cui", "8A6C": "gou", "9EE5": "qing;jing", "52E7": "quan", "53E3": "kou", "6B15": "none", "8ED6": "qiang", "9670": "yin", "6168": "kai", "64FE": "rao", "66CA": "fei", "765E": "lai", "947E": "luan", "53CA": "ji", "613D": "bo", "621E": "jia", "6527": "dian", "69BB": "ta", "6B86": "dai", "7E64": "zuan", "93D1": "di", "9AE5": "ran", "50E3": "tie", "7108": "xi", "8348": "chuan", "8EF5": "rong;fu", "9EA3": "yan", "52DD": "sheng", "6217": "qiang", "65EC": "xun", "6D50": "chan", "708D": "pan", "779F": "piao", "8EBB": "none", "65E3": "ji", "6F83": "jiong", "8347": "xing", "9B0B": "jian", "52FE": "gou", "6256": "none", "628B": "qin", "657F": "qiao", "85DA": "xu", "8C49": "chi", "69E0": "zhu", "6AE1": "zhu", "6F99": "xi", "7960": "ci", "80B2": "yu;yo", "6DCF": "hao", "6EDD": "long;shuang", "74DF": "pao", "79AC": "hui", "8368": "qian;xun", "9977": "xiang", "5991": "pa", "6329": "tuo", "659F": "zhen", "9BC4": "qiu", "4F33": "xie", "589B": "none", "6BEA": "mu", "81D6": "xing", "978D": "an", "5903": "gu", "6160": "ao", "819F": "lu", "82EA": "bing", "865F": "hao", "64BD": "qiao", "680D": "none", "6F2F": "luo;ta", "6F77": "bi", "72AB": "chou", "7DA9": "wan", "8C96": "e", "4FCC": "fu", "51E1": "fan", "8637": "kui", "970E": "sha", "63F6": "ye", "72A2": "du", "7E24": "su", "81DA": "lu", "9446": "zhui", "978C": "an", "5B65": "nu", "8FAF": "bian", "9204": "tou", "9B84": "fu", "590F": "xia;jia", "5309": "peng", "53D3": "shi", "550C": "xian", "71DB": "jing", "73F6": "ti;di", "8ECE": "wei", "51C5": "gu", "5C3C": "ni", "7664": "jie", "7BB0": "sun", "7FFD": "hui", "8373": "dou", "9F61": "ling", "5B67": "none", "612E": "yao", "940E": "jiao", "5915": "xi", "8B49": "zheng", "5B37": "ma", "63CB": "wei", "64EF": "bin", "6500": "pan", "66D3": "bao", "6C37": "bing", "76EB": "an", "79E4": "cheng", "96FC": "dang", "988A": "jia", "5B01": "deng", "5EB9": "tuo", "645D": "lu", "6487": "pie", "68E5": "fan", "6EB2": "sou", "7A3D": "ji;qi", "811B": "jing", "89F1": "bi", "5967": "ao", "77FD": "xi", "8555": "you", "9BB2": "none", "5174": "xing", "51B8": "pan", "6C70": "tai", "71D0": "lin", "8044": "zhen", "91D8": "ding", "9D82": "ni", "6DF5": "yuan", "7148": "feng", "85D2": "qie", "9C30": "none", "5BE1": "gua", "8D66": "she", "5FCC": "ji", "6300": "bo", "692C": "none", "6F90": "yun", "7541": "qi", "771E": "zhen", "810D": "kuai", "523E": "ci", "6B21": "ci", "9364": "cha", "937B": "jie", "4F59": "yu;tu", "5DAA": "ye", "6321": "dang", "77D7": "chu", "80B4": "yao", "8BA7": "hong", "548E": "jiu", "57B8": "huan;yuan", "588C": "zhi", "6B32": "yu", "6E10": "jian", "818E": "xie", "8DF0": "beng", "540E": "hou", "6370": "wo", "6AF1": "nie", "7E4F": "xuan", "8BFC": "zhuo", "8D3D": "zhi", "8D86": "di", "5434": "wu", "6B96": "zhi;shi", "78E6": "biao", "9215": "niu", "9741": "lei", "97E3": "shu", "9C92": "jie", "6D7F": "pei", "721F": "guan", "9AC1": "ke", "549B": "ning", "55FF": "tan", "6C3E": "fan", "72EF": "kuai", "981F": "e", "9EFD": "min;mian", "9934": "fen", "6156": "guo", "632E": "ti", "7159": "yan", "7A38": "xu", "8B58": "shi;zhi", "8E73": "bo", "9A48": "yu", "4F53": "ti;ben", "5D24": "yao;xiao", "677B": "chou;niu", "8150": "fu", "8196": "pang", "89CB": "xi", "98A9": "biao", "9BC0": "gun", "512D": "chen", "60EA": "de", "6697": "an", "547B": "shen", "5D23": "wei", "61D9": "yu", "719C": "cong", "75E8": "lao", "8104": "mei", "84F4": "chun", "8CC6": "pian", "882E": "ye", "8F4F": "zhan", "9771": "ren", "51AE": "gang", "557D": "an", "6F2A": "yi", "872A": "tao", "9404": "huang", "9637": "cheng", "5A4C": "shu", "7AFA": "zhu", "82A1": "qian", "9963": "shi;si", "559C": "xi", "6FF5": "bin", "5A63": "yin", "6205": "gang", "6212": "jie", "7DD7": "xiang", "857D": "deng", "9B2B": "kan", "9C80": "tun", "4F7D": "ci", "6E65": "tu", "7A1A": "zhi", "7F67": "lin;sen", "97BE": "xue", "6063": "zi", "92B9": "xiu", "9EE2": "qu", "5013": "tan", "55F0": "ge", "61B8": "xian", "5614": "ou", "5DDC": "gui", "69B6": "tang", "7332": "xie;he", "7970": "gao", "7BC6": "zhuan", "7F75": "ma", "8D7B": "xian", "9465": "lu", "9DE8": "hua", "5799": "guang", "61B9": "nao", "6C27": "yang", "9E90": "lin", "61FD": "huan", "6899": "huan", "7EA2": "hong;gong", "8905": "ti", "92F4": "none", "7778": "mei", "97F2": "ji", "56AC": "pin", "5D4E": "yu", "5F69": "cai", "86D1": "mou", "87FF": "qi", "93A1": "zi", "93E2": "biao", "9429": "sui", "5CCF": "er", "62D2": "ju", "6DDE": "song", "7E1A": "tao", "9052": "qiu", "6095": "xi", "71D8": "mei", "8393": "mei", "6665": "han", "6A58": "ju", "7289": "run", "908F": "luo", "9397": "qiang", "9747": "long", "5F4E": "wan", "6016": "bu", "6779": "hua", "6FE7": "dui", "7F5A": "fa", "8301": "zhuo", "9C8A": "zha", "9CB0": "zou", "6660": "sheng", "785F": "chan", "9B63": "yu", "5143": "yuan", "53F7": "hao", "5413": "he;xia", "71E2": "xue", "7CCD": "ci", "8CE2": "xian", "91F3": "xi", "9F9E": "bie", "5432": "yin", "7160": "ye", "806D": "kui", "8670": "ding", "8D1B": "gan", "8E52": "pan", "53A9": "jiu", "6238": "hu", "637B": "nian", "63B5": "none", "7655": "yong", "94F6": "yin", "8F6F": "ruan", "943E": "bei", "5726": "none", "63CF": "miao", "67FA": "guai", "6DC9": "guo", "7290": "ke", "7585": "jiang", "77B3": "tong", "8116": "bo", "9D73": "jian", "6E01": "yuan", "7CC1": "san;shen", "81EC": "nie", "86C7": "she;yi", "8726": "lun", "8D04": "zhi", "8E46": "tui", "90CD": "nuo", "92B0": "ai", "56B1": "xi", "6299": "pou", "641D": "qiu", "66BC": "pie", "6D71": "chun", "73E5": "er", "7900": "jian", "8FD8": "hai;huan", "9589": "bi", "9A0F": "qi", "51B5": "kuang", "5406": "yao", "80D2": "ni", "8EA4": "jie", "92AA": "you", "9766": "tian;mian", "9F9D": "qiu", "5BEF": "jun", "6B1B": "ba", "8BDE": "dan", "98D8": "piao", "81A4": "xue", "89B7": "qu", "8AFB": "heng", "8E74": "cu", "6D10": "xing", "795E": "shen", "7C43": "lan", "80BC": "jing", "8303": "fan", "9608": "yu", "9ED8": "mo", "59F8": "yan", "5EA8": "xiao", "606C": "tian", "8B4A": "nao", "7F80": "liu", "854E": "qiao", "8AD0": "qian", "8D07": "yun", "92AD": "qian", "5A84": "mei", "63F1": "shuo", "68C6": "lun", "6A9F": "jia", "6CA0": "liu", "6E87": "lou", "7095": "kang", "59A2": "fen", "6552": "shen", "6904": "jie", "6BE1": "zhan", "7023": "xie", "9EEC": "an", "6D73": "yi", "7401": "xuan", "8D75": "zhao", "9245": "ju", "9EAA": "mian", "5213": "wan", "523A": "ci", "6171": "tuan", "8DE7": "quan", "8E56": "chong", "98F1": "sun", "69AF": "shi", "6FE8": "ci", "94E3": "xian", "5C4C": "diao", "635E": "lao", "684F": "qiong", "7F6A": "zui", "83C8": "la", "98ED": "chi", "9B78": "none", "5017": "peng", "51C4": "qi", "7A19": "zhi", "83FF": "dao", "8C16": "xuan", "8E92": "li", "5954": "ben", "5F18": "hong", "6B64": "ci", "7116": "men", "4F35": "xu", "6516": "ying", "8362": "none", "8EBF": "kang", "80CD": "gua", "637D": "zu", "7ABF": "long", "911B": "chao", "9CDA": "wei", "53E9": "kou", "6067": "nu", "60AB": "que", "6388": "shou", "72DE": "ning", "9663": "zhen", "9674": "pi", "9D9A": "e", "55D2": "da;ta", "567A": "none", "5E7E": "ji", "74CF": "long", "7654": "yi", "7817": "che", "85D0": "miao", "95D2": "da;ta", "53F0": "tai", "5C45": "ju;ji", "6687": "xia", "6E24": "bo", "74B8": "bin", "9936": "gu", "6E88": "gui", "78F3": "zeng", "8914": "fu", "8AD8": "biao", "901C": "wu", "945F": "du", "67BF": "nie", "8915": "yu", "53A2": "xiang", "5866": "zhen", "5F20": "zhang", "762C": "zhang", "84BB": "ruo", "649D": "hui", "64D1": "jie", "73CD": "zhen", "7752": "shan", "7E9E": "lian", "70BF": "none", "7F76": "liu", "80B0": "ran", "9CCF": "guan", "58B8": "chu", "5DFD": "xun", "603C": "dui", "8C6F": "xi", "94EF": "se", "590D": "fu", "61CD": "lin", "6471": "man", "6D88": "xiao", "8043": "dan", "8C9E": "zhen", "976A": "ding", "58F7": "hu", "5F0E": "san", "7E16": "xia", "8079": "ning", "81FE": "yu", "82D2": "ran", "98E8": "xiang", "4E6B": "jia", "5A9B": "yuan", "80AE": "ang", "9C10": "e", "5832": "ji", "6758": "chi", "6863": "dang", "753F": "meng", "7B27": "ce", "8EAD": "dan", "5DD9": "nao", "6308": "qie", "68B2": "zhuo", "72D9": "ju", "57C6": "que", "66FF": "ti", "6767": "mang", "9BF8": "hou", "9CA8": "sha", "5BEA": "wei", "6724": "lang", "4F8D": "shi", "5AAD": "xu", "5C57": "none", "6042": "xun", "7387": "lu;shuai;shuo", "75AD": "zong", "77D4": "guan", "829C": "wu", "9DC1": "yi;ni", "69EC": "hua", "7884": "lin", "844C": "jian", "8638": "zhan", "9976": "rao", "5713": "yuan", "81C1": "lian", "961D": "fu;yi", "57EC": "dong", "7B18": "shan", "9166": "fa;po", "93BB": "suo", "964E": "shu", "98CE": "feng", "9C2B": "rong", "64D8": "bo;bai", "64E2": "zhuo", "7A59": "pu", "9055": "wei", "90FD": "dou;du", "9919": "shi", "8494": "shi", "92B1": "diao", "958F": "run", "99A6": "xian", "4E9E": "ya", "5665": "nong", "836E": "zhou", "867B": "meng", "94C3": "ling", "5957": "tao", "603E": "none", "6F45": "guan", "7687": "huang", "7BE8": "chu", "80C1": "xie", "9EFF": "yuan", "53D4": "shu", "5A5B": "jing", "628A": "ba", "5FE0": "zhong", "7D3F": "dai", "7EB9": "wen", "85E5": "yao;yue", "98E6": "jian", "5082": "chi", "5847": "xuan", "6D4A": "zhuo", "9E09": "yang", "52F6": "che", "9888": "jing;geng", "5762": "pan", "834B": "er", "8433": "nan", "8D58": "zhui", "9E5C": "wu", "6320": "nao", "6F25": "wa", "91C3": "shi", "9F85": "bao", "4F23": "xian", "5407": "zi", "7C1C": "dang", "6A79": "lu", "98C6": "biao", "71AF": "han", "72AA": "kui", "7A51": "se", "8A20": "shen", "8FDE": "lian", "9E60": "liu", "5106": "jing", "5DB2": "sui", "71BF": "huang", "752A": "lu", "81B5": "cui", "9585": "men", "967F": "shan", "9AF5": "er", "7256": "you", "7AA5": "kui", "8399": "jun", "83A9": "fu;piao", "92B4": "shi", "96B2": "zhi", "9DAA": "ju", "9EF6": "yan", "5DAB": "ye", "6DF3": "chun", "7E5E": "rao", "5A8A": "qian", "62DB": "zhao", "6C2E": "dan", "7330": "ya", "7867": "none", "78A4": "ying", "8904": "none", "99FC": "tu", "51A6": "kou", "5DA8": "xue", "6181": "zong", "9B5E": "ba", "50DF": "zhang", "5860": "dui", "61FA": "chan", "6FB3": "ao", "78F8": "ding", "8661": "ju", "9BF2": "none", "9E52": "geng", "5364": "lu", "6D3C": "wa", "7115": "huan", "4FEA": "li", "5300": "yun", "5834": "chang", "6671": "shan", "84D4": "yao", "8760": "fu", "9502": "li", "99A5": "fu", "9AAC": "yu", "9B86": "ji", "5F2D": "mi", "6475": "suo", "7DF0": "yu", "9B52": "piao", "562A": "mai", "600A": "chao", "66A9": "gui", "75C9": "jing", "7679": "po", "7913": "jiang", "8CE6": "fu", "4E89": "zheng", "5418": "ou", "5717": "tu", "75CC": "tong", "80E3": "yi", "88CF": "li", "9E9E": "zhang", "56B2": "duo", "5AD3": "pi", "67E9": "jiu", "714C": "huang", "7349": "zhen", "756E": "mu", "8C8D": "li", "8CB9": "sheng", "9B9D": "xiang", "60A1": "li", "7438": "zhuo", "7953": "fu", "8735": "yuan", "95C3": "qu", "9916": "dou", "99FF": "jun", "9CF9": "qian", "5026": "juan", "5FF6": "hun", "6C57": "han", "70CC": "xiu", "7189": "yun", "7745": "han", "8062": "none", "8461": "pu", "5047": "jia", "5621": "tang", "76D7": "dao", "7F4F": "lu", "83AA": "e", "71FE": "dao;tao", "7458": "ye", "7B5D": "zheng", "7B74": "jia;ce", "7489": "lian", "7EB7": "fen", "865B": "xu", "9264": "gou", "51E0": "ji", "58C9": "ju", "5942": "huan", "7B6E": "shi", "7B77": "kuai", "8D51": "bi", "997D": "bo", "72FF": "yan", "749E": "pu", "4E3D": "li", "87DF": "liao", "7D0D": "na", "9432": "zhuo", "5138": "luo", "5757": "kuai", "5A49": "wan", "616D": "yin", "66A3": "qi", "6A65": "zhu", "7408": "fu", "7DC3": "zong", "82CD": "cang", "847A": "qi", "93EE": "kang", "56EF": "guo", "57CE": "cheng", "74CC": "gui", "81DE": "qu", "95F2": "xian", "4E1F": "diu", "4E47": "tuo", "5735": "dang", "6399": "zheng", "6AE2": "sou", "80F8": "xiong", "8236": "bo", "8F30": "yang", "910C": "tang", "62CC": "ban", "6D4F": "liu", "70EB": "tang", "7CB2": "can", "8A6D": "gui", "5587": "la", "8E1E": "ju", "8FDA": "none", "5B1F": "yi", "7244": "qiang", "789A": "bei", "7BD7": "yue", "71F2": "xie", "769D": "huang", "777F": "rui", "9B04": "ti", "63C8": "hong", "6EBC": "shi", "718D": "none", "891B": "lu", "8EA9": "jue", "91EB": "hua", "9458": "lei", "5591": "yin", "5CB4": "qu", "6090": "ti", "6258": "tuo", "751E": "chang", "8280": "tiao", "864B": "men", "937A": "zang;zhe", "9885": "lu", "6D39": "huan", "6DFE": "yin", "6EA4": "ma", "8C19": "an", "5DA4": "yao", "78E9": "qi", "9A04": "lu", "9A5A": "jing", "51E8": "feng", "530A": "ju", "5748": "keng", "9B05": "peng", "59AF": "zhou", "618D": "jiao", "7C79": "nu", "92EA": "pu", "9327": "guan", "505C": "ting", "5DB7": "yi", "7F54": "wang", "5788": "none", "6A4C": "xian", "7B80": "jian", "83D3": "guo", "9036": "wei", "57B4": "nao", "5CB2": "kuang", "5D7E": "cen", "5F5F": "huo", "710E": "xie", "8022": "lao", "86C8": "tie", "5336": "jiu", "5ECC": "jian", "8566": "xu", "8C0D": "die", "5702": "hun", "76BC": "gu", "8D54": "pei", "9522": "gu", "96DA": "guan", "547C": "hu", "5616": "ze", "6716": "lang", "6D6C": "li", "72D1": "ling", "7ADD": "bing", "99C9": "jiong", "53C5": "can;cen;shen", "60AE": "wu", "68F6": "lai", "7614": "ku", "7F8D": "ta", "94DD": "lu", "9CB9": "shen", "5369": "jie", "5B5D": "xiao", "75E6": "wu", "7F82": "juan", "7FBA": "nou", "86C9": "ling", "6D06": "cheng", "95A9": "min", "6493": "nao", "94AF": "ba;pa", "66CB": "qin", "706D": "mie", "766D": "ying", "9C7D": "dao", "6912": "jiao", "70E1": "guang", "7F07": "ti", "8D10": "jin", "91CA": "shi", "9906": "yao", "5C66": "ju", "62DD": "bai", "7494": "zeng", "749A": "qiong", "8745": "can", "97D9": "wei", "97F3": "yin", "56C4": "li", "6248": "hu", "7F02": "ke", "8C3C": "hong", "97C6": "qian", "6C95": "wu", "57E2": "juan", "5F83": "wang", "6676": "jing", "6EA7": "li", "6EE2": "ying", "8618": "rang", "9110": "chu", "4EB7": "lian", "5659": "qin", "646E": "ao", "74AA": "zao", "9586": "yan", "9B90": "tai", "4EE8": "sa", "4F7E": "yi", "51F8": "tu;gu", "579B": "duo", "6466": "hua", "77FB": "ku", "8423": "ding", "93FD": "xiu", "965E": "sheng", "5419": "xue", "5B15": "shi", "5DEC": "none", "64E5": "lan", "6F84": "cheng;deng", "91B8": "niang", "91E8": "zi", "995B": "meng", "4F0A": "yi", "4FB1": "cheng", "6F39": "yan", "6FFA": "jian", "723A": "ye", "73EE": "pei", "76AE": "pi", "810C": "none", "5626": "jiao", "8D79": "qiong", "8FC0": "gan", "9127": "deng", "91F7": "tu", "9DBC": "jian", "4F3B": "beng", "5807": "jin", "5919": "su", "59E1": "kuo", "6A60": "nuo", "7B1E": "chi", "800B": "die", "8A8E": "su", "9B00": "ti", "620E": "rong", "80C8": "ba", "94AC": "huo", "98BF": "fan", "75F7": "an", "7EA8": "wan", "81FB": "zhen", "53BE": "du", "5982": "ru", "6035": "chu", "7934": "bo", "9556": "biao", "4E75": "yan", "5E79": "gan", "7316": "chang", "9605": "yue", "5846": "wan", "64AE": "cuo;zuo", "6C78": "fang", "73D2": "jin", "75A4": "ba", "8EAC": "gong", "9DE6": "jiao", "50F6": "min", "564C": "cheng;ceng", "567F": "zui", "5AD7": "yu", "72CC": "sheng", "74E3": "ban", "8A9E": "yu", "5E29": "qiao", "7E99": "luo", "8943": "bao", "4EC0": "shen;shi", "5198": "yin", "571B": "yi", "58CE": "xuan", "702C": "lai", "852B": "nian", "88AA": "qu", "5284": "zha", "7FE2": "tao", "8F2F": "ji", "9700": "xu", "5548": "heng", "5AEA": "lao", "72F5": "mang", "730E": "lie", "7EE5": "sui", "897A": "jian", "9A60": "yan", "67D2": "qi", "69F1": "you", "700F": "liu", "8762": "xie", "922B": "none", "5154": "tu", "6D81": "shen", "6ECF": "fu", "8239": "chuan", "8E23": "bo", "936E": "zhen", "5E69": "fen", "6BFC": "he", "81C7": "juan", "567B": "sai", "5DF2": "yi", "6CB9": "you", "7361": "shuo", "757D": "tun", "7D0E": "zi", "884E": "kan", "8869": "cha", "9374": "duan", "4F91": "you", "69D7": "qiao", "6D0E": "ji", "94E7": "hua", "9A64": "xiang", "5BCE": "bing", "726A": "yan", "754E": "quan", "78A0": "ding", "78BA": "que", "86CD": "ying", "88C2": "lie", "8E13": "wei", "965A": "fu", "750F": "beng", "54A9": "mie", "5742": "ban", "59F4": "lie", "6282": "kuang", "7B40": "gui", "8A99": "heng", "90B5": "shao", "99B0": "di", "9CBF": "chang", "533C": "an", "713C": "shao", "9A0D": "ke", "5064": "you", "515A": "dang", "69A6": "gan;han", "8882": "mei", "91AC": "jiang", "4FF8": "feng", "759E": "xu", "7D91": "kun", "5AA1": "lian", "7C16": "duan", "9CAA": "jun", "8529": "yin", "5199": "xie", "6FA3": "huan", "772D": "sui", "52B1": "li", "5516": "ya", "73AD": "pi", "78EA": "cui", "792F": "ying", "7A1B": "kun", "819A": "fu", "8B55": "wu", "95CF": "none", "9A4D": "xiao", "4F6F": "yang", "66A4": "hao", "8FD9": "zhei", "5786": "lu", "63A2": "tan", "69DC": "zui", "80FE": "zi", "9088": "miao", "93B6": "ge", "50DA": "liao", "5F1C": "qiang", "5989": "dan", "59B0": "zhou", "652A": "jiao;gao", "7835": "bo", "7F7B": "wei", "7FAD": "yu", "8CC7": "zi", "94A0": "na", "960E": "yan", "9C1F": "pang", "8B83": "zan", "8C64": "ken", "5A79": "yao", "6ED1": "hua;gu", "801B": "chi", "9302": "ling", "503B": "ye", "59AB": "gui", "6B4B": "yi", "729A": "wei", "8700": "shu", "50AD": "yong", "5973": "nu;ru", "5C68": "ju", "5E9A": "geng", "6093": "qian", "6693": "mao", "6885": "mei", "6CA4": "ou", "87BA": "luo", "9406": "sui", "9A1A": "qian", "63F2": "she;die", "6762": "none", "6831": "gong", "6FF1": "bin", "82E8": "ni", "8697": "jue", "8DBB": "chen", "6849": "an", "701E": "jing", "88C5": "zhuang", "8C71": "wen", "98FA": "ci", "824A": "bo", "9CD9": "yong", "6440": "wu", "6E86": "xu", "73DE": "luo", "89FD": "xi", "8FB0": "chen", "91EC": "han", "9C9E": "xiang", "66FC": "man", "72A5": "piao", "7DDA": "xian", "4F79": "gui", "5093": "shan", "50C0": "di", "5720": "ya", "5B3C": "liu", "5E03": "bu", "64BC": "han", "66C5": "ye", "6753": "shao;biao", "70AD": "tan", "782C": "la;li", "9136": "kuai", "9EC3": "huang", "6AA5": "yi", "6F14": "yan", "74C0": "ruan", "4EED": "ren", "54A3": "guang", "7231": "ai", "8353": "ping", "4EC6": "pu", "689D": "tiao", "6BA0": "chou;xiu", "7997": "si", "8025": "tang", "8D29": "fan", "7321": "luo", "73A7": "yun", "7C7A": "xie", "7E4C": "none", "9B1B": "lie", "9F37": "xi", "56F1": "cong", "5D90": "long", "7748": "cheng", "90B9": "zou", "912C": "wei", "55F1": "na", "5662": "o", "6A06": "li", "8A65": "he", "5BF9": "dui", "6B12": "luan", "82A5": "jie;gai", "8786": "xi", "5433": "wu", "5553": "qi", "6951": "kui", "7D25": "zha", "80C0": "zhang", "836F": "yao", "8F85": "fu", "91E1": "fu", "9214": "chao", "95D5": "que", "54C6": "duo", "638A": "pou", "7E05": "none", "569D": "huang", "5997": "jin", "637C": "nuo", "89AB": "pang", "8CA4": "yi", "9B47": "yan", "4E96": "si", "5EB3": "bi;bei", "6593": "lan", "84AA": "po", "8861": "heng", "659C": "xie;xia", "7283": "pou", "7BDD": "gou", "8B65": "jiao", "54D5": "hui;yue", "93B7": "ma", "9557": "tang", "9960": "luo", "9A38": "shan", "9C7A": "li", "4E08": "zhang", "644E": "liao", "6ADC": "gao", "7B98": "jun", "7C0E": "zha", "93AB": "wan", "706C": "biao", "7F65": "juan", "89AE": "ping", "8AFA": "yan", "966B": "pei", "63A5": "jie", "6AE0": "fei", "73FF": "chuo", "88C3": "none", "8B82": "xuan", "5A36": "qu", "899C": "tiao", "5AFF": "hua", "5C1B": "yuan", "72E0": "hen", "875E": "mei", "8FE5": "jiong", "9DE3": "yin", "4F01": "qi", "54A2": "e", "60F6": "huang", "8322": "lie", "500E": "tian", "5166": "wang;wu", "854B": "rui", "8614": "jiong", "901E": "cheng", "5739": "kuang", "7636": "sou", "7E62": "hui", "85CA": "bian", "8753": "yu", "9714": "chou", "98D0": "zhan", "5318": "nao", "5410": "tu", "5A28": "xian", "67DB": "shen", "7BC5": "chuan", "8013": "ting", "931D": "cong", "8AEE": "zi", "9268": "ni", "9A27": "gua", "56E3": "tuan", "6515": "san", "6ED7": "bi", "7188": "xi", "923C": "zuo", "5FB4": "zheng", "6325": "hui", "76DC": "dao", "7D59": "geng", "579A": "yao", "64BE": "zhua;wo", "8831": "gu", "9987": "cha", "5129": "si", "5641": "wu", "67DA": "you", "67EB": "fu;bi", "7141": "chen", "7892": "yin", "7E96": "xian", "9C54": "shan", "5BFC": "dao", "629B": "pao", "7B0B": "sun", "8080": "yu", "9E93": "lu", "5E63": "bi", "6523": "luan", "8738": "qian", "9B7A": "he;ge", "6743": "quan", "6B50": "ou", "910A": "xiang", "5A4B": "xiao", "67A8": "cheng", "6F0E": "cong", "7364": "none", "5D92": "ceng", "8064": "ting", "83C5": "jian", "8C94": "pi", "5A10": "none", "6F91": "liu", "9E63": "jian", "4E26": "bing", "501D": "gan", "68DC": "yu", "7740": "zhe;zhuo;zhao", "9F1C": "qi", "5F01": "bian", "64CD": "cao", "6FB9": "dan;tan", "7A1D": "peng", "50C2": "lou;lu", "77D0": "huo", "8157": "pi", "8E82": "ta", "5A52": "tan", "5B73": "zi", "6CAC": "mei", "7850": "dong", "7C5E": "yu", "980A": "xu", "4E24": "liang", "5032": "dong", "6448": "bin", "6828": "ci", "73F0": "dang", "5992": "du", "5B85": "zhai;zhe", "69E7": "qian", "7278": "zi", "82C1": "cong", "85EF": "wei", "579E": "cha", "6F07": "xi", "6F60": "sun", "739E": "fu", "8204": "xi", "84A9": "zu", "8605": "heng", "662F": "shi", "98CB": "se", "99CA": "bo", "50E6": "jiu", "5A8F": "duan", "60F2": "yun", "66B9": "xian", "7067": "yan", "68A1": "kuan", "6FA4": "ze", "76F7": "tian", "7A67": "ji", "7C1B": "shai", "7CF9": "mi", "7FC0": "chong", "9776": "ba", "9CDB": "xi", "5C49": "ti", "64DB": "ye", "8DE3": "xian", "9C3A": "sao", "502B": "lun", "5897": "zeng", "5A1F": "juan", "844D": "fu", "9069": "shi;kuo", "979A": "kong", "59A1": "xin", "6303": "zhi", "673D": "xiu", "7853": "none", "786B": "liu", "93E4": "lou", "618C": "chun", "6F35": "xu", "82E9": "bo", "9938": "song", "9C24": "shi", "5CAB": "xiu", "636D": "bai", "65CD": "jing", "697B": "heng", "6F72": "shao", "7BB3": "ping", "828F": "du", "8E65": "lian", "95BB": "yan", "9A2B": "qian", "522A": "shan", "57F4": "zhi", "6C1B": "fen", "78BE": "nian", "50AF": "zong", "7F89": "luan", "8912": "bao", "548A": "he;huo", "9893": "tui", "5B8C": "wan", "5EA0": "xiang", "626B": "sao", "65A1": "wo", "78CB": "cuo", "7D7A": "chi", "5D12": "zu", "60BC": "dao", "8FB9": "bian", "903B": "luo", "9517": "zhe;zang", "9D60": "hu;gu", "4FAD": "jin", "505F": "huang", "5C73": "xian", "6360": "bang", "541C": "chou", "63C7": "nan", "6E0A": "yuan", "9AF7": "qu", "6183": "chuang", "6DE6": "gan", "6E63": "min", "72E1": "jiao", "755E": "mu", "917A": "pu", "9AD9": "gao", "4E5A": "yin", "51B4": "hu", "70F6": "ting", "762A": "bie", "93CC": "mo", "5157": "yan", "7051": "sa", "761F": "wen", "7A27": "xi", "8A56": "bi", "52A2": "mai", "6658": "han", "784B": "ai", "8801": "xiang", "9050": "xia", "991C": "guo", "9CDC": "gui", "577B": "chi;di", "65C2": "qi", "6D1F": "yi", "70C0": "hu", "7A6D": "lu", "9B15": "mo", "9F0D": "tuo", "7BC9": "zhu", "8AB9": "fei", "9ADB": "kao", "9BA1": "tiao", "4F29": "xin", "7550": "fu", "879D": "xi", "8BB3": "hui", "60F9": "re", "65C4": "mao", "806A": "cong", "8774": "hu", "91BC": "yan", "6236": "hu", "8053": "none", "8E4E": "dian", "51E7": "none", "53E7": "gua", "6A5E": "hui", "7268": "ren", "4E87": "none", "55D3": "sang", "6130": "huang", "6EE7": "xiao", "7399": "yu", "9048": "shi", "6841": "heng;hang", "6B63": "zheng", "6C3D": "tun", "7DBB": "zhan", "7F1A": "fu", "892B": "chi", "9CCB": "sao", "6678": "zhen", "7887": "ding", "81DB": "hu", "82D9": "li", "6254": "reng", "6296": "dou", "645F": "lou", "6684": "xuan", "68D5": "zong", "715C": "yu", "8A34": "su", "68DF": "dong", "6B69": "bu", "7228": "cuan", "80DC": "sheng", "842E": "yu", "92FA": "yuan", "6DA5": "none", "7F4E": "tan", "89DC": "zui;zi", "9A9D": "liu", "53D2": "ruo", "6894": "zhi", "6B48": "yu", "860B": "pin;ping", "89E7": "jie;xie", "5744": "tou", "5F38": "beng", "7890": "ling", "8D65": "xi", "8EF1": "gu", "5537": "yo", "5A1B": "yu", "6317": "jue", "7780": "mao", "5D52": "yan", "6087": "yu", "7369": "hui", "7E01": "yuan", "63DF": "xu;ju", "644C": "chan", "7EE0": "geng", "8EAB": "shen;juan", "55B9": "kui", "9350": "cong", "9C73": "li", "5A43": "cong", "672A": "wei", "7E88": "xie", "8DA0": "chuo", "9142": "cuo", "9220": "yi", "5594": "wo", "5920": "gou", "6FDA": "ying;xing", "75CB": "chong", "778D": "sou", "7875": "lu", "8BB2": "jiang", "51DE": "xi", "69BE": "gu", "4ED7": "zhang", "5EBB": "shu", "633D": "wan", "98E7": "sun", "9C91": "gui;xie", "771A": "sheng", "9545": "mei", "5AB3": "xi", "87D2": "mang", "9BFB": "la", "5292": "jian", "618B": "bie", "652D": "li", "6AB1": "qi", "6FCB": "chu", "7534": "zha", "8D0B": "yan", "6CD8": "hu", "7444": "xuan", "834D": "shou", "4EF6": "jian", "683C": "ge", "8252": "mao", "8994": "mi", "98FE": "shi", "5561": "fei", "66C1": "ji", "7AB5": "diao", "7CF7": "lan", "9675": "ling", "565F": "ying", "6272": "qian", "71E0": "yu", "551F": "none", "619F": "su", "7310": "qiang", "841B": "jiu", "6400": "chan", "7087": "po", "8636": "wei", "9D5A": "tu", "5FC9": "dao", "64E4": "xing", "68AD": "suo", "86FD": "bai", "8B3C": "hu", "94FA": "pu", "60CE": "ji", "94B5": "bo", "9633": "yang", "581B": "bi", "61D4": "lin", "67CB": "dai", "9EE4": "yan", "5311": "gong", "5582": "wei", "8E59": "cu", "764D": "ban", "5498": "bu", "6C6A": "wang", "6E7E": "wan", "86B0": "you", "96F3": "li", "65E4": "huo", "76FD": "feng", "7D47": "ju", "7DF2": "miao", "82C8": "li", "95DC": "guan", "986F": "xian", "5F08": "yi", "634D": "han", "64FC": "lu", "678F": "nan", "68ED": "yi", "6DB5": "han", "73A5": "yue", "7998": "di", "7D61": "luo;lao", "8319": "rong", "9BD1": "none", "9C2E": "wen", "65AC": "zhan", "72F8": "li", "7BDB": "ruo", "89BC": "luo", "5558": "wan", "69CC": "chui", "7AAC": "yu", "8826": "lu", "5D54": "wei", "62E7": "ning", "65D0": "zhao", "7F28": "ying", "7FF8": "pen", "8133": "nao", "4E2F": "jie", "5DC0": "jie", "7B16": "yi", "90D0": "kuai", "9485": "jin", "5431": "zhi;zi", "56DD": "jian;nan", "75B3": "gan", "78FB": "pan", "7CCE": "li", "80E1": "hu", "9C41": "zhu", "637A": "na", "6A3D": "zun", "6DAF": "ya", "9D0A": "zheng", "9D22": "you", "4F09": "kang", "537A": "jin", "56C9": "luo", "6401": "ge", "64C5": "shan", "941E": "nou", "4ED1": "lun", "6433": "xia", "6BDE": "pi", "6D0C": "lie", "6DA2": "yun", "8228": "ban", "9A89": "biao", "5159": "shi;ke", "52A0": "jia", "701F": "xiao", "7676": "bo", "966A": "pei", "9A1B": "fei", "54E3": "pou", "5EC5": "he", "6FC2": "lian", "766E": "yin", "8124": "shen", "87B8": "yu", "8C5F": "e", "957A": "ao", "95FC": "ta", "531D": "za", "6BE5": "xun", "73AA": "jian", "74AF": "hui", "8E18": "ju", "6017": "tie", "6526": "li", "799F": "tang", "8DB7": "he", "59A9": "wu", "59D8": "pin", "5B45": "xian", "5C85": "ban", "72FB": "suan", "567D": "pi", "6451": "guo;guai", "6838": "he;hu", "8756": "xuan", "8C05": "liang", "61BD": "song", "6BE4": "tuo", "7C3B": "ke", "8F8A": "gun", "9105": "yu", "917D": "yan", "9480": "nie", "95B7": "shai", "5A9E": "ti;shi", "5F7E": "ling", "70DE": "po", "7874": "none", "7D9D": "lin", "8EB7": "ai", "92BE": "gong", "5ACB": "niao", "74F8": "none", "7567": "lue", "80D3": "ping", "81E3": "chen", "8260": "none", "7B8A": "yu", "7B91": "sha", "8325": "kui", "9870": "pin", "5AAB": "none", "991A": "yao", "9B09": "zong", "4F5C": "zuo", "51C6": "zhun", "63FA": "yao", "7D63": "beng;ping", "8B86": "wei", "9EC9": "hong", "548B": "za;ze;zha", "549D": "si", "6B44": "none", "837D": "sui", "8F5F": "hong", "961C": "fu", "5852": "shi", "690B": "liang", "6B61": "huan", "6CD1": "you", "6D05": "zui", "78E3": "chen", "904E": "guo", "95D0": "tian", "9D71": "lu", "62D9": "zhuo", "70B2": "tai", "71ED": "zhu", "7F70": "fa", "8822": "chun", "881E": "jie", "8DF9": "xian", "8F68": "gui", "5399": "she", "584D": "cheng", "592D": "yao", "5A20": "shen;chen;zhen", "5FF4": "qian", "5278": "tuan;zhuan", "6BE0": "jia", "6E72": "yuan", "804E": "tiao", "92CE": "han", "9F88": "yin;ken", "6DC2": "de", "6DDA": "lei", "7B2B": "zi", "80B3": "wen", "81B0": "fan", "89C6": "shi", "8E9E": "xie", "69D2": "xu", "7467": "jin", "90C0": "ku", "9A62": "lu", "9EF0": "zhen", "5D05": "que", "7327": "wo", "79E6": "qin", "8205": "jiu", "5AE5": "zhuan", "7C14": "suo", "7F57": "luo", "92A5": "yi", "55E7": "jia;lun", "6768": "yang", "6D42": "yi", "7F77": "ba;pi", "913C": "zan", "9499": "gai", "9623": "yi", "4E1E": "cheng", "68D4": "hun", "70F9": "peng", "8B51": "jiao", "9119": "bi", "5BAE": "gong", "656A": "duo", "7759": "lie", "7E28": "huang", "8963": "bi", "92FE": "tao", "98A5": "ru", "9B13": "bin", "9D5B": "jing", "68A3": "cen", "69DA": "jia", "6DC0": "dian", "97E2": "hui", "860A": "yun", "88FA": "yan", "8EE3": "hong", "9790": "gong", "9E01": "luo", "580E": "leng;ling", "7221": "che", "9927": "wei", "585D": "bang", "86FE": "e;yi", "8953": "rao", "8999": "luo", "8E8D": "yue", "515C": "dou", "59D5": "zi", "7D06": "yu", "87C0": "shuai;shuo", "87E3": "ji", "8F2D": "ruan", "9D38": "zhu", "5088": "li", "690D": "zhi", "6DD3": "fang", "78F4": "deng", "8620": "qiang", "6ADB": "zhi;jie", "72B0": "qiu", "7758": "qiong", "8DC3": "yue", "9303": "bei", "9C8E": "hou", "5B0F": "fan", "6EEB": "xiu", "88D2": "pou", "91FF": "yin", "962E": "ruan", "9D91": "none", "5A1D": "pei", "6DF2": "piao;hu", "705F": "zhu", "8F70": "hong", "8F8F": "cou", "9BCE": "none", "9C5A": "xi", "6718": "juan;zui", "9505": "guo", "96FE": "wu", "9B72": "lu", "9BC3": "wu", "52D7": "xu", "7B29": "fa", "8208": "xing", "9689": "nie", "974D": "none", "9983": "guo", "4FA8": "qiao", "61FE": "she;zhe", "68EE": "sen", "6E96": "zhun", "7AB1": "tiao", "7E27": "tao", "7F4D": "lei", "5775": "qiu", "5B90": "yi", "653C": "gan", "685D": "none", "784F": "yan", "94F8": "zhu", "5B92": "zhun", "6CBA": "tian", "7E3F": "shan", "84FE": "lu", "938F": "liu", "944C": "bin", "4FFC": "yu;zhou", "767D": "bai", "7FCB": "la", "539A": "hou", "6705": "qie", "70F8": "hai", "9431": "qian", "9E6F": "zhan", "50F9": "jia", "5C30": "zhong", "60A4": "cong", "58E1": "rui", "5E1F": "yi", "660E": "ming", "6BA4": "shang", "6D85": "nie", "80C4": "zhou", "9E25": "ou", "7573": "die", "61EF": "fu", "7266": "mao", "8917": "yan", "63C0": "jian", "6FAF": "can", "73CE": "zhen", "8245": "yu", "5645": "kui", "6195": "cheng", "6662": "zhe", "6F50": "jiao", "7769": "lu", "7E0F": "pan", "790B": "zhai", "851F": "cu", "8C65": "gai", "55CF": "cha", "5A0D": "cheng", "5ED1": "qin;jin", "70D0": "zhou", "7BA1": "guan", "9600": "fa", "97AC": "jian", "6B66": "wu", "702B": "hu", "9777": "yin", "9C55": "fan", "597A": "jiu", "7D80": "shu", "8061": "cong", "9890": "yi", "766B": "dian", "9091": "yi", "5355": "dan;chan;shan", "56BA": "ta", "80A1": "gu", "5856": "cheng", "602E": "you", "8719": "song", "6CB1": "tuo", "7A85": "yao", "87A0": "yi", "891C": "none", "968D": "huang", "9B62": "ji", "5BBA": "huang", "6818": "chi;yi", "723E": "er", "7ED6": "die", "7EFC": "zong;zeng", "908C": "li", "98EE": "yin", "9D77": "yuan", "4E81": "gan", "5BD8": "zhi", "63EC": "tu", "6918": "chu", "7074": "hong", "7963": "lu", "7B60": "yun;jun", "808D": "qiu", "8A41": "gu", "8A57": "xiong", "5B66": "xue", "7341": "ma", "7928": "lei", "8083": "su", "84B2": "pu", "4F4E": "di", "62D4": "ba", "6D1D": "an", "82DC": "mu", "84B6": "fen", "857C": "si", "95A0": "run", "9A52": "tuo", "5236": "zhi", "6F58": "pan", "7A32": "dao", "86A9": "chi", "4F71": "fa", "5326": "gui", "5D07": "chong", "6278": "xi", "6B7B": "si", "8AA7": "pu", "974E": "he", "9ADA": "qiao", "513A": "nuo", "65A7": "fu", "69D0": "huai", "6CB5": "mi", "747D": "cong", "913E": "you", "4FAE": "wu", "60B4": "cui", "6AE8": "lu", "9E29": "zhen", "5222": "ling", "59BB": "qi", "5B2F": "tai", "5F0D": "er", "60AA": "e;wu", "71AB": "zhi", "7A49": "zhi", "8331": "zhu", "514B": "ke", "5FA6": "jia", "62E3": "jian", "6423": "mie", "6B4E": "tan", "70E0": "hui", "76DA": "qiu", "9E85": "pao", "5F95": "lai", "6010": "kou", "618F": "chi", "66F4": "geng", "706A": "yu", "707A": "xie", "83CE": "kun", "91C2": "jiao", "9D6C": "peng", "5040": "ying", "5B6A": "luan", "635D": "tuo", "8B89": "yi", "52C4": "min", "6C30": "qing", "7C06": "kou", "7D5D": "ku", "91A1": "zha", "50B6": "zu", "6F0C": "jin", "82C7": "wei", "9C45": "yong", "4F1D": "yun", "69FF": "jin", "8796": "hua", "9C6C": "ru", "682D": "er", "79D9": "ku", "96AC": "ni", "70DF": "yan;yin", "929E": "jun", "9756": "jing", "5074": "ce;ze", "60B1": "fei", "7172": "bao", "7CEE": "jian", "7DCE": "yu", "9855": "xian", "9BE3": "yi", "7445": "ti", "7AC3": "zao", "910F": "ru", "971C": "shuang", "86AF": "qiu", "87E7": "lao", "90DF": "jia", "974B": "li", "5261": "yan;shan", "53A8": "chu", "631C": "ya", "6675": "qi", "8656": "hu", "9BD4": "zi", "5E04": "ding", "61B3": "tan", "6E6B": "qiu;jia;jiao;jiu", "7594": "ding", "7D5E": "jiao", "88A2": "pan", "961B": "huan", "5F2A": "jing", "5F88": "hen", "8C22": "xie", "616C": "jin", "746B": "tao", "7495": "xun", "7EA3": "zhou", "6914": "zi", "7063": "wan", "7C2C": "lu", "9CE5": "niao", "516E": "xi", "64F3": "jie", "8093": "huang", "8FB5": "chuo", "9687": "wei", "9951": "ji", "5FC7": "le", "61AF": "can", "819D": "xi", "8307": "ba", "8749": "chan", "8926": "nai", "8AA4": "wu", "8BC8": "zha", "969F": "xi", "6C40": "ting", "75CE": "jie", "8BDC": "shen", "5EB8": "yong", "7165": "huan", "76BB": "zha", "4ECA": "jin", "8E10": "jian", "93E7": "long", "9801": "ye", "6FFB": "dui;wei", "7270": "you", "75D0": "hui", "7693": "hao", "910B": "sou", "920A": "xin", "5D68": "wu", "6AEB": "zhu", "7064": "luan", "74A0": "fan", "81D0": "xun", "8FBE": "da", "98FF": "duo", "52FB": "yun", "6022": "tu", "6B3F": "kan", "6ECA": "xi", "7C2A": "zan", "6421": "sang", "76B9": "jun", "7F61": "gang", "87A9": "none", "5A74": "ying", "6127": "kui", "659A": "jia", "7094": "gui;que", "7D87": "xiu", "6F30": "peng", "7118": "dao;tao", "7EC9": "zhou", "913B": "lian", "9D6B": "zhao", "9E94": "jiu", "4F55": "he", "50F8": "jin", "5EF3": "ting", "69E6": "yong", "7D1A": "ji", "54F5": "ba", "8253": "die", "9E83": "biao", "4EFA": "cang", "590C": "ling", "6E34": "ke", "8C35": "zhan", "8DBF": "ta", "5B9F": "shi", "733B": "sun", "8779": "yun", "5FEB": "kuai", "91A7": "yu", "5121": "lei", "5CC1": "mao", "74F3": "hu", "977E": "yi", "9BF6": "hun", "5F84": "jing", "6CAB": "mo", "7EF1": "shang", "8C6C": "zhu", "4E82": "luan", "669D": "ming", "6BB9": "yi", "8F12": "zhe", "95E0": "hui", "532E": "kui", "6C17": "qi", "6CBC": "zhao", "71FD": "chou", "7EF7": "beng", "9405": "pie", "5BBE": "bin", "7E29": "cai", "8D7F": "chi", "9D02": "ju", "4EF5": "wu", "576B": "dian", "5DBA": "ling", "6387": "duo", "6544": "wu", "6B33": "kuai", "6C20": "shen", "7EE4": "xi", "82D0": "yi;ti", "8375": "ren", "85E8": "biao", "9DBD": "zhun", "6069": "en", "6CA5": "li", "6EBA": "ni;niao", "708F": "kai", "8485": "none", "8EE4": "hu", "535F": "bu", "5D8A": "zui", "7729": "xuan", "88AF": "bo", "9B2A": "dou", "68C0": "jian", "7AEF": "duan", "873A": "ni", "89C8": "lan", "9B20": "kuai", "5098": "san", "68E9": "yuan", "7C21": "jian", "81EA": "zi", "8AF2": "yin", "8F1D": "hui", "9E43": "juan", "5A02": "hong", "6E3A": "miao", "6EEF": "zhi", "70DA": "xia", "7F9A": "ling", "8077": "zhi", "8E01": "xing", "96A8": "sui", "6239": "e", "6481": "qian", "64F2": "zhi", "733C": "bo", "7B14": "bi", "7CCC": "zan", "8149": "jie", "8ED7": "shu", "9B38": "liu", "84FF": "xu;su", "739B": "ma", "5C51": "xie", "93A2": "wu", "9C38": "qu", "5C5B": "ping", "8871": "jie", "5B6C": "nao", "80BB": "ken", "98DD": "fei", "5F15": "yin", "8F95": "yuan", "5AB1": "yao", "5DAF": "ji", "6A00": "di", "606E": "quan", "6985": "yun", "6E8C": "po", "8E97": "wei", "8F13": "wan", "5524": "huan", "5C54": "ni", "5CD1": "quan", "634F": "nie", "7B72": "shao", "8E00": "chu", "97A7": "qiu", "644D": "suo", "729E": "se", "7706": "fang", "8BAD": "xun", "903C": "bi", "96A4": "tui", "9E98": "xiang", "593C": "kuang", "64AD": "bo", "5944": "yan", "6795": "zhen", "95A6": "chu", "9804": "pan", "9F62": "ling", "5273": "zha", "6334": "mei", "73F3": "wen", "766C": "xian;xuan", "6956": "ji", "6FE0": "hao", "7456": "duan", "7914": "pi", "7DBA": "qi", "844A": "an", "70AF": "jiong", "7B03": "du", "81BB": "shan", "83E3": "qin", "9095": "yong", "6FA0": "min;mian;sheng", "895A": "sui", "59EE": "heng", "5A17": "ding", "6247": "shan", "861F": "yin", "94E1": "zha", "7E8A": "kuang", "806B": "lian", "847D": "yao", "8754": "jie", "9841": "ding", "9C47": "kang", "4F43": "dian;tian", "6EB9": "su", "706B": "huo", "745D": "huang", "5C70": "ni", "696A": "die", "6A29": "quan", "77F6": "ji", "886D": "fu", "8CB5": "pian", "994F": "dan", "5371": "wei", "5518": "qi", "5DE8": "ju", "6B5E": "kan", "70AB": "xuan", "858C": "xiang", "9009": "xuan", "9DE7": "yi", "5DAD": "e", "752F": "ning", "7FE6": "jian", "63F7": "cha", "74ED": "dan", "77BC": "jian", "91E2": "nai", "504A": "yu", "7986": "bei", "7EDA": "xuan", "8F35": "ge", "9C63": "zhan", "9D7C": "kong", "51CF": "jian", "5259": "chuang", "5C95": "jie", "70B3": "bing", "71C1": "ye", "7560": "none", "4F97": "dong;tong", "6119": "ke", "62C9": "la", "64A5": "bo", "7193": "wen", "7565": "lue", "596D": "shi", "6673": "xi", "6E83": "kui;hui", "89B6": "luo", "8EEA": "ao", "9004": "pang", "6B30": "xu", "8FE1": "ni", "5AC0": "qin", "6530": "gui", "6562": "gan", "66ED": "tang", "76CC": "wan", "7CFE": "jiu", "9C25": "guan", "591C": "ye", "5D9D": "deng", "7273": "mu", "780E": "jie", "7BB5": "sheng", "7F01": "zi", "5745": "qin", "5790": "ci", "641A": "xie", "7656": "pi", "8F7E": "zhi", "9774": "xue", "9A9E": "qian", "9E80": "you", "5857": "tu", "7BEB": "zhu", "8254": "none", "827A": "yi", "846F": "yao", "989D": "e", "9918": "yu", "9BAC": "pu", "4F90": "xu", "5D51": "jie;he", "607C": "nao", "6498": "da", "6D44": "jing", "739D": "wu", "7422": "zhuo;zuo", "7811": "ya", "82C2": "yin", "8D3C": "zei", "9D70": "diao", "5820": "hou", "5F29": "nu", "68EC": "quan", "7720": "mian", "7A1E": "ke", "8A95": "dan", "9049": "zhen", "90BA": "ye", "6C9C": "pan", "6E48": "mei", "8454": "hou", "779B": "cong", "82C9": "pi", "839D": "cuo", "9324": "qi", "97B9": "kuo;kui", "99C6": "qu", "9D51": "juan", "5A65": "chuo", "5F92": "tu", "7959": "mei", "79DC": "ni", "828A": "qian", "906E": "zhe", "98EF": "fan", "591F": "gou", "66A8": "ji", "7FFF": "dao", "90CE": "lang", "9845": "qian", "510A": "chu", "796D": "ji;zhai", "81A7": "tong", "97B5": "xie", "986A": "hui", "7A29": "ji", "92C4": "wan", "4E13": "zhuan", "5B58": "cun", "62A9": "tan", "7843": "zhu", "7BF7": "peng", "8C04": "chan", "5279": "lu", "66C8": "tong", "6E0E": "du", "738D": "ga", "753D": "quan", "7770": "ma", "7DCF": "zong", "8736": "su", "9A6D": "yu", "538C": "yan", "6A51": "lao", "7243": "zang", "72E7": "ta", "72FE": "zhi", "86C4": "gu", "9593": "jian", "980B": "gu", "983C": "lai", "9F40": "wu", "5B1B": "huan;qiong;xuan", "6F36": "huan", "75B5": "ci", "7825": "di", "7BC0": "jie", "870B": "lang", "8A4F": "ao", "8A5C": "tao", "98F8": "tao", "9A68": "xi", "567E": "yin", "5B11": "yi", "6685": "geng", "67C6": "la", "758C": "nie", "7A3A": "zhi", "8FAB": "bian", "9BDE": "zhou", "5445": "mei", "55D0": "hai", "5C94": "cha", "5D9B": "liao", "696B": "ji", "8055": "hao", "5861": "tian", "698E": "jia", "6CAA": "hu", "7478": "bin", "8F46": "lu", "5FAD": "yao", "6BA7": "cu", "7A93": "chuan", "98AD": "zhan", "99EF": "none", "573D": "mo", "62FD": "zhuai;ye", "754D": "jie", "7CBB": "chang", "67A1": "dou", "7B58": "kou", "7C4E": "none", "8580": "yun", "5C6C": "shu;zhu", "6D5B": "han", "7BCF": "qian", "8315": "qiong", "4FC3": "cu", "510E": "zai", "5461": "wen", "5531": "chang", "5C97": "gang", "8488": "kai", "8D43": "zang", "98F5": "zhai", "9B4F": "wei", "56C5": "chan", "6573": "ai", "6BEF": "tan", "72F4": "bi", "7CE9": "kuai", "7D7F": "qiu", "5218": "liu", "6C09": "sao", "7CDC": "mi;mei", "89B4": "deng", "902B": "jue", "6775": "chu", "82F8": "hu", "82FB": "fu", "84F5": "jie", "9375": "jian", "94DE": "diao", "9CA0": "geng", "522E": "gua", "5395": "ce;si", "581E": "die", "5C7B": "ren", "62B5": "di", "6BD4": "bi", "7771": "xia", "7B1D": "na", "8D60": "zeng", "9712": "ying", "98E1": "can", "9B57": "chou", "5380": "xi", "5557": "dan", "85A0": "fan", "8B8C": "yan", "57F0": "cai", "700D": "chan", "763B": "lou", "8C27": "mi", "8F89": "hui", "9F1A": "chang", "54DF": "yo", "7053": "luan", "9280": "yin", "9D50": "wu", "5A29": "mian;wan", "775C": "zheng", "7FBD": "yu", "935F": "xing", "577C": "che", "670B": "peng", "70A9": "ling", "5975": "ding", "6B68": "bu", "7C2D": "shi", "8CF6": "cang", "9570": "lian", "964D": "jiang;xiang", "6F89": "gan", "8CDC": "si;ci", "93B3": "nie", "9935": "wei", "9CF2": "shi", "6FBA": "yi", "876C": "zong", "5DB6": "none", "6AB7": "mi;ni", "75D4": "zhi", "8773": "du", "8B1E": "xue", "916E": "tong", "5B3A": "ni", "7C7F": "cun", "8513": "man;wan", "879A": "nai", "8D2F": "guan", "5136": "hui", "58F2": "mai", "5AFC": "mo", "61C1": "huan", "6CEE": "pan", "7644": "qiao", "8047": "zheng", "83DA": "zhan", "997E": "dou", "5754": "di", "57BD": "yin", "626A": "men", "7372": "huo", "87DD": "qu", "9853": "zhuan", "4E38": "wan", "66C2": "kuang", "6A43": "fa", "7D17": "sha", "8587": "wei", "894C": "dan", "4F57": "tuo", "5A41": "lou;lu", "7725": "zi", "852E": "kui", "87CE": "man", "8C7E": "pi", "8E0B": "jiao;jue", "4E06": "none", "61AD": "liao", "94E6": "xian", "5C2F": "kui", "51F4": "ping", "5475": "he;ke;a", "5E97": "dian", "6E73": "nan", "768C": "mo", "7AF2": "ceng", "8371": "wei", "93F7": "pu", "4F2A": "wei", "4FFF": "chi", "643E": "zha", "7153": "tuan", "917F": "niang", "95BE": "yu", "975F": "fei", "52DB": "xun", "7AB8": "xi", "7682": "zao", "76F3": "mang", "809A": "du", "8B47": "she", "90F3": "ni", "919F": "yong", "9B22": "bin", "9C64": "gan", "5AD1": "bao", "6713": "tiao", "7C27": "huang", "8BC4": "ping", "4E5E": "qi", "5862": "wu", "5BB2": "bao", "65EE": "ga", "7450": "jian", "7927": "lei", "8397": "che", "9707": "zhen", "5057": "sheng", "5C9D": "zhai", "6808": "zhan", "513B": "tang", "6943": "wo", "9177": "ku", "9761": "mi", "9C89": "you", "4FDA": "li", "54DC": "ji", "925D": "li", "96F1": "pang", "61E0": "qi", "7B75": "yan", "52E3": "ji", "5DF7": "xiang;hang", "66C9": "xiao", "6B35": "kuan", "5D71": "yong", "735F": "yao", "9396": "suo", "73CB": "liu", "7742": "mei", "8983": "tan;qin", "9239": "pi", "97A0": "ju", "9A7A": "zou", "9D66": "lu", "52CD": "qing", "759B": "zhou", "76B2": "jun", "7C83": "bi", "8581": "yu", "9BAE": "xian", "9782": "jia", "5737": "none", "6588": "xue", "6A2F": "qiang", "76A7": "ai", "7C45": "yu", "983E": "zi", "9931": "hou", "4F98": "cha", "5D8D": "xi", "629E": "ze;zhai", "754C": "jie", "7B10": "gang", "7EBF": "xian", "84DD": "lan", "9B01": "li", "9C0A": "lian", "5BD0": "mei", "6F0B": "long", "809E": "cha", "651D": "she", "7882": "zong", "8964": "lan", "94D8": "ye", "9952": "rao", "5F4A": "qiang;jiang", "66FD": "ceng;zeng", "67AD": "xiao", "6933": "wei", "6B6B": "ju", "7B6A": "xia", "85EC": "tui", "87EC": "chan", "8EB3": "gong", "55D1": "ke", "5653": "xu;shi", "6D66": "pu", "6EF5": "mi", "7734": "xuan", "888C": "bao", "695B": "hu;ku", "7B05": "xiao", "86B5": "he;ke", "92C7": "bei", "5BC6": "mi", "6738": "li", "6B81": "mo", "7299": "san", "7439": "qin", "78B9": "xuan", "987B": "xu", "5EDA": "chu", "6BBD": "yao", "9014": "tu", "5062": "qiu", "5238": "quan;xuan", "5A3C": "chang", "5F1A": "tui", "6479": "mo", "73D0": "fa", "74E0": "hu", "7F7E": "zeng", "96B1": "yin", "9C34": "hui", "883B": "man", "8A9D": "an", "68D8": "ji", "6DD8": "tao", "77D9": "kan", "5642": "zun", "611E": "nuo", "6340": "feng", "66DF": "chen", "6C7A": "jue", "7010": "jian", "9749": "ai", "5397": "ti", "6EE6": "luan", "74BA": "wen", "8875": "ri", "5885": "shu", "7A7B": "yu", "90B6": "bei", "9C70": "none", "5D8C": "dao", "7389": "yu", "7661": "chi", "7FCE": "ling", "9597": "dou", "6879": "lang", "8C21": "su", "8ED3": "fan", "53DB": "pan", "568A": "pi", "59AC": "du", "5EE0": "chang", "66AE": "mu", "674C": "wu", "4E42": "yi;ai", "7370": "ning", "8247": "ting", "516A": "yu;shu", "5378": "xie", "6178": "di", "72B6": "zhuang", "821D": "xia", "84E8": "xiu", "87FD": "da", "968F": "sui", "71BC": "yi", "92D1": "cuan", "6266": "qian", "86B2": "ping", "99A0": "han", "9E61": "ji", "670F": "fei", "8E2C": "zhi", "5644": "chi", "6285": "ju", "6D1B": "luo", "6DA8": "zhang", "592C": "guai", "5E11": "tang", "7F0D": "duo", "8EE9": "dai", "9383": "pai", "7448": "rou", "833B": "mang", "8B2E": "ze", "9C57": "lin", "535A": "bo", "82CE": "zhu;ning", "8617": "bo;nie", "9089": "bian", "733F": "yuan", "76D1": "jian", "797A": "qi", "89FA": "yi", "8F02": "ju", "5593": "yao", "6A8A": "gan", "8130": "dou", "90E9": "xiao", "9BEF": "zhi", "5290": "huo", "7951": "zhi", "8452": "hong", "8A62": "xun", "96FA": "meng", "9AA6": "shuang", "5C6F": "tun;zhun", "5EAD": "ting", "8424": "ying", "8913": "bao", "8DE5": "duo", "93C8": "lian", "9F09": "tuo", "6B73": "sui", "78DA": "zhuan", "7D20": "su", "8A7B": "e", "4FA9": "kuai", "6019": "hu", "685C": "ying", "9053": "dao", "83F0": "gu", "9EED": "yan", "550B": "tu", "584C": "ta", "681C": "su", "7549": "fu", "9DA1": "he", "62A0": "kou", "6F88": "che", "7021": "sui", "780F": "fen", "92A9": "diu", "9672": "chui", "991D": "shi", "6645": "xuan", "6D69": "hao", "7A98": "jiong;jun", "83A5": "niu;chou", "8507": "ji", "8D78": "shan", "6268": "cha", "710D": "di;ti", "7CC9": "zong", "80EA": "lu", "89A1": "xi", "9DDF": "zhuo", "619E": "dui", "728A": "du", "88F6": "fei", "9BB8": "mian", "5AA7": "wa", "728C": "jia", "7497": "dang", "86AB": "bao", "8277": "yan", "6A33": "xin", "76E5": "guan", "7809": "hua;xu", "8103": "cui", "8864": "yi", "7993": "yang", "53C7": "dai", "62F4": "shuan", "660A": "hao", "6869": "zhuang", "89D3": "jiu", "94F1": "yi", "501B": "qi", "6309": "an", "6491": "cheng", "6B6C": "qian", "773F": "mai", "90F0": "zou", "9F02": "chao", "9732": "lu;lou", "67B0": "ping", "6A61": "xiang", "721D": "jue;jiao", "775A": "ya;ai", "881F": "la;zha", "91C4": "mi", "5837": "an", "6099": "heng", "6241": "bian;pian", "6E81": "ying", "9A30": "teng", "4E58": "cheng;sheng", "4F85": "gai;kai", "51C2": "mei", "87A7": "none", "56F9": "ling", "7028": "lai", "7412": "none", "8866": "gan", "9546": "mo", "58D1": "he;huo", "5A60": "wan", "63AD": "tian", "6C1C": "ri", "77E0": "ce", "82CA": "e", "766A": "ji", "7E50": "hui", "99C7": "wen", "9D92": "chi", "5443": "e", "603F": "yi", "6DF6": "lai", "7297": "jie", "76F4": "zhi", "7B6C": "cheng", "8444": "zuo", "5A48": "ling", "5613": "guo", "61CA": "ao", "69F4": "hu", "7DDC": "mian", "7E1F": "ru", "8434": "ze", "51C3": "shang", "5392": "ke", "65DB": "fan", "689F": "xiao", "6CCD": "ben", "7FA7": "suo", "857B": "hong", "93DE": "yong", "95B8": "kun", "884F": "yuan", "5211": "xing", "62BB": "chen;shen", "6572": "qiao", "6811": "shu", "7813": "zhe", "7985": "shan;chan", "915F": "tian", "92AE": "luan", "9B96": "none", "69B1": "cui", "8B9D": "zhan", "539C": "zui", "55CB": "xie", "6462": "hu", "6DD4": "chi", "943C": "fen", "9E4A": "que", "6BED": "dou", "781C": "feng", "84EB": "zhu", "88E4": "ku", "8BC3": "he", "8D8D": "chi", "99D1": "nu", "9B11": "lian", "5402": "mang", "58C0": "pi", "784D": "ken", "7ED8": "hui", "90EE": "none", "654F": "min", "81C0": "tun", "8E49": "cuo", "9103": "yu", "9227": "kang", "9925": "fei", "698C": "none", "6D08": "wei", "7ECA": "ban", "9BB3": "kao", "9E18": "shuang", "9E22": "yuan", "5337": "qu", "5C76": "none", "64FB": "sou", "5609": "jia", "59DB": "tong", "6B85": "sheng", "6D7D": "sui", "8C89": "he;hao;mo", "8D9D": "jian", "8EE2": "zhuan;zhuai", "9886": "ling", "9D2B": "none", "85B7": "ru", "8C50": "feng", "8E9F": "rang", "520B": "qian", "6B42": "chuan", "94FE": "lian", "52AD": "shao", "5595": "mian", "58A4": "kuai", "763C": "mo", "7ABA": "kui", "8010": "nai", "8108": "mo;mai", "9BBA": "za", "5B13": "chan", "6A07": "xiu", "7D35": "zhu", "8B1C": "yuan", "8BBC": "song", "9001": "song", "5652": "lian", "5AD4": "pin", "5F86": "xi", "67C1": "tuo;duo", "6B2F": "xi", "7F86": "pi;biao", "829A": "tun", "8967": "zhi", "98C0": "liu", "9E50": "qian", "5A26": "pin", "7388": "lu", "8012": "lei", "87AA": "shang", "880B": "zhu", "9DA4": "yun", "5384": "e", "57CD": "xuan", "6203": "tang", "79CB": "qiu", "8D2E": "zhu", "9C69": "none", "9F27": "tuo", "53B0": "chang", "5E4F": "jia", "7DD5": "none", "8DEC": "kui", "9428": "fei", "9AED": "zi", "9C21": "liu", "6E03": "re", "7A9C": "cuan", "7E87": "lei", "8258": "sou;sao", "5B91": "jing", "646F": "zhi", "6DD0": "chang", "6EAE": "shi", "7EBE": "shu", "8443": "zuo", "85AE": "sou", "88A0": "zhi", "990F": "yi", "6214": "jian", "6701": "can", "691E": "xi", "785C": "keng", "7C84": "ban", "87DA": "peng", "92DF": "qin", "9A84": "jiao", "8548": "xun;jun", "73AB": "mei", "7F91": "you", "862A": "mi", "8802": "she", "9BBD": "yu", "507F": "chang", "5951": "qi;xie;qie", "60B0": "cong", "6413": "cuo", "7BD6": "tang", "8263": "lu", "847C": "zong", "9798": "qiao;shao", "4E16": "shi", "524C": "la", "887C": "zhi", "90C5": "zhi", "98FD": "bao", "9D12": "ling", "57CC": "lang", "62A5": "bao", "8586": "ai", "875D": "yuan", "880A": "lian", "9323": "zhuo", "956A": "qiang", "5747": "jun;yun", "722E": "pao", "8052": "guo;gua", "8FB3": "nong", "8FEF": "tao", "9AF9": "xiu", "9F76": "e", "5880": "chi", "59B9": "mei", "6AC1": "mi", "607D": "yun", "7062": "nang", "7AE2": "si;qi", "8460": "shen", "8C7D": "na", "9B87": "wei", "9DB1": "xuan", "9F23": "fei", "55BC": "jie", "66F0": "yue", "6A8B": "ju", "7462": "rong", "63E3": "chuai", "6925": "zhi", "8DB0": "none", "9478": "lei", "9E13": "lei", "9E15": "lu", "52B4": "lao", "5B8D": "rou", "5E48": "ping", "62CF": "na", "778E": "xia", "9514": "ju", "9B50": "jian", "9BB6": "jun", "65D6": "yi", "6B76": "yu", "6F5A": "xiao;su", "7846": "e", "8646": "lei", "8DCD": "ku", "6230": "zhan", "6D55": "jin", "6CD5": "fa", "6F18": "chun", "7E51": "qiao", "573F": "jia", "6152": "cong", "6FE9": "huo", "76AB": "piao", "80AF": "ken", "78C8": "wei", "88F3": "shang;chang", "512C": "qin", "672D": "zha", "7DD4": "shang", "5333": "lian", "72BE": "han", "83B1": "lai", "92D5": "zhi", "93AA": "sou", "57DE": "di", "7683": "mao", "8D3E": "jia;gu", "5D17": "gang", "65E2": "ji", "6EFD": "yong", "7D99": "ji", "7F0F": "bian;pian", "8FB2": "nong", "9A1D": "jian", "5031": "hun", "6598": "sheng", "68F7": "zou", "7B59": "lai", "8DB9": "jue", "9AEC": "pi", "6E66": "sheng", "747B": "kun", "8179": "fu", "9A1C": "huang", "8B7C": "jian", "8C72": "huan", "9401": "san", "9532": "qie", "5482": "za", "6577": "fu", "7AF5": "huai", "807D": "ting", "8D15": "du", "9F15": "dong", "531E": "jiang", "6D4C": "none", "762D": "biao", "79BE": "he", "7B54": "da", "8689": "wen", "6232": "xi;hu", "6BC2": "gu", "734D": "jing", "8A98": "you", "8BB4": "ou", "919B": "quan", "9380": "xiu", "9A92": "ke", "69D8": "yang", "9A96": "can", "9F65": "xie", "9F82": "yin", "6211": "wo", "6235": "qu", "692F": "duo", "6B7D": "zhe", "756D": "yu", "79B9": "yu", "89C7": "chan", "951E": "ke", "5B71": "chan;can", "6011": "ban", "765C": "dian", "77A4": "run", "7A03": "fu", "909C": "none", "93D8": "qiang", "5370": "yin", "5DB3": "di", "6BFF": "san", "70A1": "zheng", "8C0C": "chen", "50BA": "chi", "6580": "zhuo", "900E": "qiu", "51B1": "hu", "6024": "fu", "8DD0": "ci", "9DE1": "wu", "5148": "xian", "61E2": "lan", "6578": "shu;shuo", "6BA1": "bin", "7BAC": "ruo", "8B04": "teng", "9290": "chi", "9528": "xian", "9799": "xuan", "9E28": "bao", "508E": "dian", "6354": "jue", "6B79": "dai", "6DEF": "yu", "84E2": "lang", "981B": "lei", "5351": "bei", "5D06": "kong", "5D8E": "yu", "6AC3": "gui;ju", "6F8A": "cun", "7646": "lao", "89AD": "ming", "6E9D": "gou", "6F80": "se", "77AB": "shen", "9D10": "jia", "5FF8": "niu;nu", "6D87": "jing", "7234": "jue", "9121": "qiao", "926B": "jia", "9626": "yang", "988B": "ting", "5756": "ji", "801F": "ju", "88CB": "shu", "8D2C": "bian", "8D38": "mao", "93E6": "cong", "9C88": "lu", "6349": "zhuo", "7A17": "bai;bi", "8FA9": "bian", "9D99": "ti", "5156": "yan", "603D": "none", "6221": "kan", "758F": "shu", "79C7": "yi", "95EE": "wen", "63F5": "qian", "7001": "yang", "751B": "tian", "5139": "zan;zuan", "52CE": "lu", "5CFF": "wu;yu", "5D13": "gu", "6585": "xue", "8D3A": "he", "9E72": "meng", "4F95": "er", "59D3": "xing", "5C31": "jiu", "651B": "cuan", "6E1C": "nuan", "7C75": "fan", "984C": "ti", "5408": "he;ge", "581F": "zhuan", "61A1": "ce", "6DFD": "zhi", "8142": "guo", "8853": "shu;zhu", "891F": "ta", "919E": "yun", "9210": "qian", "9973": "duo", "6048": "mou;mu", "6D13": "zi", "9E06": "yu", "6CF0": "tai", "7135": "gang", "7EDE": "jiao", "9C18": "none", "5CDD": "tong", "66FA": "cao", "7083": "fen", "71AE": "liao", "813A": "cui", "9EFC": "fu", "53F9": "tan", "62A6": "bing", "7E4D": "xiu", "50A7": "bin", "524D": "qian", "5787": "ao", "640F": "bo", "6730": "none", "7B7B": "gang", "5A61": "lai", "657C": "xi", "66C7": "tan", "7A40": "gu", "9709": "mei", "5F19": "wu", "7D6C": "xie", "8F3E": "zhan", "90B0": "tai", "4F58": "she", "5D2C": "dong", "8D99": "zhao", "8EFB": "ke", "665E": "xi", "6BEB": "hao", "6E8B": "none", "7D51": "zhu", "8456": "tu", "8C9C": "qu", "99A2": "jian", "502C": "zhuo", "5CE1": "xia", "5D75": "none", "8AE2": "hun", "8D8F": "gua", "8D0A": "zan", "7F37": "xie", "6BA8": "hui", "73DB": "xiu", "772A": "bing", "8BEC": "wu", "8C8F": "bi", "61D5": "yan", "639F": "ding", "7A18": "ji;qi", "7602": "ya", "7772": "xing", "7B73": "ting", "7E26": "zong", "9222": "nie", "96BF": "yi", "59FC": "chi", "6FEC": "jun", "7539": "ping", "89B0": "qu", "5048": "jie", "6253": "da", "6311": "tiao", "64D3": "kuai", "69E3": "qi", "8AB8": "xuan", "900A": "xun", "676A": "miao", "83E5": "xi", "4FBD": "nan", "52CA": "ke", "5838": "feng", "76F9": "dun", "7C2B": "xiao", "7E4B": "xi;ji", "840C": "meng", "8DCF": "jia", "5BE6": "shi", "6050": "kong", "7E21": "zai", "9020": "zao", "91B4": "li", "544F": "sheng", "8FE9": "er", "928A": "xu", "86E3": "ji", "8AD2": "liang", "9BE2": "ni", "9C86": "ping", "52E2": "shi", "5EF6": "yan", "6990": "zhan", "8F3D": "ben", "95FB": "wen", "6159": "can", "6338": "jian", "8877": "zhong", "92A0": "lao", "93D4": "yin", "9D7E": "kun", "6A4E": "fan", "8908": "chong", "8F36": "you", "9ECD": "shu", "5316": "hua", "67CE": "fu", "6C54": "qi", "8111": "nao", "926A": "di", "9D37": "lie", "9E79": "xian", "53CE": "shou", "6055": "shu", "4FDD": "bao", "5E4D": "dao;tao", "5CA0": "ju", "61D1": "men", "6242": "dian", "9843": "yan", "9C58": "xun", "9D4B": "ji", "686F": "ting", "773E": "zhong", "86A3": "gong", "5177": "ju", "691C": "jian", "7A89": "bing", "8290": "xia", "83A3": "wang", "88AD": "xi", "9E53": "yuan", "9E71": "hu", "694D": "ben", "9ADD": "lao", "686D": "zhen", "74AE": "tan", "7C74": "di", "94BE": "jia", "9639": "qu", "9CB7": "diao", "5374": "que", "55EF": "ng", "6893": "zi", "6C75": "gan", "71C9": "dun", "9D90": "shu", "5900": "shou", "6CD7": "si", "7E2F": "yin", "94A8": "wu", "561B": "ma", "5EDF": "miao", "632F": "zhen", "6B2E": "jue", "6D00": "zhou", "6EF0": "jiang", "7246": "qiang", "776D": "zhou", "7D6A": "yin", "8CA0": "fu", "574A": "fang", "5EE8": "xie", "6B53": "huan", "66E7": "rong", "6EB0": "yi", "7807": "min", "84B1": "pu", "5260": "qing", "54C0": "ai", "804D": "ning", "9076": "rao", "91A0": "ang", "67D3": "ran", "7147": "hui", "782D": "bian", "78A2": "tuo", "8D20": "yuan;yun", "98A2": "hao", "9B2F": "chang", "56B3": "ku", "7343": "dai", "8003": "kao", "644B": "sha", "66F7": "he", "998E": "bo", "73CA": "shan", "75EC": "yi", "7A76": "jiu", "8034": "zhe", "9B92": "fu", "5149": "guang", "684A": "juan", "7449": "min", "990E": "le", "4F77": "heng", "675C": "du", "7CA0": "hong", "8C9F": "yuan;yun", "9E69": "liao", "5E84": "zhuang", "6206": "gang;zhuang", "83CD": "nie", "784E": "xing", "8237": "xian", "8ED5": "shan", "9E84": "cu", "5990": "zhong", "8389": "li", "87DC": "jiao", "5A91": "zhong", "5CC3": "xue", "76EE": "mu", "780C": "qi;qie", "78E7": "qi", "822D": "bi", "8ABC": "yi", "9549": "ge", "9899": "yong", "5085": "fu", "6365": "wan", "5583": "nan", "5AD2": "ai", "6376": "chui", "6E58": "xiang", "9A71": "qu", "6B1E": "ling", "902C": "beng", "4E97": "sui", "546F": "ping", "6D49": "shi", "7216": "long", "85B8": "piao", "885A": "hu", "4E74": "xi", "5FE2": "wu", "762F": "cu", "8281": "jiao", "8817": "zhuo", "50FB": "pi", "5F10": "er", "6AC0": "qi", "7191": "lian", "4EC5": "jin", "54D7": "hua;ye", "57BC": "yi", "6F33": "zhang", "80D9": "zuo", "8178": "chang", "828C": "yu", "8524": "mi", "8F67": "ya;zha;ga", "5FD2": "te;tui;tei", "67A6": "lu", "83EB": "jin", "9312": "a;e", "63DC": "yan", "650A": "lue", "6672": "yi", "6964": "song", "506D": "mian", "5B23": "ning", "85A3": "gu", "8923": "rong", "998D": "mo", "5DC6": "ying", "7217": "yan", "7454": "quan", "7B24": "tiao", "8275": "ping", "9D6F": "bei", "5AB6": "rong", "783D": "none", "7A7C": "sen", "9A8C": "yan", "5C8F": "wan", "691D": "gui", "8A9A": "qiao", "9E3B": "heng", "9F49": "nang", "6AE6": "none", "923D": "bu", "93F5": "hua", "5B09": "xi", "606F": "xi", "806C": "weng", "87F1": "wu", "88B8": "cun", "89F6": "zhi", "5F35": "zhang", "6009": "bao", "776E": "yu", "51ED": "ping", "6EEC": "hu", "8F99": "zhe", "78F1": "lao", "81D3": "zang", "94D6": "cheng", "9EEB": "yin", "52D5": "dong", "7F18": "yuan", "8991": "pian", "8D0E": "wan", "8EA2": "ta", "93DB": "chang", "5874": "beng", "58E8": "lei", "6077": "none", "6D60": "xi", "81AE": "xiao", "9ACB": "kuan", "5810": "ya", "6202": "mi", "6632": "fei;fu", "7420": "dian", "7861": "hong", "838C": "duo", "9BCB": "sha", "6709": "you", "6A39": "shu", "8D57": "feng", "5003": "zan", "65BE": "pei", "6691": "shu", "6824": "bing", "87D4": "mo", "9C96": "tong", "9DC9": "ti", "6895": "ren", "75D2": "yang", "7CA2": "zi;ci", "7FE4": "chi", "6397": "ya", "6CDE": "ning", "8B78": "zhou", "8E61": "qiang", "8EBD": "yan", "632C": "bo", "87FA": "shan", "5150": "er", "541A": "yi", "801E": "jia", "80A2": "zhi", "8725": "xi", "8F6A": "dai", "9298": "ming", "52CC": "juan", "631F": "xie;jia", "6ACC": "you", "6DB8": "he;hao", "7374": "meng", "7535": "dian", "7BB6": "hu", "7E63": "hua", "94B1": "qian", "966D": "yi", "9A94": "zong", "57DB": "jiong", "65D9": "fan", "6B87": "shang", "6E9E": "sao", "6EDE": "zhi", "71B7": "zeng", "7795": "zhang", "84DB": "ce", "8593": "shen;can;cen", "8935": "li", "8AE8": "fu", "959B": "peng", "655B": "lian", "7631": "yi", "83D7": "chou", "8AD7": "shen", "8FA8": "bian", "57D3": "lie", "57D9": "xun", "70D7": "kai", "7D3D": "tuo", "7FF9": "qiao", "8658": "cuo", "8C60": "cu", "932F": "cuo", "937F": "zi", "58C8": "lan", "5B46": "ying", "7B21": "qie", "80DD": "zhi", "8F42": "gu", "5038": "cai", "5232": "kui", "53DC": "sou", "56F7": "jun", "7441": "mao;mei", "7857": "qiao", "8EB6": "luo", "91AF": "xi", "9F8F": "gong", "4E78": "na", "4F72": "ming", "88CC": "jia", "8C48": "qi;kai", "5C69": "jue", "5DAE": "xian", "672F": "shu;zhu", "7A5D": "none", "7D8B": "hong", "825E": "yao", "82A9": "qin", "8472": "quan", "94B2": "zheng", "54C8": "ha;ka", "5794": "yin", "627B": "zi", "744D": "huan", "8CDB": "zan", "4FDC": "ping", "5670": "yong", "6CF2": "ji", "7AC4": "cuan", "88FF": "qi", "550E": "li", "5780": "hu", "6A72": "none", "7C6E": "luo", "839B": "ting", "8648": "xiao", "865C": "lu", "9254": "za", "6F6B": "wan", "802C": "lou", "940F": "zun", "4E61": "xiang", "6B71": "zhong", "7DE5": "bao", "82F4": "ju", "8771": "meng", "5128": "zhi", "5696": "hui", "62A2": "qiang", "677D": "chou", "693B": "yan", "719D": "lu", "729B": "li", "7920": "zi", "8504": "man", "939F": "sang", "4F5D": "gou", "664C": "shang", "99D5": "jia", "4EB9": "wei", "5B5E": "xin", "7B92": "zhou", "88FC": "ti;xi", "9B99": "ta", "5140": "wu", "523D": "gui", "5C7E": "shen", "8830": "rang", "9A16": "wu", "558D": "chai", "5B28": "ci", "624E": "zha;za", "66EE": "yan", "7BFC": "dou", "7D96": "yan", "85C7": "xu", "9794": "man;wan", "4EDE": "ren", "574E": "kan", "5D34": "wei;wai", "604D": "huang", "826A": "lu", "8DC4": "qiang", "4F39": "qu", "5A4E": "hui", "5BCD": "ning", "6139": "yong", "65BB": "hang", "67BE": "shi", "71FC": "jin", "9C17": "hu", "9D6A": "an", "9EEE": "tan", "4FD5": "san", "5122": "lu", "5BAC": "cheng", "5CEB": "ye", "6488": "lao", "5E17": "fu", "6E4C": "can", "82C3": "you", "84CC": "cuo", "8B05": "zou;zhou", "8D9E": "que", "996A": "ren", "99E2": "pian", "7CEC": "shu", "8214": "tian", "8B8B": "zhe", "9F31": "jing", "4E99": "gen;geng", "4EF2": "zhong", "67DD": "tuo", "6A1F": "zhang", "8C45": "long", "9D09": "ya", "9F03": "wa", "9F7F": "chi", "669C": "pu", "7B53": "ji", "7E4A": "xian", "7E90": "none", "7F95": "yang", "842F": "fu", "8CAA": "tan", "8E26": "qi", "9569": "cuan", "96A2": "rao", "50C5": "jin", "7356": "ben", "8B5A": "tan", "8C09": "shen", "6BB7": "yin;yan", "7E66": "qiang", "8F6C": "zhuan;zhuai", "9300": "lun", "74C5": "li", "75FE": "e", "87E0": "pan", "9954": "yong", "5266": "yan", "5749": "dun", "5976": "nai", "5CD6": "an", "7FC7": "fu;pei", "8501": "zhang", "595D": "diao", "5CC4": "yi", "8137": "li", "9413": "dui;dun", "9BED": "meng", "9EE3": "mei", "9F7A": "zou", "573B": "qi;yin", "630B": "zhen", "78FF": "li", "7B50": "kuang", "89C4": "gui", "5089": "ru", "5677": "xin", "7C5C": "tuo", "7DAD": "wei", "7E55": "shan", "835E": "qiao", "865D": "hu", "95DD": "piao", "6A25": "peng", "70D9": "luo;lao", "7D69": "tiao", "552B": "yin", "5FE8": "wan", "772F": "mi", "7CCF": "xie", "9AA2": "cong", "7D49": "shu", "7E3E": "ji", "87F0": "xiao", "8A4A": "pan", "9A65": "ji", "5936": "bi", "712D": "qiong", "9E32": "qu", "5C6B": "jue", "805E": "wen", "6B56": "xi", "78E5": "lei", "79A8": "ji", "7FFC": "yi", "81E0": "luan", "8FD0": "yun", "9BEE": "zong", "4F44": "han", "68F8": "zou", "7041": "yuan", "709B": "xin", "856C": "si", "88A5": "none", "56D6": "none", "7315": "mi", "9DB4": "he;hao", "53C8": "you", "81B1": "zhi", "85B2": "pin", "8610": "xuan", "9862": "man", "4EAA": "none", "5E55": "mu", "726E": "jian", "936C": "qiao", "50C9": "qian", "5993": "ji", "8DB5": "bao;bo", "9097": "han", "9B6E": "pi", "7459": "nao", "7485": "suo", "89A6": "yu", "8C84": "si", "4FB9": "ting", "5AF9": "mao", "7561": "gai", "7862": "yu", "86C5": "ran", "4F4A": "bi", "6E06": "yuan", "79AA": "chan;shan", "8751": "xu", "8839": "du", "99DB": "shi", "5F1E": "shen", "6FB1": "dian", "9656": "jun", "9E2A": "gu", "4E56": "guai", "59C5": "ban", "71F1": "yi", "5245": "lou", "6514": "lan", "6BFA": "yu", "7395": "gan", "7921": "bo", "7C56": "qian", "5E34": "sha", "6BAC": "du", "76C9": "he", "7D3E": "zhen", "8A1B": "e", "690A": "zuo", "6E5A": "yin", "92DD": "lue", "9415": "zan", "941F": "ti", "9CF7": "zhi", "7050": "none", "7182": "xi", "7379": "lu", "9858": "yuan", "50CF": "xiang", "750D": "meng", "7803": "dan", "82FD": "gu", "9378": "hu", "528D": "jian", "5AA8": "jiu", "5CE6": "luan", "689E": "ji", "7FB0": "tang", "8ACA": "ju", "9B1D": "qian", "5BC8": "qing", "715A": "jiong", "751F": "sheng", "7AD9": "zhan", "7F4A": "qing", "8A08": "ji", "9D80": "qi", "5BC7": "kou", "7AEA": "shu", "8045": "che", "8727": "li", "8E5B": "dai", "923E": "you", "6073": "ken", "65FD": "tun", "733D": "ming", "7E14": "shuang", "59B4": "yuan", "6336": "ju", "6F70": "kui;hui", "9407": "fan", "9ABE": "geng", "533A": "qu;ou", "5D7A": "liao", "6445": "shu", "6C82": "yi", "7930": "li", "91CE": "ye", "558A": "han", "610F": "yi", "6CC6": "yi", "7A8F": "wu", "5C99": "ao", "6842": "gui", "8BCF": "zhao", "995A": "hai", "6EA1": "shi", "8276": "yan", "4E01": "ding;zheng", "56BD": "chuo", "647D": "biao", "6E2D": "wei", "81B8": "sui", "878D": "rong", "89DA": "gu", "71BA": "xi", "72A7": "xi", "8211": "tan", "86BC": "gou", "8B76": "ta", "8B85": "shen", "8E79": "ta", "5538": "nian", "7CBE": "jing", "819E": "zhuan", "82AF": "xin", "8F18": "ling", "95BF": "wen", "5640": "xun", "5B98": "guan", "6A38": "pu;po", "7F41": "gang", "9543": "zi", "5366": "gua", "5AF4": "gu", "5DF9": "jin", "605B": "hui", "7583": "tuan", "92DB": "gong", "5D7C": "chan", "60E1": "e;wu", "884B": "shi", "88BE": "zhu", "9D07": "bao", "5A87": "qin", "6129": "gong", "7AD4": "gong;sheng", "7D0C": "qiu", "7F2C": "xie", "7F32": "qiao;sao;zao", "9DF2": "jiu", "4F08": "xin", "4FB0": "jiong", "5321": "kuang", "5464": "ling", "5F34": "diao", "6541": "dian", "6A90": "yan;yin", "84C9": "rong", "8FC5": "xun", "9107": "hou", "95F4": "jian", "9632": "fang", "53A1": "yuan", "56F5": "lun", "7E58": "yu", "8C24": "bang", "53B7": "si", "5A95": "an", "692D": "tuo", "7A3B": "dao", "81E2": "za", "86C3": "bing", "9258": "fu", "9561": "chan;xin;tan", "517E": "ji", "54B6": "huai", "55E8": "hai;hei", "5B99": "zhou", "7B22": "min", "9F8C": "wo", "4ECE": "cong", "6A54": "tui", "8996": "shi", "9EB2": "xian", "64C7": "ze;zhai", "6B89": "xun", "6CB7": "fu", "6CE1": "pao", "7397": "yu", "7552": "mu", "81E9": "guang", "964C": "mo", "9A12": "sao", "9BD7": "xiang", "9F51": "ji", "51FB": "ji", "54AC": "yao", "63A4": "bing", "657A": "qu", "6DDF": "tian", "74DB": "huan", "763A": "lou", "77B8": "ye", "7F88": "ji", "9ACF": "lou", "6026": "peng", "6721": "zong", "8084": "yi", "8361": "dang", "8651": "lu", "9823": "shen", "5090": "hao", "5E4C": "huang", "5E89": "dun", "7403": "qiu", "74E8": "jiang;hong", "9129": "xin", "4EFC": "wang", "9507": "e", "4F1C": "cui;zu", "59A8": "fang", "6049": "zhi", "61E8": "yan", "622A": "jie", "7DBD": "chuo", "8039": "qin", "966C": "zou", "684C": "zhuo", "6891": "di", "791F": "pao", "7A46": "mu", "8C0B": "mou", "8E67": "zao", "8F22": "yi", "9322": "qian", "9BF4": "shi", "6A23": "yang", "6FB8": "dan", "838D": "qiu", "8B99": "huan", "8BFA": "nuo", "4FEE": "xiu", "6F20": "mo", "7285": "gang", "7335": "bian", "77D8": "tang", "794E": "yi", "9278": "jiao", "4F3D": "jia;ga;qie;qia", "6A5D": "tan", "8291": "qi", "9683": "yu", "537C": "wu", "54E0": "hao", "5895": "yan", "6C32": "yun", "75D6": "ya", "7DC1": "jie", "94ED": "ming", "7619": "sao", "9291": "xian", "598E": "xie", "5E86": "qing", "6942": "zha;cha", "82D1": "yuan", "62E8": "bo", "6E6C": "jiao", "5ADA": "man", "6BFB": "tuo", "6CE6": "ju", "7C6C": "li", "7E6D": "jian", "8FE2": "tiao", "927E": "mou", "9573": "biao", "9613": "hui", "9A18": "cong", "9DE9": "bi", "5170": "lan", "5D0C": "ju", "74AC": "jiao", "7C42": "none", "992F": "hui", "9CFB": "fen", "51A1": "meng", "8642": "lu", "948C": "liao", "4F47": "zhu", "510D": "sha", "5FED": "bian", "7708": "dan", "7BA6": "ze", "7F6D": "yu", "8466": "wei", "8981": "yao", "956E": "huan", "6640": "tiao", "817A": "xian", "8A30": "zhun", "6E9B": "wa", "7A83": "qie", "5CBE": "none", "7A7A": "kong", "9361": "wei", "9961": "zuan;zan", "999B": "ba", "5738": "none", "5AC2": "sao", "771C": "mo", "77AF": "xian", "9040": "sui", "6567": "qi", "6601": "bei", "79A5": "qi", "6A7B": "none", "6B45": "yin", "6D89": "she", "86A4": "zao", "89B1": "zhan", "8EDA": "dai", "8D12": "xian", "8C08": "tan", "9BC9": "li", "6398": "jue", "7815": "sui", "7A35": "zi", "9164": "gu", "9B30": "yu", "9CAB": "ji", "5841": "lei", "5E56": "biao", "63E4": "ji;jie", "6B09": "cong", "6C61": "wu", "7405": "lang", "4EB3": "bo", "563B": "xi", "7526": "su", "8005": "zhe", "5208": "yi", "90E5": "bei", "66D9": "shu", "74CD": "sui", "7C0F": "lu", "84EF": "cong", "6164": "que", "908E": "you", "90D1": "zheng", "93CB": "man", "9CA2": "lian", "5BA1": "shen", "60AF": "min", "6B1C": "nang", "745F": "se", "5D2D": "zhan", "72E8": "rong", "7457": "yuan", "79E2": "ling", "8235": "duo;tuo", "889A": "bo;fu", "8AA6": "song", "60BA": "guan", "7281": "li", "73C2": "ke", "759A": "jiu", "75BB": "zhi", "7976": "di", "858D": "luan", "909D": "kuang", "5EFB": "hui", "66C3": "dai", "8C06": "zhun", "4E9C": "ya", "6BC8": "duan", "71E9": "que", "84D7": "zong", "8695": "can;tian", "92C1": "lu", "9AC3": "yu", "75C1": "dian", "7A02": "lang", "82C5": "yi", "830F": "long", "8357": "rong", "936D": "hou", "4F2C": "chi", "552F": "wei", "571E": "luan", "6DED": "qu", "9BE7": "chang", "6843": "tao", "6DB4": "wan", "77E9": "ju", "97AF": "jian", "4FED": "jian", "5568": "qing", "88BD": "ru", "8E5A": "tang", "9520": "chang", "53AF": "li", "57D0": "jin", "6CCB": "hui", "72CB": "ni", "8335": "yin", "9251": "bo", "970D": "huo", "60C6": "chou", "6304": "kuo", "7A58": "xiao", "7C62": "lian", "8B40": "han", "55A1": "wei", "5D47": "ji", "5ED5": "yin", "6C68": "mi", "7EC7": "zhi", "8A3D": "gou", "9969": "xi", "80F1": "guang", "8543": "fan;bo", "511D": "qiong", "6BC6": "ou", "6F1F": "tang", "7667": "li", "7939": "yan", "8216": "pu", "848C": "lou", "9194": "qiu", "9A2F": "pang", "6132": "gu", "6855": "jiu", "7B87": "ge", "6586": "xiao", "6612": "hu", "7FE9": "pian", "8A97": "chan", "8D47": "qiu", "5221": "min", "5A92": "mei", "6141": "hun", "7B2D": "ling", "8814": "hao", "562E": "lao", "5FCA": "ding", "61C2": "dong", "76B4": "cun", "8671": "shi", "8E54": "zhan", "9B4D": "wang", "9E6A": "jiao", "9F06": "mang", "4E3E": "ju", "5241": "duo", "5721": "tu", "711D": "hun", "7B67": "jian", "8565": "ya", "8F6E": "lun", "9AAB": "wei", "5027": "zong", "6ECD": "zhi", "8154": "qiang", "9D21": "ju", "6116": "chen", "6834": "zhan", "7337": "you", "9443": "diao;yao", "4EE0": "gan", "56EE": "e", "5AC7": "ming", "8495": "yun", "84A1": "bang;pang", "616F": "shang", "81C6": "yi", "8382": "bie", "848E": "pai", "9038": "yi", "9439": "guo", "9F77": "wo", "7751": "jian", "7ECB": "fu", "8298": "bi;pi", "59A0": "na", "6AEF": "su", "76FA": "xin", "83E1": "han", "8C85": "xiu", "9A81": "xiao", "9CC5": "qiu", "5246": "luo", "5E54": "man", "668D": "he", "6F29": "xuan", "879E": "ma", "8FE4": "yi", "97F7": "luo", "9D36": "ji", "4F74": "nai;er", "6589": "qi;ji", "688E": "ao", "7A74": "xue", "83C3": "qu", "86CC": "gu", "88C6": "dang", "528B": "jiao", "58CD": "qian", "602D": "bi", "7D4B": "kuang", "8591": "jiang", "8D95": "gan", "9475": "guan", "9AE4": "xiu", "6883": "ting", "583B": "zhen", "8D32": "bi;ben", "51D7": "cui", "5535": "an", "58BC": "ji", "6865": "qiao", "6B67": "qi", "6C80": "xu", "6E4E": "mian", "938D": "suo", "9E87": "jun;qun", "5099": "bei", "50FF": "sai", "6755": "di", "6D2B": "xu", "982E": "hui", "50F7": "ye", "5DE0": "jing", "6496": "han", "70CE": "yin", "7386": "zi", "87AC": "cao", "9CB3": "chang", "50C4": "piao", "6646": "kui", "6CFD": "ze", "8629": "fan", "8DBE": "zhi", "91DC": "fu", "4EB5": "xie", "6653": "xiao", "6E36": "ying", "518B": "jiong", "6CE9": "sheng", "7122": "hong", "92F3": "zhu", "6415": "ke", "7836": "po", "5C88": "ya", "6966": "xuan", "8261": "dang", "860F": "jiong", "8FBF": "chan", "52F7": "rang", "5660": "da", "6170": "wei", "7AA0": "ke", "5519": "di", "56CC": "su", "5B8F": "hong", "7218": "none", "7F40": "none", "7FE1": "fei", "8351": "ti;yi", "5B93": "mi", "754F": "wei", "88C7": "none", "97DA": "ge", "99F3": "dan", "9E14": "bo", "5005": "cui", "557E": "jiu", "7AC9": "zao", "7FB6": "shan", "8C10": "xie", "90D9": "fu", "9CE4": "guan", "51A2": "zhong", "5FBD": "hui", "74C1": "huo", "7B0E": "yuan", "815C": "mei", "8715": "tui", "8757": "huang", "8AB4": "cong", "8B34": "guan", "525F": "duo", "8CF1": "yun", "8D0D": "shan", "919C": "chou", "9810": "yu", "9B79": "none", "7DE8": "bian", "8398": "xin;shen", "9218": "yi", "552D": "qi", "67DC": "ju;gui", "7746": "huan", "9CC0": "ti", "5172": "tian", "5932": "ben;tao", "71E6": "can", "74B5": "yu", "8422": "none", "8ECF": "yue", "98DE": "fei", "5FD0": "tan", "64E6": "ca", "658C": "bin", "6A0E": "suo", "771D": "zhu", "7C05": "chan", "7FF3": "yi", "949D": "dun", "6363": "dao", "647F": "yin", "7C52": "zhou", "7E6C": "se", "9BB5": "duo", "4E71": "luan", "5ECB": "sou", "533B": "yi", "6ED4": "tao", "78CD": "xia", "815B": "wu", "5B84": "gui", "87A6": "none", "9E6D": "lu", "50BF": "yan", "5F32": "xuan", "69F9": "gao", "77B5": "lin", "8159": "zong", "77CA": "mian", "7A6E": "biao", "8BBA": "lun", "8E96": "duan", "904F": "e", "928F": "shan", "9658": "xing", "58D5": "hao", "84CE": "tang", "8691": "qi", "9508": "xiu", "9C6A": "none", "887F": "jin", "8F27": "ping", "56B7": "rang", "6361": "jian", "647B": "chan;shan", "6A02": "le;yue", "7BA5": "bo", "889C": "wa", "8918": "hui", "8C28": "jin", "5250": "gua", "61CB": "mao", "6C8D": "hu", "8166": "nao", "8146": "tian", "872E": "yu", "6792": "ya", "9851": "kan", "9A3B": "shuang", "7240": "chuan", "7827": "zhen", "807C": "ting", "86D6": "mang", "94A1": "bei", "9566": "dun;dui", "9B24": "rang", "56A3": "xiao", "7202": "biao", "7430": "yan", "75DA": "xiao", "78B8": "feng", "794D": "none", "52AF": "zhu", "539B": "ting", "7309": "qi", "8FAE": "bian", "928B": "ren", "6681": "xiao", "71A2": "feng", "7304": "jing", "7DF3": "jie", "8896": "xiu", "8A40": "zhan", "8D0F": "ying", "9072": "chi", "97B2": "gou", "504D": "ti", "5257": "chan", "8F5E": "xian", "93BE": "none", "4F75": "bing", "51B3": "jue", "5C59": "e", "5FC8": "ren", "926F": "yi", "9D1C": "zi", "6D28": "xiao", "7B49": "deng", "868B": "rui", "972D": "ai", "56CD": "xi", "5774": "liu", "717E": "yun", "853E": "li", "95CB": "que", "992C": "hu", "5115": "chai", "6D3B": "huo", "7223": "tang", "8FD4": "fan", "50D5": "pu", "59E5": "lao;mu", "60E5": "yong", "6373": "yue", "78E8": "mo", "8B5D": "sheng", "8C2C": "miu", "9D41": "jiao", "5E67": "qiao", "72FD": "bei", "7D7B": "mian", "832A": "guang", "8CDF": "tian", "7303": "xian", "825C": "dai", "97F0": "xie", "537D": "ji", "53E4": "gu", "56F6": "guo", "5E42": "mi", "7C6A": "duan", "7D68": "rong", "8483": "zhuan", "9403": "nao", "5E6D": "mie", "7329": "xing", "7492": "deng", "7C3F": "bu", "8569": "dang", "9DEF": "liao", "8B2A": "shang", "9F0A": "bi", "5DDE": "zhou", "8438": "yu", "88FD": "zhi", "8EC5": "none", "8F1B": "liang", "9EA8": "chao", "4F45": "mai", "552E": "shou", "7700": "ming", "8611": "mo", "8CCD": "zang", "9435": "tie", "9588": "han", "4FD9": "xi", "5BF1": "yi", "5D3D": "zai", "7181": "xie", "94C4": "shuo", "9BA5": "luo", "592E": "yang", "6F76": "hei", "7E41": "fan;po", "82A7": "zhu", "82E1": "yi", "8C4B": "deng", "9115": "xiang", "5054": "e", "79E3": "mo", "7BCB": "qie", "7EB8": "zhi", "80D1": "zhi", "8804": "qin", "4FA7": "ce;ze;zhai", "6FC6": "fen", "8EA1": "nie", "5C2D": "yao", "6A2C": "cong", "6BF5": "san", "9160": "qia", "7E5F": "chan", "9AF3": "mao", "93A5": "tiao", "6F1E": "mi", "7AB0": "yao", "7DEF": "wei", "8978": "zan", "8BDA": "cheng", "9BEB": "zou", "716D": "lie", "9B06": "song", "9F6A": "chuo", "60B8": "ji", "65D3": "shao", "8BFE": "ke", "5E2B": "shi", "61EE": "you", "9A6E": "tuo;duo", "4E88": "yu", "4FBE": "hao", "621F": "ji", "69D3": "gang", "6B43": "sha", "7831": "ling", "8957": "duo", "9167": "chou", "9B40": "jie", "5153": "jin", "5546": "shang", "56E0": "yin", "5C0B": "xun;xin", "7101": "none", "6518": "rang", "8188": "ge", "9392": "nou", "9DAC": "cang", "5DFE": "jin", "60D9": "chuo", "6BAF": "bin", "70C6": "xing", "73D4": "jian", "8404": "tao", "87D5": "zi", "8C6A": "hao", "9B66": "sha", "6B26": "qian", "9153": "yan", "67C3": "ling", "7860": "lang", "7E38": "mo", "855C": "fei", "9281": "jun", "974F": "he", "4F11": "xiu", "6FA7": "li", "7ADB": "ling", "7FEA": "zong", "8740": "dong", "9796": "sui", "6226": "zhan", "7DFF": "dai", "9470": "yao;yue", "9BD5": "qi", "54C3": "tong", "5DD0": "chao", "6F03": "ji", "8FD7": "e", "9230": "shi", "57FF": "ni", "91BA": "xun", "948F": "chuan", "9CA6": "tiao", "6286": "wen", "7196": "none", "78CC": "tian", "9ACD": "mo", "5DFC": "none", "6257": "zai", "9A46": "bi", "6CAD": "shu", "7580": "cha", "7E0A": "yi", "62E2": "long", "7721": "di", "7EA6": "yue;yao", "9473": "jian", "9DE2": "jue", "5C39": "yin", "82E2": "yi", "8677": "gan", "8D41": "lin", "945E": "la", "9C23": "shi", "5E2A": "zhen", "8341": "huan", "8729": "tiao", "9D53": "bo", "5169": "liang", "53E6": "ling", "5479": "yi", "58AD": "sheng", "6C4B": "zhuo", "7808": "nuo", "88C9": "ken", "9750": "bing", "9F2B": "shi", "8B7A": "ni", "63B6": "none", "6B20": "qian", "6C87": "yan", "7104": "xun", "714F": "bi", "87CC": "cong", "9495": "nu", "4F7A": "quan", "5602": "jiao", "6623": "zhen", "6A55": "cheng", "6A9E": "jia", "8F9F": "pi;bi", "4FAC": "nong", "5939": "jia;ga", "6215": "qiang", "7932": "long", "9529": "juan", "5F57": "hui", "6ACD": "zhi", "71EC": "hui", "85F6": "li", "8934": "lan", "8936": "zhe;xi", "95F5": "min", "9ED0": "chi;li", "9F3A": "lei", "56D7": "wei", "57FD": "sao", "5DDF": "huang", "6A0F": "lei", "74FF": "bu", "7E7D": "bin", "85AB": "xun", "8D96": "suo", "915E": "tai", "955F": "xuan", "9D54": "xun", "4FD1": "yong", "9665": "xian", "65E0": "wu;mo", "6EC3": "weng", "70FB": "shan", "7357": "jue", "8937": "shi", "91AB": "yi", "719F": "shu;shou", "93EC": "xia", "9484": "lan", "78E2": "qiang", "7D13": "shu", "8E1C": "leng", "5D5F": "dui", "610E": "bi", "9CDE": "lin", "50E9": "xian", "51BF": "jian", "5631": "zhu", "5C5D": "fei", "5F9F": "zhou", "68D6": "cheng", "6E1A": "zhu", "7446": "xing", "79C6": "gan", "7E37": "lu", "8AEB": "jian", "926E": "shen", "97A9": "xiao", "9838": "jing;geng", "9ADE": "zao", "9F7B": "dian", "6001": "tai", "70FE": "chi", "88F4": "pei", "97D2": "qiao", "9F24": "wen", "5D46": "ji", "6081": "juan", "6499": "zun", "64A6": "che", "7ACF": "qian;gong;sheng", "9C7E": "ji", "6760": "gang", "68E6": "cheng", "6E6D": "none", "8833": "ying", "5825": "mao", "6988": "lu", "70D2": "shi", "723C": "zu", "8C53": "yan", "4E3C": "jing;dan", "9356": "chen", "592A": "tai", "85AD": "bai", "91B6": "yan", "565A": "xun", "929B": "xian", "94B3": "qian", "5109": "jian", "5F6B": "diao", "605D": "jia", "7665": "zheng", "7E91": "lu", "921A": "pi", "58C5": "yong", "5952": "kai", "67F4": "chai", "7282": "li", "8D87": "se", "914E": "zhou", "56D4": "nang", "6537": "kao", "9BE5": "lu", "5058": "kan", "5F91": "jing", "64B0": "zhuan", "8CAB": "guan", "7413": "wan", "8097": "ru", "80E7": "long", "6D26": "po", "75F8": "chi", "80A8": "pang", "81E1": "ni", "9B39": "gui", "57BF": "xu", "6909": "cheng;sheng", "98E2": "ji", "9B16": "san", "5210": "dan", "561E": "lei", "68FE": "qiong", "6C15": "pie", "6EBD": "ru", "6F47": "xiao", "7C54": "sou", "8296": "zhi", "8C44": "du", "93EA": "cao", "9B60": "tuo", "5520": "lao", "5AF5": "wu", "69DE": "long", "6B02": "bo", "6C66": "chi", "721E": "tong", "7F43": "ying", "8213": "shi", "5489": "bi;fu", "55F3": "ai", "58F3": "qiao;ke", "6AF8": "ju", "7434": "qin", "77EA": "zhou", "80EC": "nu", "5490": "fu", "6F2B": "man", "7A6C": "gong", "8E6C": "deng", "9314": "ta", "9491": "sa", "996F": "jian", "52E9": "yi", "54FE": "shuo", "6C06": "pu", "71C2": "qian", "878E": "rong", "9602": "he", "56B9": "la", "5A24": "zhuang", "5F41": "none", "6B23": "xin", "6F95": "he", "75D3": "chi", "7F9B": "yi", "5E7A": "yao", "633F": "cha", "6456": "qi", "66D4": "jing", "783E": "li", "942C": "hui", "9694": "ge", "96F0": "fen", "5387": "zhe", "78D2": "yun", "876A": "tang", "91BD": "ling", "82B0": "ji", "91A6": "lao", "7BF0": "bu", "7E17": "shuai", "858B": "ci", "86E1": "yi", "83B0": "kan", "94A7": "jun", "5021": "chang", "52A6": "xie", "6312": "lie", "6ABB": "jian;kan", "75E1": "pu", "7D4D": "ren", "820F": "jiu", "8C56": "chu", "7A84": "zhai;ze", "8675": "she;yi", "8EB9": "ju", "9ABD": "tui", "9BB1": "none", "5CC5": "none", "607A": "kai", "60F5": "die", "7F92": "fen", "935C": "xia", "9807": "han", "5447": "qi", "5D5D": "lou", "5F05": "fen", "66E2": "none", "779C": "lou", "56A7": "lu", "870E": "yuan", "5566": "la", "7689": "ci", "79FD": "hui", "911D": "liao", "58ED": "none", "687D": "wen", "9253": "chi", "9ED3": "yi", "53F5": "po", "5D50": "lan", "5FA5": "chi;shi", "826B": "lu", "9728": "wei", "9BFF": "bian", "68CE": "chan", "8968": "none", "9CE7": "fu", "5984": "wang", "6327": "none", "6C4D": "wan", "7F62": "ba", "8545": "ou", "8635": "zhi", "8C95": "xi", "8FEC": "wang", "9C04": "wei", "7D95": "zhi", "97F5": "yun", "9887": "po", "6EBE": "wei", "9DDA": "liao;liu", "5CFD": "xia", "7592": "chuang", "773C": "yan", "87B0": "lu", "8AC5": "ji", "5933": "tai", "60B9": "guan", "71B0": "ou", "7A9E": "dan", "9140": "yan", "9AAD": "gan", "50F1": "gu", "730A": "ni", "90F7": "xiang", "9F66": "yin;ken", "4FFB": "bei", "59F0": "jun", "635A": "zhai", "6DB7": "dong", "7079": "zha", "7BB8": "zhu", "7D2D": "hong", "8046": "ling", "8E64": "zong", "9379": "xuan", "93BC": "none", "5B78": "xue;xiao", "61B2": "xian", "6ECE": "ying;xing", "7006": "du", "7139": "none", "7A99": "xiao", "8A67": "cha", "8CEE": "jin", "8D84": "ju;qie", "97D3": "han", "9E39": "gua", "9EB7": "feng", "51DD": "ning", "5513": "che", "6EA2": "yi", "7465": "wen", "82DE": "bao", "8951": "xin", "91FB": "none", "947B": "pan", "60D4": "yan", "6CDC": "zhi", "7054": "yan", "9AB0": "tou;shai", "646C": "ying", "66BF": "xi", "81EF": "gao", "88AB": "bei;pi", "8C0A": "yi", "905F": "chi", "9DD8": "chi", "61A6": "lao", "6FBB": "sui", "7483": "li", "9E5D": "yi", "52F5": "li", "5B60": "si", "8DDD": "ju", "5CC7": "ke", "5FC0": "xiang", "62E6": "lan", "6B9E": "yun", "6D21": "lei", "6D75": "tong", "7D65": "fu", "9F94": "gong", "9F99": "long", "5020": "xu", "6252": "ba;pa", "7013": "cheng", "8AB0": "shui;shei", "8972": "xi", "94DC": "tong", "9706": "ting", "4F5B": "fo;fu", "544D": "hong", "5798": "fu", "57A3": "yuan", "614E": "shen", "6CD4": "gan", "6C5E": "gong;hong", "7761": "shui", "6B7C": "jian", "8883": "chai", "955E": "zu", "95E8": "men", "57C3": "ai", "6BD6": "bi", "858A": "ji", "9108": "kui", "92BB": "ti", "9DCC": "ma", "4E80": "gui;jun;qiu", "6C94": "mian", "96A6": "pi", "4ECD": "reng", "6E33": "mi", "9333": "meng", "6450": "chuang", "6ABE": "qing", "722D": "zheng", "7CFA": "jiu", "8EA8": "kui", "5937": "yi", "831C": "qian;xi", "834C": "an", "8B1F": "tao", "99FE": "tui", "4FAF": "hou", "5067": "zha", "53FC": "diao", "5667": "hui", "5854": "ta;da", "7406": "li", "8195": "guo", "827F": "nai", "90BC": "kuang", "90E3": "bo", "96D1": "za", "5C2A": "wang", "5EC3": "fei", "6D8A": "nian", "7072": "xiao", "97E1": "wei", "9AB7": "ku", "5D14": "cui", "7A34": "lian", "857F": "xuan", "98BB": "yao", "9904": "jia", "5C41": "pi", "68A8": "li", "72A8": "chou", "85E6": "mo", "8B9C": "dang", "9F18": "yuan", "524F": "chuan", "6406": "gou", "6E3B": "xing", "7A53": "yi", "876D": "ti", "8808": "ze", "5931": "shi", "6628": "zuo", "7F4B": "weng", "8000": "yao;yue", "85E3": "pi", "8C30": "lan", "9B6B": "shen", "5390": "pang", "60C4": "ni", "7B00": "mang", "7BBA": "chun", "8451": "feng", "8CB6": "bian", "9BAD": "gui;xie", "5E98": "ya", "6867": "gui;hui", "7CD8": "none", "81FA": "tai", "915A": "fen", "52A8": "dong", "5C1F": "xian", "64C2": "lei", "6ADE": "yuan", "6D5A": "jun;xun", "764E": "xian", "80C5": "die", "8522": "po", "929F": "cha", "57F5": "duo", "6BD0": "ai", "6FBF": "qin", "8413": "yi", "870A": "li", "88F7": "yuan", "8AE9": "pu", "94F5": "an", "989C": "yan", "9EB5": "mian", "5BF2": "yi", "7237": "ye", "748C": "yin", "7821": "yu", "4E43": "nai", "68AE": "ju", "6E39": "hong", "8723": "qiang", "8C78": "zhi", "4E37": "none", "52DA": "yi", "582A": "kan", "5F71": "ying", "63E5": "ti", "7002": "lu", "8A9B": "qin", "8F06": "kai", "90D4": "yan", "94CD": "pi", "58DE": "huai;pi", "598C": "jing", "826F": "liang", "9DEA": "ying", "5435": "chao", "4EA8": "heng", "5EEE": "ying", "601E": "zhou", "516B": "ba", "6298": "zhe;she", "97B0": "none", "56DA": "qiu", "7317": "yi", "4EB1": "ye", "4F94": "mou", "516C": "gong", "5AC8": "ying", "6B0E": "yu", "6FC4": "guo", "702D": "none", "9956": "hui", "9AEA": "fa", "9D78": "qi", "66F2": "qu", "6D4E": "ji", "81B7": "xin", "8CE0": "pei", "9259": "zhai", "999A": "fen", "5465": "ran", "5AAE": "tou", "67CC": "ci", "67F2": "bi", "7298": "ma", "7991": "wu", "84ED": "an", "968A": "dui", "5A96": "ying", "5CE9": "e", "7162": "qiong", "7A8B": "zhu", "883A": "can", "931E": "chun", "7C51": "zhuan", "9AE3": "fang", "6F38": "jian", "8DF1": "zhi", "966E": "dui", "56CA": "nang", "5FE9": "zong", "9BAF": "ge", "69EA": "gai", "6F1B": "teng", "9223": "gai", "92D6": "si", "56A8": "long", "5DDD": "chuan", "676E": "fei", "747F": "yi", "8595": "lian", "863B": "ji", "4E65": "none", "57E7": "ju", "5A7B": "nan", "5BF0": "huan", "6469": "mo;ma", "6559": "jiao", "8710": "jie", "526C": "duan", "681F": "bing;ben", "74AD": "gun", "9441": "dang;zheng", "6B54": "xu", "8E03": "xiao", "6519": "chan", "6521": "li", "741C": "lai", "7909": "he", "81C9": "lian", "8333": "jiang", "8BA4": "ren", "9037": "ti", "9462": "lu", "9610": "chan", "58A8": "mo", "5E91": "wu", "87B3": "tang", "8AEF": "chuan", "9186": "zhan", "6AD1": "lei", "74BF": "xuan", "7C47": "hao", "8D9A": "su", "9A01": "cheng", "7B23": "bao", "87A4": "yu", "8992": "mao", "9553": "jia", "977A": "mo", "9B35": "qian", "895E": "bi", "8B35": "xi", "5455": "ou", "61DC": "meng", "63C4": "yu", "7BCE": "miao", "8EEC": "fan", "665D": "zhou", "8AC2": "chan", "9AA5": "ji", "5BB4": "yan", "79C1": "si", "87FC": "jing", "8F14": "fu", "9574": "la", "9F9C": "gui;jun;qiu", "4EE4": "ling", "5086": "yuan", "5945": "pao", "691F": "du", "728B": "ju", "84A0": "xi", "569B": "hu", "6CA8": "feng", "75CF": "wei", "8CA7": "pin", "98B1": "tai", "5D99": "lin", "6173": "qian", "67E7": "gu", "6A73": "none", "8B30": "lian", "8C86": "huan", "8E34": "yong", "9839": "tui", "985B": "dian", "586F": "liu", "65C1": "pang;bang", "6BE9": "ju", "7241": "ke", "7839": "ai", "864A": "luan", "8B10": "mi", "8C4E": "shu", "56AE": "xiang", "5C80": "chu", "7CDD": "san;shen", "80E5": "xu", "93C1": "suo", "958E": "hong", "591B": "duo", "5C22": "wang;you", "5C7C": "wu", "6799": "e", "6972": "wei", "71B5": "shang", "7F46": "guan", "5192": "mao;mo", "60FA": "xing", "655F": "dian", "6B1A": "li;ji", "903D": "nuo", "96B9": "zhui;cui", "5C7A": "qi", "5F4C": "mi", "6896": "bei", "72C2": "kuang", "7696": "wan;huan", "877B": "nan", "9512": "lang", "532F": "hui", "57E5": "cheng", "5961": "ao", "7703": "yun", "84A3": "xu", "9073": "cuo", "9B31": "yu", "6616": "yan", "8518": "sen", "87C1": "wen", "8A2C": "chao", "5887": "zhang", "61A2": "xiao", "8A38": "he", "9748": "ling", "5034": "ben", "6507": "xian", "70E9": "hui", "745B": "ying", "7DD1": "lu", "9165": "su", "5D7B": "none", "66B6": "xuan", "7F3F": "hou", "8721": "la;zha", "9E88": "zhu", "4E7B": "none", "521C": "fu", "5655": "hui", "576D": "ni", "5C34": "gan", "6C3B": "le", "7DED": "wei", "8266": "jian", "8458": "zi", "8F54": "lin", "94DF": "yin", "9A0B": "lai", "4E2E": "ji", "53CD": "fan", "6E19": "huan", "71C7": "zun", "7589": "die", "8516": "cuo", "95F6": "kang", "4E45": "jiu", "6A0C": "guan", "6FBE": "ta", "81F1": "mian", "8AA9": "jing", "8DEE": "chi", "96E8": "yu", "9BF0": "nian", "5529": "wo", "6157": "chi", "6CA7": "cang", "6E7A": "yan", "6EAC": "qiang", "6F54": "jie", "74E5": "li", "940A": "yang", "9D29": "zhi", "534F": "xie", "6486": "pie", "8C67": "fu", "911C": "fu", "9A93": "zhui", "510C": "jiao", "5EA1": "yi", "6A95": "ji", "6C4C": "chuan", "7710": "zheng", "825F": "chong;tong", "840B": "qi", "88DB": "yi", "8E22": "ti", "6A57": "meng", "7675": "luan", "8813": "meng", "51D3": "li", "520E": "wen", "6A3F": "zhan", "6D79": "jia", "8051": "die", "4F68": "none", "534A": "ban", "6969": "pian", "707E": "zai", "7E2E": "suo", "8B20": "yao", "50D8": "chang", "52F9": "bao", "6DD5": "lu", "6DF8": "qing", "6E02": "wen", "7AA8": "yin;xun", "863C": "mi", "956B": "deng", "64EC": "ni", "7648": "fei", "81D7": "kuan", "8BB0": "ji", "65B6": "chu", "8598": "da", "67C0": "bi", "7731": "yi", "7AFF": "gan", "7DF6": "bian;pian", "8447": "rou", "4F8E": "mi", "55F7": "ao", "7982": "dao", "7F2B": "sao", "9856": "xin", "560F": "gu;jia", "69A0": "ming", "8AAA": "shuo;shui;yue", "9087": "er", "5471": "gua;wa", "54CD": "xiang", "55FC": "mo", "6091": "bu", "68B9": "bing", "7CF6": "tiao", "8006": "qi", "9240": "jia", "649A": "nian", "7177": "none", "905A": "chu", "9360": "huang", "978F": "gong", "5ECD": "pou", "66EA": "luo", "7215": "xie", "73F5": "cheng", "7466": "wu", "9A0E": "qi;ji", "52F2": "xun", "681B": "li", "7E67": "none", "5FD1": "te", "6A8F": "pu", "736D": "ta", "8FCC": "none", "5FD4": "qi", "8215": "dan", "893F": "cao", "926D": "tan", "9837": "han", "4E44": "none", "51DA": "jin", "6600": "yun", "688C": "tu", "6EDC": "gao", "7197": "qiang", "79C2": "ren", "7A1C": "leng", "7CF2": "li", "9E19": "yue", "530C": "ge", "5B4E": "zhu", "5E8B": "gui", "71B6": "cuan", "7DF5": "zong", "82E7": "zhu;ning", "8EC1": "lou", "9A57": "yan", "9D86": "lai", "9E20": "jiu", "56FA": "gu", "5F59": "hui", "6CBE": "zhan", "7184": "xi", "7933": "mo", "8B6F": "yi", "9C44": "zhuan", "6564": "ke", "6A42": "dian", "7C20": "fu", "800F": "er", "9E12": "yu", "54D8": "none", "5972": "che", "75F4": "chi", "764A": "yin", "8902": "gua", "8A43": "jian", "9688": "wei", "9B0A": "shun", "593A": "duo", "72FA": "yin", "7840": "chu", "79D5": "bi", "7EC4": "zu", "815F": "zhi", "9701": "ji", "53CC": "shuang", "6416": "yao", "6509": "huo", "8AE1": "shi", "8DD7": "fu", "5851": "su", "7347": "none", "7B66": "guan", "7C04": "hu", "8E12": "wo", "90E8": "bu", "536C": "ang;yang", "605F": "xiong", "6A41": "xun", "75A1": "yang", "79C5": "cha", "96BE": "nan", "61FF": "yi", "75B4": "ke", "97E7": "ren", "9A69": "huan", "6901": "guo", "6BE3": "mu", "6DEE": "huai", "7423": "pei", "7DEA": "geng", "8D14": "bi", "8D1F": "fu", "8E2D": "zheng", "92E3": "ye", "9AD7": "lu", "52E0": "lu", "634C": "ba", "92FB": "jian", "58FC": "kun", "62A7": "zhi", "6C2F": "lu", "77E2": "shi", "7D44": "zu", "898C": "guan", "89D0": "jin", "9148": "li", "4EF3": "pi", "4F63": "yong", "599B": "chi", "7121": "wu;mo", "71EE": "xie", "8225": "pa", "9E2B": "dong", "4F42": "zheng", "64D9": "ao", "666D": "zhou", "7262": "lao", "73E6": "xiang", "85BB": "zao", "94D0": "kao", "9E0B": "ning", "4F6A": "huai", "7C1F": "dian", "692A": "peng", "6C88": "shen;chen", "6D93": "juan", "84B5": "xi", "4F4F": "zhu", "5CF4": "xian", "651A": "none", "72B1": "bo", "88B5": "ren", "8BF5": "song", "9E51": "chun", "679B": "zhao", "7926": "kuang;gong", "8BCD": "ci", "9785": "yang", "9B6D": "yuan", "57E8": "lun", "5AA2": "mao", "5D77": "song", "5E22": "qia", "66A6": "li", "77A2": "meng", "6B4D": "wu", "8708": "wu", "90FB": "qiao", "6576": "zhen", "7FD6": "xi", "8C3B": "jue", "8CD9": "zhou", "961E": "le", "9EAE": "qu", "5622": "ye", "5675": "dao", "581D": "guo", "7404": "quan", "76DF": "meng;ming", "85A4": "xie", "624F": "qiu", "7FB2": "xi", "881C": "fan", "5209": "ji", "54AD": "ji", "5FAC": "pang", "7144": "zhong", "884C": "xing;hang;heng", "98B5": "shao", "55E4": "chi", "63AC": "ju", "6979": "ying", "7608": "ji;zhi", "8CBD": "yi", "96B6": "li", "7543": "xun", "77CC": "guang", "7B0C": "ya", "900C": "you", "9BCD": "meng", "4E50": "le;yue", "83BB": "none", "88E9": "gun", "95AB": "kun", "97E6": "wei", "4FF4": "jian", "7532": "jia", "87F2": "chong", "8B70": "yi", "9630": "pi", "5325": "fan", "7885": "jun", "7B8B": "jian", "82A0": "wen", "893A": "die", "9F6D": "chu", "5383": "han", "5D32": "huang", "64C9": "chuo", "70B8": "zha", "81A9": "ni", "98BA": "yang", "9ACA": "cuo", "5A37": "chui", "632D": "geng", "6CA1": "mei;mo", "8FA1": "bian", "946E": "bo", "98A0": "dian", "5F65": "yan", "80BF": "zhong", "84F9": "yu", "915B": "none", "9498": "xing", "5585": "yu", "65AB": "zhuo", "6AC4": "chun", "6AD3": "lu", "6FDC": "jin", "8A51": "tuo", "9BC2": "none", "6D70": "li", "6E05": "qing", "8B42": "chan", "9504": "chu", "70BE": "ping", "74FA": "chang", "7637": "suo", "7A7F": "chuan", "9045": "chi", "64D4": "dan", "6E56": "hu", "7103": "lang", "7C29": "lao", "93A4": "huang", "6201": "nan", "6A1E": "shu", "67EC": "jian", "8B7F": "hui", "518C": "ce", "5B83": "ta", "749D": "gui", "9DF7": "zun", "9F58": "xie", "6546": "ge", "6619": "tan", "6EE1": "man", "8D53": "geng", "9CB1": "fei", "9E03": "yi", "4FB5": "qin", "5D44": "mei", "61E6": "nuo", "55F6": "bi", "641F": "xian", "79E1": "ba", "7F35": "zuan", "8A7E": "xiong", "8F1E": "wang", "94FB": "wu", "5119": "qian", "55FB": "zhe", "56FE": "tu", "6D7A": "chong", "7487": "xuan", "7A95": "tiao", "8664": "yan", "8E3D": "ju", "5563": "xian", "5681": "di", "63C1": "zheng", "63EE": "hui", "65C5": "lu", "76CA": "yi", "79EB": "shu", "839C": "you", "8EEE": "ang", "908A": "bian", "979C": "ta", "9BE9": "lun", "9D45": "luo", "5493": "wa", "59C2": "fa", "6565": "yan", "96FD": "hang;yu", "5890": "jin", "630F": "dong", "6752": "ren", "6B77": "li", "8220": "dao", "8A8B": "ji", "4EE7": "chang", "66D1": "sen", "7A0C": "tu", "9158": "tou", "625E": "han", "63CE": "xuan", "6AB4": "huo", "7353": "ao", "6E5D": "jie", "7BD0": "none", "9F20": "shu", "4F4C": "ci", "5F1D": "ba", "6B55": "pen", "77CB": "li", "784A": "wei;kui", "5146": "zhao", "6790": "xi", "7300": "sha", "7E9F": "mi", "5824": "di;ti", "5A72": "none", "732D": "yuan", "755D": "mu", "89BB": "qu", "94B6": "ke", "98DA": "biao", "586A": "kan", "597F": "fan", "5F21": "jue", "7473": "cuo", "7AD6": "shu", "7C80": "zhang", "7D81": "bang", "8BDD": "hua", "572A": "ge", "7443": "chun", "83C0": "yu;wan", "9C40": "ji", "8019": "pa;ba", "99E3": "tao", "9E44": "hu;gu", "4E79": "gan;qian", "5188": "gang", "51D9": "duo", "6836": "none", "7152": "wei", "75F3": "lin", "7E12": "cuo", "8024": "ji", "98F4": "yi", "69AB": "sun", "7849": "lu", "7CD2": "bei", "7E42": "shuai", "8F90": "fu", "9B8D": "pi", "5EF4": "yin", "6940": "yu;ju", "7325": "wei", "7431": "diao", "7432": "bei", "8A0F": "xu", "8A78": "mi", "95DA": "kui", "9727": "wu", "4E02": "kao", "58BF": "yi", "73E2": "ken", "8A80": "er", "9098": "yu", "95AE": "ting", "59BE": "qie", "5A15": "lai", "618E": "zeng", "794B": "shu", "9CE0": "hu", "9DB6": "tang", "7ED3": "jie", "95E1": "chan", "7AC7": "dou", "9830": "jia", "9AC0": "bi", "5237": "shua", "783C": "tong", "7F04": "jian", "8EFD": "qing", "9C42": "jiang", "9EC2": "fen", "543E": "wu", "6CC9": "quan", "738E": "ding", "82E4": "pie", "8969": "shu", "64E0": "ji", "7E2A": "bi;bie", "85BA": "qi;ji", "87FE": "chan", "882C": "long", "8D82": "chen", "54B5": "kua", "56F3": "tu", "770A": "mao", "7BB2": "xian", "8D1C": "zang", "9764": "pao", "9AF6": "rong", "5575": "bo", "7BE2": "gong", "7CBC": "lin", "992B": "hun", "9B80": "tuo", "5078": "tou", "537B": "que", "66AD": "hao", "75FB": "min", "7DB0": "wan", "8036": "ye", "8231": "cang", "57A1": "fa", "5B06": "xi", "5D1B": "jue", "9971": "bao", "567C": "pi", "8734": "yi", "6B2A": "chu", "775F": "sui", "8135": "gu", "55C5": "xiu", "5A2F": "yu", "6472": "shan", "740F": "lian", "75C5": "bing", "81A6": "lin", "4FE8": "yan", "6E3C": "mei", "6F3D": "ti", "739F": "min;wen", "8072": "sheng", "96D8": "huo", "9F93": "long", "53E8": "tao;dao", "6DD2": "qi", "7FF7": "lin", "84AD": "chu", "8626": "ling", "901A": "tong", "5C20": "xian", "6C4A": "cha", "73D5": "li", "7EA5": "he;ge", "9A31": "xi", "5D3A": "yi", "7DBE": "ling", "8793": "qin", "8CDD": "chen", "9B25": "dou", "9B73": "za", "513E": "nang", "5F79": "yi", "8D71": "zou", "5FBB": "wei", "74A3": "ji", "7A79": "qiong", "83B2": "lian", "880D": "xie", "8876": "zhong", "9803": "qing", "5697": "bao", "5FB7": "de", "69ED": "qi;cu", "7DD6": "xu", "8577": "yu", "948A": "zhao", "9C93": "kao", "5533": "li", "5F55": "lu", "71C4": "yan", "7F08": "miao", "8050": "ya", "8F0D": "yu", "9524": "chui", "5D22": "zheng", "6EB7": "hun", "75F0": "tan", "7C37": "yan", "82F6": "nie", "8E2B": "pan", "9B3E": "ji", "9DA2": "yuan", "545D": "e", "65B4": "lin", "6D8F": "ting", "7883": "qing", "7CEB": "huan", "5981": "shuo", "61B1": "chou", "731F": "lie", "9260": "yang", "96B7": "li", "9E77": "ling", "9F4D": "zi;ji", "515E": "mao", "9295": "yi", "518A": "ce", "547A": "xiao", "5F96": "cong", "6114": "yin", "70CD": "xian", "8E5C": "su", "9D14": "fu", "4F4D": "wei", "7760": "juan", "8D4A": "she", "62B7": "pi", "8645": "none", "95B5": "lin", "5A64": "chou;zhou", "5AB2": "pi", "5D67": "liu", "6C7B": "hu", "78E4": "yin", "5C60": "tu", "601F": "di", "8A46": "di", "8A4C": "gan", "542D": "hang;keng", "807E": "long", "830B": "di", "846A": "ji", "88A1": "ran", "9369": "nuo", "5560": "zhe", "5580": "ka;ke", "5896": "ta;da", "72BC": "hou", "8AAC": "shuo;shui;yue", "8F43": "zhen", "9170": "xian", "6770": "jie", "6F24": "lan", "9027": "none", "5FCD": "ren", "6A75": "none", "75FD": "dui", "77C8": "mian", "788C": "liu;lu", "8A7C": "hui", "9CB8": "jing", "8889": "tuo", "9AC4": "sui", "5661": "zhan", "56C2": "xiao", "73BD": "gou", "74F7": "ci", "75BE": "ji", "7C9F": "su", "84BE": "mi", "8A28": "zhi", "9DFA": "lu", "5253": "li", "5710": "ku", "8257": "yi", "914A": "ding", "4EAC": "jing", "6040": "chi", "61A5": "lao", "703C": "rang", "8074": "ting", "9878": "han", "5D57": "sui", "68FC": "fen", "8E3B": "gua", "4E3A": "wei", "64A8": "xiao", "65DA": "piao", "7823": "tuo", "7B71": "xiao", "821C": "shun", "8990": "jue;jiao", "8F78": "zhen", "9341": "xian", "7C3D": "qian", "8F47": "jiu", "9EE7": "li", "5922": "meng", "65A5": "chi", "7BC7": "pian", "72F3": "yu", "7B25": "si", "831A": "yin", "9079": "yu", "53B8": "lin", "5572": "di", "6117": "mou", "6B74": "li", "6E23": "zha", "7698": "qian", "7716": "kuang", "7C28": "sun", "54F0": "lao", "6A5A": "su", "8652": "zhi", "8F79": "li", "93EB": "li", "6A91": "lei", "71FB": "xun", "7219": "rang;shang", "7225": "zhu", "8A79": "zhan", "9D0F": "te", "7AF3": "deng", "8E2E": "dian;die", "9C95": "er", "4FB2": "zhen", "5FE3": "ji", "6E3E": "hun", "97CE": "mei", "99E1": "ma", "65F4": "xu", "6E74": "ban", "5573": "quan", "678E": "fu", "8558": "rao", "9476": "cang", "5269": "sheng", "7331": "nao", "892E": "ying", "8B31": "lou", "96D0": "hu", "557A": "tang", "7D70": "die", "8A37": "shen", "918F": "du", "5532": "er", "6522": "zan;cuan", "6ED0": "jie", "71A4": "yi", "7B7F": "xiao", "81C3": "yong", "5633": "kui", "6255": "fu;bi", "682E": "er", "7DB1": "gang", "827C": "ting", "8542": "sheng", "892A": "tun;tui", "8BA1": "ji", "5094": "qian", "5A50": "wo", "7DF9": "ti", "836B": "yin", "5226": "jie", "62FF": "na", "8E4B": "ta", "9729": "kuo", "9A2C": "cheng", "69B9": "si", "8A2D": "she", "9C01": "quan", "4E22": "diu", "589A": "liang", "60E9": "cheng", "65D8": "zhi", "73B0": "xian", "7527": "shen", "807A": "none", "9DD9": "zhi", "5964": "pan", "5AF0": "nen", "62BC": "ya", "9035": "kui", "66CF": "xiang", "6986": "yu", "6F4E": "pi", "732B": "mao", "8530": "hu", "89C2": "guan", "8EDB": "e", "9347": "kai", "619C": "duo", "6710": "qu", "7068": "gan", "80E4": "yin", "894D": "za", "90C6": "ji", "92A6": "yin", "9B1E": "nong", "577A": "ba", "5CD9": "zhi;shi", "6A18": "tang", "6C0A": "zhan", "89D7": "zhi", "710C": "qu;jun", "8533": "qian", "817D": "wa", "9D84": "jing", "9F0C": "chao", "549E": "xian", "6402": "lou", "6C49": "han", "858E": "mie", "89AF": "gou", "9580": "men", "967E": "reng", "5227": "jie", "6A7A": "none", "7320": "none", "7C68": "lian", "997A": "jiao", "5EDB": "chan", "713D": "none", "727E": "wu", "90A9": "huo", "5A42": "mian", "6385": "qing", "69E1": "none", "6D20": "mou", "74E6": "wa", "810A": "ji", "8895": "xue", "91C6": "bian", "9949": "jin", "5AE2": "gui", "91D0": "li;xi", "5821": "bao;bu;pu", "93CE": "bi", "9924": "tan", "9F39": "yan", "5185": "nei", "8CFA": "zhuan;zuan", "995F": "xiang", "9CBE": "bi", "591E": "none", "6439": "e", "776C": "cai", "92EE": "cheng", "529E": "ban", "5BF5": "chong", "911F": "zhuan", "986D": "hong", "67C9": "fan;bian", "68E8": "qi", "77E6": "hou", "8C87": "kun", "8CFE": "ze", "8D26": "zhang", "8DC7": "yi", "925F": "pi", "9883": "hang", "9967": "xing;tang", "6A53": "shun", "8B2D": "jian", "91B2": "nong", "93FC": "suo", "9DCA": "ni", "6F64": "run", "7F39": "fou", "90D6": "dou", "642D": "da", "742D": "lu", "7B11": "xiao", "83EE": "geng", "8D5C": "ze", "915D": "yun", "9293": "quan", "5A05": "ya", "5C02": "zhuan", "8B8E": "chou", "8C2A": "zhe", "9357": "ti", "5368": "xie", "6AB0": "mian", "74D1": "li", "80A9": "jian", "8FB7": "none", "7EAD": "yun", "8279": "cao", "94C0": "you", "968E": "jie", "9D06": "zhen", "5946": "juan", "5C32": "gan", "63A7": "kong", "8038": "song", "9CEB": "yan", "5D2E": "gu", "6549": "mi", "7531": "you", "7DAC": "shou", "8805": "ying", "6590": "fei", "67A3": "zao", "6AC8": "deng", "9B7B": "xia", "4F21": "che", "557F": "dan", "5823": "yu", "7323": "zong", "7D36": "qu", "8663": "bao", "8B09": "none", "5069": "fu", "7A62": "hui", "5FEF": "chi", "5396": "pang", "6290": "na", "71DC": "men", "7D85": "qin", "8540": "ji", "9111": "zi", "9DA0": "yan", "7E19": "rong", "85F8": "zhu", "8973": "xian", "935B": "duan", "4F82": "tuo", "56DF": "xin", "8EF3": "pao", "95FE": "lu", "56F8": "ri", "5DEB": "wu", "65CE": "ni", "6F46": "ying", "7137": "pi", "7C5F": "lai", "8CD7": "chuan", "9CF3": "feng", "53A4": "li", "6AFE": "you", "6E04": "fei", "71CE": "liao", "8DA1": "cui", "9511": "ti", "7271": "gu", "7437": "qiang", "8AC0": "pi", "92CF": "jia", "9F74": "xian", "9540": "du", "9939": "tang;xing", "9F8B": "qu", "6F0A": "lu;lou", "72B2": "chai", "7C7C": "xian", "81D1": "nao;ru", "822B": "fang", "8E87": "chu", "9629": "sheng", "5499": "long", "6438": "zhen", "6C00": "lu", "86AA": "dou", "94F7": "ru", "9650": "xian", "5542": "nou", "5B82": "rong", "5C10": "ji", "7EB5": "zong", "84A2": "chu", "8CA3": "te", "9582": "shuan", "9E54": "su", "54F7": "le", "593B": "none", "5C35": "gan", "7901": "jiao", "7DC5": "zou", "92E6": "ju", "513C": "yan", "562F": "xiao", "63AB": "zou", "6B8F": "qiu", "79D1": "ke", "7FAE": "geng", "8081": "zhao", "8528": "jun", "934E": "tu", "5F50": "ji", "6054": "xiao", "76B6": "zha", "8EA0": "xie", "5766": "tan", "5D59": "ke", "6188": "qu", "8732": "wei", "507C": "jie", "6A37": "cong", "82BC": "mao", "921F": "shi", "9DED": "fan", "62A8": "peng", "7306": "fei", "7672": "dian", "7972": "jin", "850D": "lu", "9EBC": "ma;me;mo", "4F52": "yang", "5CD3": "yi", "5DD7": "yan", "6D9B": "tao", "9EBB": "ma", "5694": "ti", "5C46": "jie", "6D80": "xian", "6F3F": "jiang", "70EE": "none", "7ABD": "none", "8AFE": "nuo", "9EDD": "you", "5D66": "ai", "6584": "li", "6E5B": "zhan", "8ADA": "pian", "975A": "jing;liang", "9E23": "ming", "5A55": "jie", "63BD": "peng", "65FE": "chun", "69A7": "fei", "88E6": "fou", "9256": "tong", "4E76": "fu", "6CE0": "ling", "939A": "chui", "83B4": "wo;zhua", "860D": "xun", "89CC": "di", "8B96": "chen", "61D8": "chi", "7A23": "su", "9770": "wu", "9C4E": "jiao", "57D6": "none", "5E43": "wei", "64B6": "none", "8788": "yuan", "4FD4": "xian", "52CF": "bu", "62C6": "chai;ca", "63BB": "sao", "8094": "yi", "951D": "de", "55B0": "shi;si", "5858": "tang", "60F7": "chun", "6928": "none", "725D": "pin", "6307": "zhi", "70F5": "zhuo", "7227": "ling", "7AF7": "kan", "5A33": "li", "7120": "cui", "7B84": "bi", "8E53": "liu", "4E4E": "hu", "742C": "wan", "7B6B": "zhi", "8BD8": "jie", "8E33": "chun", "9D46": "none", "704F": "hao", "7826": "zhai", "8944": "xiang", "924D": "bi", "5421": "bi;pi", "5AB8": "chi", "5E31": "chou;dao", "6B5D": "yi", "7F1C": "zhen", "954D": "nie", "4EA6": "yi", "67F3": "liu", "6A11": "liang", "8C92": "tuan", "97EE": "jiu", "588E": "guo", "766F": "qu", "4EE3": "dai", "6E49": "tian", "6F63": "min", "9294": "pi", "9BF9": "xing", "4F6D": "xiang", "50B4": "yu", "796F": "zhen", "7C9C": "tiao", "839F": "han", "8A55": "ping", "9395": "tang", "9417": "jian", "572C": "wu", "6131": "none", "6E3F": "nai", "7BE9": "shai", "7E89": "zuan", "56D0": "za", "6AF0": "huai", "78F2": "qu", "7978": "huo", "90A3": "nei;na", "9269": "xi", "944B": "qing", "5527": "ji", "6D6E": "fu", "8497": "lang", "8B7B": "ying", "61A8": "han", "6E37": "yan", "6F71": "none", "7EFB": "quan", "537E": "e", "7A6B": "huo", "7F9F": "qiang", "8473": "wei", "8C7B": "han", "9922": "bu", "4EC2": "le", "595C": "fei", "620B": "jian", "9C78": "lu", "6C45": "mian", "9ABB": "kua", "5B07": "hui", "6C1D": "nei;nai", "9384": "ai", "9648": "chen", "97E8": "fu", "57FE": "ju", "6032": "bing", "70AE": "pao;bao", "7DC7": "zi", "8E1A": "lun", "9905": "bing", "9C2F": "ruo", "9F30": "nian", "520A": "kan", "6AA4": "dao", "6CA6": "lun", "712A": "qiong", "7A16": "bang", "7AD1": "hong", "8D2D": "gou", "6952": "si", "79B1": "dao", "927F": "jia;ha", "688D": "zao", "700E": "mie", "8380": "chen", "9C0F": "bi", "52EA": "qiao", "59DF": "gai", "731B": "meng", "7407": "xiu", "78BD": "gong", "9DFF": "pi", "4E94": "wu", "4FC4": "e", "7178": "bian", "9A77": "si", "7211": "jue", "85B6": "mai", "8BE7": "cha", "8379": "bu", "96C0": "que;qiao", "9F44": "zha", "5F22": "tao", "7BFF": "zhuan", "812B": "tuo", "89CA": "ji", "5DBD": "yue", "6876": "tong", "6921": "none", "6DE1": "dan", "70F2": "che", "55BD": "lou", "63DB": "huan", "67E8": "none", "73AC": "dan", "7964": "yu", "7B9E": "qian", "8117": "wen", "8919": "bei", "973F": "meng", "9A8F": "jun", "9E81": "cu", "5A66": "fu", "6C01": "mu", "7DDF": "zhong", "80AC": "you", "83DC": "cai", "89F7": "xue", "8CB2": "zi", "9B4C": "qi", "5D82": "zhang", "8082": "si", "96A5": "deng", "63A0": "lue", "6EC6": "he", "73D9": "gong", "774F": "kun", "81BE": "kuai", "9772": "qin", "99E8": "xun", "9ECA": "xi", "5D9E": "duo", "6D1E": "dong", "77B2": "xu", "5009": "cang", "53CF": "guai", "6B16": "lan", "83C7": "gu", "8ADC": "die", "95AD": "lu", "9DCF": "zhen", "5BD3": "yu", "888F": "zuo", "8B1D": "xie", "5CA1": "gang", "61A0": "jue", "6890": "bi", "6CED": "fu", "71B3": "man", "7E31": "zong", "8EA3": "qu", "5ACC": "xian", "60C8": "guo", "619D": "dui", "64D2": "qin", "72DB": "bo", "7AD8": "ju", "7ED2": "rong", "7F10": "xian", "80DE": "bao", "9984": "hun", "6B82": "cu", "7D86": "geng", "8161": "gua;luo", "6E1B": "jian", "7D8F": "sui", "83F3": "jin", "840F": "dan", "8CA1": "cai", "5E7C": "you", "6DA6": "run", "716A": "qiu", "8F16": "zhou", "928E": "qiong", "5E37": "wei", "6784": "gou", "6E98": "ke", "76FC": "pan", "9CBC": "fen", "9D2F": "er", "5917": "yuan", "59FB": "yin", "6FF3": "qian", "83BA": "ying", "8FC8": "mai", "924C": "he", "5322": "hu", "5A2C": "wu", "72A0": "xi", "7763": "du", "7C4A": "ti", "898F": "gui", "8DB1": "zan", "560C": "piao", "5BEC": "kuan", "582D": "huang", "630A": "nong;long", "6674": "qing", "71B2": "jiong", "868F": "yue", "50A2": "jia", "50CD": "dong", "59A5": "tuo", "5AAC": "bao", "6751": "cun", "73C3": "ran", "96D4": "chou", "9FA0": "yue", "54C5": "xiong;hong", "63BE": "yuan", "9E10": "di", "4F26": "lun", "5600": "di", "6018": "hu", "60A6": "yue", "738C": "qiu", "8201": "yu", "91BF": "mi", "55C3": "he", "5914": "kui", "6092": "yi", "79AB": "xuan", "830C": "chi", "955A": "beng", "4F93": "lu", "5639": "liao", "599E": "niu", "6F11": "gai", "7858": "none", "8B98": "zhe", "9362": "fu", "9859": "sang", "5C23": "wang;you", "7267": "mu", "8D37": "dai", "5E2E": "bang", "7A80": "zhun", "7AEE": "ping", "7C8A": "bi", "4E4D": "zha", "50BB": "sha", "5258": "qi", "800D": "shua", "6DDB": "zhi", "7525": "sheng", "761D": "guan", "7845": "gui;huo", "7A70": "rang", "957C": "qu", "8057": "lie", "9A9A": "sao", "9B12": "zhen", "5649": "dan", "73A8": "jue", "9308": "juan", "56ED": "yuan", "5B27": "jin", "5F1B": "chi", "69AC": "yuan", "6A77": "dou", "741D": "wen", "72EA": "tong", "8131": "tuo", "9CA9": "huan", "55DE": "zi", "5C01": "feng", "647C": "keng", "7F45": "xia", "8234": "ze", "832C": "cha;zha", "8378": "bi", "8D77": "qi", "91E9": "fan", "550F": "xi", "5E39": "sha", "894A": "zui", "8F5B": "dui", "96E3": "nan", "9C97": "zei", "5DA2": "yao", "6126": "kui", "6AAE": "tao", "8508": "biao;piao", "91C9": "you", "9669": "xian", "9C74": "mie", "4F60": "ni", "70D1": "yao", "81F2": "nie", "960A": "chang", "613B": "sun", "6629": "mo", "8021": "chu", "8F71": "gu", "622B": "yu", "711F": "xi", "8F7F": "jiao", "9D05": "huan", "9D20": "dan", "4E20": "qiu", "8879": "qi;zhi", "971F": "hong", "9A97": "pian", "9E5A": "ci", "54D4": "bi", "7AB7": "liao", "9472": "xiang", "5643": "pan", "6125": "none", "6310": "ru;na", "6F87": "lao", "7622": "ban", "506C": "zong", "53BA": "qu", "5ABD": "ma", "80E9": "ka", "841E": "none", "8A81": "beng", "8EC3": "duo", "931A": "zheng", "987E": "gu", "5EFF": "nian", "692B": "shan", "6AA6": "biao", "7EE2": "juan", "8CCA": "zei", "924E": "sheng", "4FD0": "li", "50C3": "bei", "542F": "qi", "5C92": "qian", "9F4E": "ji", "7031": "ji", "7F55": "han", "8BE8": "hun", "9E73": "guan", "885C": "dao", "96CA": "gou", "9A4E": "lin", "5F2E": "quan", "666A": "tian", "6A6F": "lao", "9BFC": "zong", "4EC7": "chou;qiu", "4FF5": "biao", "5353": "zhuo", "6056": "sai;si", "63A8": "tui", "6906": "chou", "758A": "die", "8C1A": "yan", "8E48": "dao", "91DD": "zhen", "5F5A": "hui", "782E": "nu", "7D94": "hu", "83E2": "bao", "8406": "bei;bi", "5A13": "wei", "69C5": "ge", "80DA": "pei", "9032": "jin", "9DA3": "pian;bin", "5C04": "she;shi;ye", "5C2C": "ga", "6199": "xi", "6ED6": "sui", "80D0": "ku", "81A8": "peng", "84B7": "yun", "866E": "ji", "5357": "nan", "5850": "su", "5AEF": "ao", "5B36": "none", "70E8": "ye", "6276": "fu", "63F0": "chong", "65D1": "yi", "6FE4": "tao", "767B": "deng", "90D2": "lang", "57B5": "an", "6941": "he", "8FB4": "zhen", "4E70": "mai", "5D19": "lun", "6FD7": "mi", "7311": "kun", "7CD7": "qiu", "890C": "kun;hui", "559D": "he", "8F03": "jiao", "9743": "huo;sui", "5886": "di", "7365": "xi", "78ED": "chuo", "8C02": "shen", "8E98": "long", "965D": "shan;xia", "5F40": "gou", "7BED": "long", "82E3": "ju;qu", "54FB": "han", "5C03": "fu", "637F": "xi;qi", "7471": "tian", "761B": "chi", "78A5": "bian", "4F38": "shen", "682F": "yu", "6D23": "mi", "7A01": "kao", "7A2C": "nuo", "8834": "none", "9E08": "ye", "6575": "di", "7618": "lou", "777E": "gao", "9031": "zhou", "9445": "heng", "502E": "luo", "82CC": "chang", "9DA5": "mei", "4E52": "ping", "507E": "fen", "5FF9": "wang", "606B": "dong;tong", "8EE7": "di", "9101": "bei", "9BC5": "ting", "5193": "gou", "526A": "jian", "8F0F": "you", "544A": "gao;gu", "74D2": "zan", "82BD": "ya;di", "8F4C": "none", "5B00": "gui", "66EF": "chu", "73F7": "wu", "746A": "ma", "96D2": "luo", "6F3C": "cui", "841D": "luo", "9D6E": "qian", "5442": "lu", "5C1E": "liao", "5CA3": "gou", "651F": "jun", "866F": "qiu", "87B6": "qu", "92CB": "chan", "99B1": "tuo;duo", "7B3A": "jian", "8B73": "nou", "8F80": "zhou", "5EFE": "gong", "6BBB": "ke;qiao", "78D3": "dui", "8037": "da", "9E7C": "jian", "5EE5": "guai", "6FF7": "fei", "7FEE": "he", "9B3C": "gui", "57C1": "cen", "6ED9": "hui", "7822": "ke", "9AA3": "zhan;chan", "9CFC": "wen", "87F6": "cheng", "8F7B": "qing", "9399": "shuo", "9738": "ba", "5C6A": "liao", "795F": "sui", "5A6D": "ya", "6861": "rao", "7D0B": "wen", "8ACF": "zou", "91CF": "liang", "669A": "yao", "6DBD": "hun", "76E1": "jin", "86EB": "gui", "8D11": "gan", "90A4": "none", "9515": "a", "69E8": "guo", "6E76": "quan", "711E": "chun", "54A6": "yi", "5930": "gao", "5B95": "dang", "5D65": "jie", "6D6A": "lang", "9192": "xing", "9B43": "ba", "9C43": "qiu", "4E59": "yi", "58FA": "hu", "5E4E": "mi", "6907": "ju", "6F05": "jiao", "7429": "chang", "597C": "cha", "7792": "man", "93F9": "qiang", "9981": "nei", "811A": "jiao;jue", "9F54": "chen", "75A6": "jue", "7C95": "po", "7D62": "xuan", "4F27": "cang;chen", "6840": "jie", "7277": "quan", "7447": "dai", "81FC": "jiu", "883E": "zhu", "90DE": "lang", "6DB1": "zhang", "70C8": "lie", "82D6": "di", "8B74": "qian", "99FD": "xuan", "4FE7": "none", "5B38": "shen", "6E93": "lian", "7FD3": "xie", "83F2": "fei", "8B80": "du;dou", "9A8A": "li", "9CE6": "yi", "4F54": "zhan", "5001": "zhi", "7047": "cong", "7220": "none", "81EE": "ji", "84CD": "shi", "4E7F": "zhi", "5205": "chuang", "543B": "wen", "5A51": "rui", "6833": "lao", "6905": "yi", "8249": "wei", "9075": "zun", "6D47": "jiao", "6F3B": "liao", "7ADE": "jing", "554B": "xiao", "8673": "di", "5D02": "lao", "79B7": "lei", "8E8E": "nian", "89F4": "shang", "57CA": "di", "70E6": "fan", "7C40": "zhou", "8075": "kui", "8E81": "zao", "5A00": "song", "6796": "yao", "7017": "xian", "7791": "ming", "86EF": "none", "89EE": "lu", "992D": "huang", "9F5C": "zi", "500D": "bei", "5BC0": "cai;shen", "6BDB": "mao", "7E30": "xi", "87B9": "jian", "884D": "yan", "9451": "jian", "577F": "fu", "5BC1": "zan", "931B": "ben", "99AC": "ma", "6989": "ju", "6FF2": "gu", "83F9": "zu", "86E7": "wang", "9819": "cheng", "5E5F": "zhi", "62C2": "fu;bi", "6A2E": "none", "6CC1": "kuang", "8286": "chai", "580D": "tu", "7D9A": "xu", "7E86": "mo", "97FF": "xiang", "534D": "wan", "5AEC": "zhe", "6198": "xi", "65C7": "pi", "8537": "qiang", "8D5F": "yun", "7119": "bei", "8470": "jun", "90C7": "xun;huan", "5F04": "nong;long", "6582": "lian", "6B06": "shuang", "7C7B": "lei", "7DDB": "ruan", "7FEF": "he", "8679": "hong;jiang", "9442": "xun", "5906": "feng", "6A01": "zhuang", "6E17": "shen", "77A6": "xi", "85AF": "shu", "8F29": "bei", "9EE0": "xia", "5477": "xia", "6605": "jie", "66FE": "ceng;zeng", "720C": "kuang", "8F9E": "ci", "8FCA": "za", "91D1": "jin", "72D2": "fei", "7880": "ceng", "8707": "zhe", "952C": "tan", "51E6": "chu", "5E6A": "meng", "65EF": "la", "69D1": "mei", "7D32": "xie", "8355": "jin", "83D1": "zai", "9E2E": "xiao", "5569": "gua", "57AE": "kua", "81B3": "shan", "8BC1": "zheng", "954F": "liu", "9746": "dai", "9F3F": "hui", "7DB7": "cui", "9902": "tian", "51D2": "ai", "6D82": "tu", "853F": "wei", "8CEF": "xiong", "9051": "huang", "91F0": "jian", "9F67": "nie", "5829": "geng", "6362": "huan", "8377": "he", "8A12": "ren", "4EEE": "jia", "54F1": "bei", "55DC": "shi", "72D8": "yue", "7C02": "guo", "87B2": "zhi", "895C": "chan", "8DB6": "ku", "9644": "fu", "9DBE": "han", "68B3": "shu", "7511": "zeng", "7E6F": "huan", "9616": "he", "9645": "ji", "9884": "yu", "5A8C": "mao", "6F75": "sa", "9190": "hu", "8B92": "chan", "8D56": "lai", "9D39": "ren", "5625": "none", "61C7": "ken", "7801": "ma", "9261": "ban", "5947": "qi;ji", "63B8": "dan;shan", "77BA": "hui", "78C0": "e", "82B7": "zhi", "8390": "chen", "89AA": "qin;qing", "8EB1": "duo", "99BE": "dan", "9A45": "qu", "5C83": "none", "7502": "bian", "799E": "gao", "8AE0": "xuan", "90AF": "han", "4EA4": "jiao", "76E9": "zhou", "6443": "gong", "69B0": "zhi", "6FC3": "nong", "72EB": "lao", "7545": "chang", "8471": "cong", "5763": "tang", "6004": "ou", "6CC4": "xie", "8158": "guo", "8D4F": "shang", "965F": "zhi", "69C3": "pan", "6B8E": "qia", "75EF": "guan", "877D": "chun", "5A44": "pou", "7C66": "zhong", "7E9B": "dao;du", "64BF": "jian", "6C72": "ji", "6CD3": "hong", "7F47": "zun", "8971": "long", "98D3": "ju", "9F0B": "yuan", "4E8B": "shi", "5E75": "jian", "63D9": "bian", "6BF4": "bi", "7F14": "di", "81BD": "dan", "9F7C": "chu", "5867": "ai", "5949": "feng", "71F8": "ru", "8CB8": "dai", "90DC": "gao", "97F9": "huang", "4FA4": "none", "5A9C": "zhen", "6CE4": "si", "52DC": "weng", "6BF3": "cui", "9D8F": "ji", "61D7": "xia", "6269": "kuo", "7470": "gui", "96F6": "ling", "9F13": "gu;hu", "58B2": "mu", "6804": "rong", "9134": "ye", "9137": "feng", "93C7": "xuan", "557B": "chi", "8310": "none", "907C": "liao", "5CD4": "mu", "73B1": "qiang", "75F2": "ma", "842B": "xiang", "9C87": "nian", "6CDD": "su", "8EB8": "ji", "903E": "yu", "94D2": "er", "4EF0": "yang", "5456": "li", "7E73": "jiao;zhuo", "9A49": "xu", "62B2": "he", "6666": "hui", "7B26": "fu", "908D": "yuan", "9B91": "bao", "50A4": "zai", "5C07": "jiang;qiang", "5C8B": "e", "5DDA": "yan", "7D18": "hong", "9F04": "zhu", "4ECF": "fo;fu", "5111": "an", "6C64": "tang;shang", "6E2F": "gang", "6FB5": "lian", "8F8E": "zi", "620A": "wu", "65C6": "pei", "6874": "fu", "7D09": "ren", "994E": "chi", "794C": "chong", "8F2E": "rou", "57F1": "shu", "8DD3": "zhu", "9168": "dai", "9F11": "ding", "54B2": "xiao", "5605": "kai", "70C1": "shuo", "83D9": "chui", "5FBC": "jiao", "6911": "bei;pi", "7645": "liu", "798C": "zi", "96AB": "fen", "9D23": "gu", "726F": "gu", "77B9": "ai", "8E69": "bie", "8EBE": "none", "9F12": "zi", "5426": "fou;pi", "5A67": "jing", "61E5": "zhi", "98FB": "tie", "51F1": "kai", "694E": "hun", "8273": "yan", "91A5": "piao", "93F1": "none", "9965": "ji", "5759": "jing", "5AA5": "pian", "5BE3": "hu", "6F16": "jiao", "787F": "kong", "7E7B": "xu", "8855": "tong", "8E84": "bi", "9624": "tuo", "9723": "yun", "658F": "lang", "65F9": "shi", "9C5B": "none", "648C": "kui", "9BE6": "jiu", "58C6": "xue", "6185": "tong", "59B2": "da", "7554": "pan", "75D1": "duo", "7988": "hui", "8568": "jue", "4F96": "lun", "5AB0": "zou", "65A4": "jin", "696C": "jie", "81D8": "la;xi", "90AA": "xie;ye", "5420": "fei", "68C4": "qi", "6B4A": "xiao", "852F": "chen", "8BEF": "wu", "5623": "beng", "6ADA": "lu", "716C": "yang", "77BB": "zhan", "8A63": "yi", "79E8": "zuo", "7C23": "kui", "8D4C": "du", "585E": "sai;se", "76AA": "li", "84FD": "bi", "8B77": "hu", "63B3": "lu", "6553": "duo", "724F": "tou", "7CCA": "hu", "8209": "ju", "54F6": "mi", "603B": "zong", "77C1": "chou", "7C10": "nian", "538B": "ya", "5F30": "shao", "65AE": "zhuo", "72C7": "yun", "901D": "shi", "9248": "she;tuo;ta", "92BF": "zhong", "53DA": "jia", "5586": "zhe", "5995": "zhong", "6180": "liao", "66BD": "lin", "7D9B": "none", "8812": "jian", "8847": "mo", "8989": "ji", "9391": "ye", "8189": "yi", "6F3A": "chuang;shuang", "7E1B": "fu", "8C42": "liao", "9AA9": "wei", "50EE": "tong;zhuang", "51F6": "xiong", "5729": "wei;xu", "74F2": "none", "7814": "yan", "7E70": "qiao;zao", "7EE9": "ji", "8202": "chong", "8846": "zhong", "9EEF": "an", "7D88": "ti;di", "8C4D": "bi", "8F9A": "lin", "4E91": "yun", "5795": "hou", "8A70": "jie", "8C9B": "huan", "5F7D": "di", "6C73": "bian", "7C03": "yi", "7E8F": "chan", "9AAE": "yi", "9E4C": "an", "54E7": "chi", "79B3": "rang", "7FE5": "zhu", "807B": "ji", "879B": "he", "923F": "dian;tian", "99DE": "tuo", "5315": "bi", "6723": "tong", "699D": "sha", "970A": "ling", "6C35": "shui", "57BE": "han", "6A5C": "jue", "7BFB": "piao", "8A45": "ling", "8E1B": "lu", "951F": "kun", "9523": "luo", "8702": "feng", "9A9C": "ao", "5BB9": "rong", "5F28": "chao", "5F61": "shan", "774A": "juan", "7A33": "wen", "810E": "sa", "9C6B": "ai", "9F32": "hun", "54CA": "you", "6929": "none", "740C": "ling", "7DA6": "qi", "9183": "yan", "992E": "tie", "9F26": "diao", "53FB": "le", "69DB": "jian;kan", "719B": "biao", "72E3": "zhao", "9765": "ye", "9D79": "li", "5B12": "wei", "6000": "huai", "6D3A": "ming", "6F9F": "lin", "8AD6": "lun", "6910": "ju", "7076": "zao", "8292": "mang;wang", "8959": "cao", "9188": "tan", "5019": "hou", "627A": "zhi", "6D14": "zhi", "7658": "li;ji", "9763": "mian", "5414": "ye", "62D0": "guai", "6DCB": "lin", "8F7D": "zai", "9A47": "zhi", "5B39": "xing", "8BAA": "shan", "98FC": "si", "9CAC": "yong", "555E": "ya", "6107": "wei", "6FAC": "zi", "9F8A": "chuo", "7FF0": "han", "9359": "hong", "5CED": "qiao", "7528": "yong", "76C2": "yu", "9753": "jing;liang", "5E90": "lu", "61DE": "meng", "63E2": "ke", "6495": "si", "7020": "ying", "7653": "wei", "76D0": "yan", "55D5": "ru;nou", "5DFF": "fu", "675D": "yi", "82EB": "shan", "51E9": "none", "527F": "jiao;chao", "535B": "shuai;lu", "54BC": "guo;kuai", "6E1F": "ting", "7735": "chi", "7B42": "chi", "837F": "cheng", "8741": "e", "88F9": "guo", "8A1D": "ya", "4EB8": "duo", "6777": "pa;ba", "67D7": "song", "9B44": "po;tuo;bo", "9ECF": "nian", "5135": "shu", "56BB": "xiao", "5797": "zhao", "747E": "jin", "7805": "li", "8076": "nie", "87A1": "wen", "8DB3": "zu;ju", "7479": "tu", "7BEF": "jian", "8232": "ling", "8650": "nue", "887B": "ran", "8F3C": "wen", "6615": "xin", "7059": "dang", "786C": "ying", "805F": "xu", "8F72": "ke", "9910": "can", "9EE6": "yu", "5056": "che", "5179": "zi;ci", "7226": "lan", "77EF": "jiao", "8678": "zi", "892D": "niao", "8940": "ji", "97D0": "ge", "56FC": "tai", "7B1C": "zhu", "88B3": "chi", "8F82": "lu", "99AE": "feng;ping", "5855": "weng", "5EBE": "yu", "6EC0": "chu", "7983": "zhi", "9F2C": "you", "55E9": "suo", "8028": "nou", "89BA": "jue;jiao", "8D73": "jiu", "9171": "jiang", "95B3": "chan", "9E02": "qi", "90A2": "xing", "6949": "ruo", "8CBB": "fei", "9D2E": "wu", "4FF3": "pai", "85A2": "xiao", "9130": "lin", "95EF": "chuang", "5716": "tu", "62ED": "shi", "7824": "tuo", "86BA": "ran", "981E": "e", "657E": "none", "689C": "jia", "68BD": "zhi", "6DA0": "wei", "7FF2": "piao", "8287": "mian", "88C1": "cai", "59B5": "tou", "7CA8": "bai", "907F": "bi", "6124": "fen", "6EBB": "ta", "78F0": "shan", "4FF1": "ju", "55C7": "se", "5908": "none", "5AC1": "jia", "7472": "qiang", "7905": "dun", "7D82": "tong", "8A93": "shi", "4ED9": "xian", "53DD": "ji", "88E1": "li", "9321": "qi", "529C": "ya", "609D": "kui;li", "7728": "zha", "8961": "shu", "66E3": "yan", "7584": "lin", "7671": "tan", "7D04": "yue;yao", "8657": "xu", "9C13": "sai;xi", "6109": "yu", "6872": "bo", "7863": "xiao", "90A1": "fang", "7EC5": "shen", "954E": "na", "9A79": "ju", "675F": "shu", "866D": "diao", "87F4": "si", "8C97": "ju", "5324": "qu", "68B0": "xie", "6DD9": "cong", "7A05": "shui", "8639": "huai", "909F": "kang", "94CA": "tuo;she;ta", "622E": "lu", "9932": "he", "4E9B": "xie", "5247": "ze", "5D80": "tu;die", "609F": "wu", "760F": "tu", "556A": "pa", "57AD": "ya", "8CC2": "lu", "57F8": "yi", "6145": "sao", "7302": "zhi", "8349": "cao", "9946": "bi", "67EA": "ao", "72C5": "qing", "7427": "e", "8126": "none", "818B": "liao", "852D": "yin", "9805": "xiang", "9A63": "teng", "5220": "shan", "62EF": "zheng", "711B": "lin", "8515": "di", "8FEA": "di", "9C7F": "you", "5C2B": "wang", "7F15": "lu", "8BA8": "tao", "72D0": "hu", "7A4D": "ji", "7B9B": "gu", "8BAB": "qi", "5708": "quan;juan", "572F": "yi", "583D": "gang", "4E34": "lin", "543A": "dou", "67CA": "zhong", "6BD1": "zuo", "6F74": "zhu", "9681": "yan", "50E0": "fan", "6714": "shuo", "7468": "jin", "789C": "chen", "7A8E": "diao", "512F": "teng", "5BE0": "ju", "6190": "lian", "6289": "jue", "6746": "gan", "67B4": "guai", "8A1E": "yao", "8A85": "zhu", "753E": "zai", "52C3": "bo", "6852": "sang", "8C90": "yu", "9150": "gan", "65FA": "wang", "6C97": "tian", "898E": "yan", "8D3F": "hui", "9212": "ji", "96C5": "ya", "9BC1": "geng", "5118": "jin", "6281": "yan", "64CB": "dang", "685E": "none", "8FA5": "xue", "9113": "ju", "9328": "mao", "552C": "hu;xia", "7BAE": "none", "504F": "pian", "596F": "huo", "789D": "ruan", "89E0": "quan", "93BA": "none", "6719": "ming", "6B70": "se", "6C8B": "you", "84B9": "jian", "88B2": "yi", "8BE4": "zheng", "9067": "zhang", "5690": "chang", "645E": "luo", "64A3": "dan;shan", "6614": "xi", "7BA9": "luo", "7BE6": "bi", "8DE8": "kua", "506E": "ji", "5E13": "ma", "66D8": "ru", "6BB0": "du", "9A0A": "tao", "4EA2": "kang", "5F46": "bie", "646A": "jiang", "6C63": "none", "78B6": "qi", "8073": "song", "90AD": "ju", "7046": "lan", "70D6": "zai", "7EBD": "niu", "82B5": "jue", "8364": "hun;xun", "519F": "shi", "536F": "mao", "5B80": "mian", "6D52": "hu;xu", "6F52": "xiang", "7CE8": "jiang", "8A35": "chi", "8C8C": "mao", "9947": "yu", "99B9": "ri", "5367": "wo", "608F": "qie", "6857": "duo", "7AFB": "le", "81C2": "bei;bi", "88E3": "lian", "93F2": "none", "9CB5": "ni", "4E0C": "ji", "55E6": "suo", "613A": "cao", "85A7": "kao", "8D7D": "jue", "9662": "yuan", "5783": "la", "5EE2": "fei", "5FF7": "xiong", "763F": "ying", "769E": "hao", "8218": "guan", "7461": "none", "7C73": "mi", "801D": "qu", "7E00": "jia", "9011": "qiu", "9289": "yu", "982F": "kui", "99FB": "han", "52A1": "wu", "5B26": "chou", "68A5": "song", "6B3E": "kuan", "97B4": "bei", "9AFA": "gua", "9E31": "chi", "521A": "gang", "5B29": "yu", "7B94": "bo", "663A": "bing", "7570": "yi", "9548": "bo", "89EC": "ni", "9427": "jian", "5CDE": "kui", "6293": "zhua", "6C9F": "gou", "8761": "ruan", "6AC7": "po", "868C": "bang;beng", "9BC7": "huan", "6F7E": "lin", "76B0": "pao", "7E98": "zuan", "88D5": "yu", "9063": "qian", "96BC": "sun;zhun", "9FA3": "jue", "5331": "kui", "5A7D": "jia", "7694": "han", "7E9A": "xi", "8308": "zi;ci", "9490": "shan", "7D64": "xian", "82E0": "min", "9911": "bo", "9CBD": "die", "50E8": "fen", "4ED6": "ta", "734E": "jiang", "753B": "hua", "79A9": "si", "80CA": "qu", "84C1": "zhen", "506A": "bi", "60DE": "xin", "78A7": "bi", "7EF6": "shou", "8ED9": "chen", "6C16": "nai", "7185": "yun", "845B": "ge", "8502": "luo", "8A6F": "hui", "8F24": "qian", "5B89": "an", "661A": "shen", "749B": "su", "894B": "ji", "9647": "long", "5243": "ti", "72E4": "ji", "7D08": "wan", "85CE": "jin", "9393": "weng", "9D5C": "ti", "580A": "e;wu", "6193": "hui", "6510": "qian", "669F": "kai", "6F6F": "xun", "5242": "ji", "7F6C": "zhuo", "821F": "zhou", "911E": "yin", "666E": "pu", "96A9": "yu", "548F": "yong", "569A": "yin", "958B": "kai", "95AA": "none", "55AE": "dan;chan;shan", "797F": "lu", "8785": "xi", "8DD5": "die", "594A": "xie", "5B6F": "jian", "6FF9": "bin", "701A": "han", "7D7E": "cheng", "55FE": "sou;zu", "5709": "yu", "7B3F": "luo", "8316": "ge", "9C49": "bie", "9D9E": "chun", "79C0": "xiu", "9193": "tan", "55B3": "zha;cha", "5DC8": "ju", "6251": "pu", "7E5D": "jian", "7FA8": "xian", "8153": "fei", "9A13": "yan", "4F5A": "yi;die", "6A1B": "jiu", "8F63": "li", "99B4": "xun", "9DB0": "yuan", "63C3": "jian", "65A8": "qiang", "665F": "sheng;cheng", "8412": "yan", "8C1C": "mi;mei", "8EEB": "zhen", "648F": "xian", "8042": "nie", "9019": "zhe;zhei", "9D4A": "jia", "5087": "rong", "553A": "tian", "625F": "shen", "6420": "shuo", "65B7": "duan", "88ED": "chi", "89DE": "shang", "98C2": "liao", "53F3": "you", "570E": "yuan", "607F": "yong", "832F": "fu", "4F9C": "zhou", "7155": "xi", "8337": "fa", "6041": "nen;ren;nin", "70EC": "jin", "873B": "qing", "8854": "xian", "8D6D": "zhe", "93A8": "sun", "4E1B": "cong", "545A": "none", "591A": "duo", "68A6": "meng", "80C6": "dan", "9BCC": "gao", "5112": "ru", "5840": "none", "82A3": "fou", "5B2B": "none", "5F0A": "bi", "83D4": "fu", "9D42": "xiu", "5EA9": "tu", "5F89": "yang", "877C": "lou", "91AE": "jiao", "9AE6": "mao", "737A": "ta", "77A5": "pie", "7D3A": "gan", "8E40": "die", "6074": "de", "61D3": "ai", "78EC": "qing", "7ACC": "chu", "7CD4": "xiu", "7D01": "cha", "854F": "chu", "8843": "pei", "90BF": "shi", "986C": "ru", "5373": "ji", "5826": "jie", "5DA6": "zhan", "609B": "quan", "62DE": "di", "6815": "zhen", "6B46": "xin", "704D": "que", "798F": "fu", "882A": "long", "9257": "qian", "92BC": "cuo", "9466": "none", "968C": "an", "51FE": "han", "5293": "yi", "5491": "da", "6643": "huang", "6D22": "yi", "8BEE": "qiao", "5B5F": "meng", "5CB5": "hu", "5E4A": "gong", "6882": "qiu", "6C5D": "ru", "73A4": "beng", "75D8": "dou", "875C": "fu", "87C9": "liao", "8F37": "hong", "980F": "hang", "6068": "hen", "7092": "chao", "709C": "wei", "7A45": "kang", "7D2C": "chou", "98D1": "biao", "5601": "qi", "5878": "ou", "7C0B": "gui", "8D19": "xuan", "94EC": "ge", "9CD2": "jian", "9DE4": "tan", "9F3E": "han", "67CF": "bo;bai", "6F92": "hong", "700C": "biao", "86E2": "ping", "8820": "mi", "88DF": "sha", "62CB": "pao", "64AB": "fu", "6F12": "qiang", "8274": "fu", "96A3": "lin", "7BFA": "pai", "8ABF": "diao;tiao", "953C": "sou", "5AB9": "liu", "6A68": "fen", "7777": "jian", "778F": "qiong", "7B3B": "qiong", "804F": "er", "870C": "bi", "9B6A": "gai", "5BDA": "bao", "6F10": "zhi", "73AE": "wei", "9519": "cuo", "9CE2": "li", "5853": "mi", "7294": "xi", "78AA": "zhen", "92B3": "rui", "9AC5": "lou", "5E7B": "huan", "7685": "pa", "78D7": "none", "83FE": "tian", "993A": "bo", "9B19": "seng", "9F2E": "ting", "7D46": "ban", "8F20": "guo", "9367": "hong", "9655": "shan", "988F": "ke", "4E48": "me;ma;yao", "65FC": "min", "6DE5": "lu", "78D9": "gun", "7D8A": "xie", "538A": "ya", "5BE2": "qin", "6FE2": "zui;cui", "7055": "li", "77B0": "kan", "801A": "pi", "5409": "ji", "77A9": "zhu", "84BA": "ji", "83D8": "song", "8AE4": "e", "9090": "li", "4EF7": "jia;jie", "5A35": "ju", "83F7": "zhou", "52A7": "zhi", "5C91": "cen", "93C2": "kou", "9B26": "dou", "9CCA": "bian", "5EB6": "shu", "6F65": "su", "72AE": "ba", "8B28": "mo", "9003": "tao", "9317": "wei", "9671": "ju", "4F25": "chang;tang", "6B84": "tian", "50A3": "dai", "50D3": "tui", "59F5": "pei", "5BA3": "xuan", "6EAD": "ce", "8FF3": "jing", "68E3": "di", "74E1": "zhi", "82BB": "chu", "8B32": "can", "9D1F": "chi;zhi", "5DA1": "gui", "5E10": "zhang", "8778": "gua;wo", "8892": "tan", "9780": "tao", "5C96": "qu", "60B3": "de", "74C6": "zhi", "8724": "si", "50AE": "zao", "55AF": "pen", "61FB": "ji", "7895": "qi", "7A6F": "none", "7EBA": "fang", "9172": "cheng", "917B": "zui", "9B98": "none", "9F6E": "yi", "53ED": "ba", "564D": "jiao", "6786": "mao", "67D6": "zhao", "7192": "ying", "7284": "ji", "73A2": "bin;fen", "8630": "none", "8C99": "chu", "95CD": "du;she", "5893": "mu", "5D11": "kun", "9915": "jun", "662D": "zhao", "850A": "han", "8E1F": "chi", "4F1B": "yu", "67C8": "ban", "7A09": "jing", "7B07": "suan", "7C55": "zhou", "7F20": "chan", "8C88": "he", "93E3": "shu", "93F8": "hui", "51A9": "xie", "5929": "tian", "76A4": "po", "7D98": "feng", "8049": "wa", "96C8": "huan", "54CC": "pai", "553E": "tuo", "6410": "chu", "7971": "shui", "7A61": "se", "9584": "huo", "9721": "mai", "99A3": "yan", "9DE5": "si", "9DF6": "mai", "6395": "ling", "6CFA": "luo;po", "78C3": "si", "826E": "gen", "9237": "gu", "51F3": "deng", "5E3D": "mao", "76C8": "ying", "7CA6": "lin", "8823": "li", "8EED": "kuang", "939D": "ta", "9930": "jian", "578C": "tong;dong", "59E2": "juan", "5A5D": "dian", "63E8": "cheng", "8816": "huo", "8AAB": "zhen", "93E0": "feng", "98EC": "juan", "9F22": "fen", "61C8": "xie", "63A9": "yan", "6556": "ao", "71D7": "lan", "7C24": "dai", "8705": "fu", "5DD2": "luan", "9B42": "hun", "585A": "zhong", "8933": "lian", "93E9": "jian", "949E": "chao", "9768": "ye", "64A2": "dan", "6AD7": "mie", "9A3F": "zhang", "6FD5": "shi", "8D1D": "bei", "9896": "ying", "5F8C": "hou", "89EA": "xing", "8C74": "di", "93E1": "jing", "9A8B": "cheng", "5789": "pao", "6835": "li", "6903": "hao", "799C": "yong", "92D4": "wan", "5B24": "ma", "5F23": "fu", "695D": "lian", "6D0D": "si", "73BF": "shao", "73D7": "xian", "7ACB": "li", "8BA0": "yan", "96EF": "wen", "50F4": "xian", "79B5": "ti", "7CDE": "fen", "5216": "yue", "7E69": "sheng", "8105": "xie", "87E8": "jue", "8A3F": "zi", "4E0A": "shang", "56E4": "dun;tun", "6377": "jie", "949B": "tai", "9E0C": "hu", "6649": "jin", "90C8": "hou", "5FC6": "yi", "6CEA": "lei", "882F": "pi", "8BB5": "ju", "96B5": "xi", "9EA5": "mai", "6DCE": "peng", "7334": "hou", "7501": "ping", "9E0E": "ying", "56BC": "jiao;jue", "68F1": "leng;ling", "69C6": "xun", "7BE3": "pang", "90DB": "fu", "63AF": "ken", "7626": "shou", "7A57": "sui", "7F97": "qiang", "9F5F": "ju", "8B1A": "shi;yi", "5892": "shang", "5F06": "ju", "6EFE": "gun", "7025": "hao", "7E92": "chan", "7F2A": "mou;miao;miu", "861C": "ju", "8811": "rong", "8C41": "huo;hua", "95C9": "yin", "6D2E": "tao", "7B5C": "dang", "811F": "lie", "982C": "jia", "9B88": "ju", "9CFA": "fu", "9F1B": "gao", "6ABD": "er", "6FA5": "xie", "939C": "pan", "6B58": "hu", "8365": "ying;xing", "5555": "tao", "61BC": "jing", "7CB4": "li", "8DE0": "yi", "50F2": "xian", "7CD1": "nuo", "7FEC": "hui", "861B": "yu", "68F4": "fu", "6F2D": "mang", "835D": "ce", "91EA": "yu", "5592": "zan", "76F6": "wan", "78A8": "wei", "8D7E": "qin", "58CB": "dang", "678D": "yi", "7537": "nan", "85A1": "ding", "985C": "jiang", "52BF": "shi", "5842": "gang", "69E2": "xi", "9AAF": "ang", "6F9C": "lan", "70FC": "hu", "7229": "yu", "85B9": "tai", "8CCB": "jiao", "9310": "zhui", "6105": "ge", "63DE": "an", "7312": "yan", "820C": "she", "86F3": "si", "87C7": "ma", "9012": "di", "91C8": "shi", "9784": "pao", "52EE": "ju", "5A6C": "yin", "694A": "yang", "80AD": "na", "91FE": "ye", "6C56": "pai", "6E6E": "yin;yan", "83F5": "wang", "88F8": "luo", "892F": "jie", "8E50": "ji", "902A": "cuo", "9243": "shi", "9D04": "pi", "5599": "hui", "57DD": "nian", "5ADB": "yi", "5D9C": "jin", "6980": "pin", "699C": "bang", "7E7F": "jian;kan", "8048": "you", "5011": "men", "58C4": "ye", "724C": "pai", "728E": "feng", "8E91": "zhi", "574C": "ben", "5F8B": "lu", "61F7": "huai", "6627": "mei", "750C": "ou", "88A3": "yi", "7BAD": "jian", "6C69": "gu", "936B": "qiao", "97C8": "wa", "515F": "xin", "5197": "rong", "7733": "ming", "9F43": "ge", "53BD": "lei", "664A": "zhi", "7CE2": "mo", "7FA9": "yi", "824C": "nian", "8F34": "chun", "58EC": "ren", "7A2A": "fu", "9263": "jie", "9D03": "jue", "5734": "zhuo;shao", "5E2D": "xi", "6424": "e", "655A": "duo", "6CB6": "yi", "6D78": "jin", "89A9": "du", "9408": "qiao", "9A20": "ti", "9D93": "miao", "9E58": "gu;hu", "5BE7": "ning", "62FC": "pin", "65B9": "fang", "6A66": "tong;chuang", "77ED": "duan", "7CE6": "chi", "969B": "ji", "9711": "zhan", "8D40": "zi", "9BDA": "ji", "5758": "di", "5ABF": "kui", "725C": "cheng", "7C89": "fen", "92EC": "shi", "51CB": "diao", "67C7": "he", "8DCC": "die", "991F": "zhui", "9E00": "shu", "667C": "wan", "6977": "kai;jie", "7151": "zhu", "7187": "he", "7F17": "min", "8DF8": "bi", "9C00": "huan", "631D": "wo;zhua", "677C": "zhu", "9A7E": "jia", "5484": "duo", "5871": "lang", "5ED4": "lou", "663B": "ang", "530E": "an", "6B25": "yu", "782B": "zhu", "787C": "peng", "7A8A": "yu", "7C9E": "xi", "8BCB": "di", "93D5": "lu", "9913": "e", "5839": "zhong", "625D": "ku", "746D": "tang", "93E8": "zan", "960F": "yan;e", "98C8": "biao", "9EA2": "ling", "5234": "duo", "6C8C": "dun;zhuan", "6D25": "jin", "7FB9": "geng", "8289": "gan", "85E4": "teng", "8962": "tan", "976F": "du", "5C7D": "han", "5D45": "gan", "6550": "chen", "65BD": "shi", "78C6": "hua", "7D2E": "zha;za", "866B": "chong;hui", "8AD9": "huai", "6A05": "cong;zong", "6BE7": "rong", "77FC": "qiang", "8203": "xi", "8A18": "ji", "5225": "bie", "8493": "chun", "967D": "yang", "57F3": "kan", "663E": "xian", "7307": "yao", "80EE": "pang", "8583": "hao", "8F7A": "yao", "9102": "e", "98E3": "ding", "5075": "zhen", "50A8": "chu", "6787": "pi", "7286": "zhi", "84A4": "tu", "8CF9": "ai", "8FE3": "zhi", "6313": "zha", "65BF": "you", "6F85": "hua", "723D": "shuang", "77DA": "zhu", "8DDB": "bo", "523B": "ke", "606D": "gong", "7C11": "suo", "58EE": "zhuang", "5F68": "chi", "7C88": "rou", "81FD": "xian", "85AC": "yao", "86D3": "ci", "87F7": "dang", "8D67": "nan", "5B69": "hai", "6394": "qian", "6EB4": "xiu", "72AC": "quan", "5D6F": "cuo", "622C": "jian", "6E18": "rou", "7799": "mo", "7B5A": "bi", "869E": "mu", "7248": "ban", "7D38": "zhu", "80DF": "mu", "9AE8": "kun", "669E": "jiao", "6E51": "xu", "75F1": "fei", "8CEC": "zhang", "8F2C": "liang", "9047": "yu", "9270": "si", "5084": "xia", "82CF": "su", "6386": "gang", "7923": "mie", "9800": "hu", "6745": "yu", "67F9": "shi", "6A40": "xi", "7563": "da", "8523": "jiang", "8B46": "xi", "5974": "nu", "80ED": "yan", "832D": "jiao", "9C26": "zi", "9E86": "zhu", "53EB": "jiao", "5E58": "ze", "690E": "zhui;chui", "7060": "lan", "7493": "none", "9CF0": "none", "53A0": "ce;si", "9B9E": "er", "50A5": "tang", "6652": "shai", "67DF": "nan", "6CD6": "mao", "7946": "xian", "953F": "ai", "9B8E": "nian", "9F84": "ling", "571C": "yuan;huan", "5812": "none", "5D8B": "dao", "60FD": "hun", "6657": "han", "76F0": "gan", "9157": "xu", "55C2": "yao", "585C": "peng", "6561": "yi", "6886": "bang", "8145": "dan", "9E4B": "miao", "6224": "gai", "6345": "tong", "6819": "xiang", "70F0": "fu", "85EB": "tan", "8CD2": "she", "8E4F": "ti", "9AC2": "qia", "6E4B": "wei", "79FE": "nong", "7B90": "qing", "875A": "rou", "8E7C": "pu", "9463": "biao", "540B": "cun", "5A5E": "xing", "6B2B": "qi", "78E1": "kan", "8DA3": "qu;cu", "8E86": "ju", "9A78": "fu", "742F": "guan", "4FA5": "jiao;yao", "55AB": "chi", "5767": "zhi", "636B": "men", "70C9": "huan", "74BC": "lan", "793A": "shi", "8FED": "die", "9BBF": "zhe", "53CB": "you", "5F52": "gui", "755A": "ben", "8594": "qiang", "5BAB": "gong", "65C3": "zhan", "73ED": "ban", "7418": "min", "751A": "shen", "7ED4": "ku", "9A59": "zhan", "9F50": "qi;ji", "577D": "ling", "585B": "li", "6B34": "lang", "6BC9": "yi", "7CC0": "none", "8C4A": "feng;li", "9860": "piao", "5B6E": "cong", "5E3F": "hou", "760D": "yang", "76C4": "zhao", "9081": "mai", "9C08": "die", "4EE2": "di", "57A8": "shou", "8BC7": "xiong", "9DAF": "ying", "6F69": "yi", "8008": "gou", "580F": "none", "6D1C": "none", "7FB5": "fen", "87D6": "si", "5FB9": "che", "7610": "yu", "9C02": "ji", "554F": "wen", "595E": "sui", "657B": "xiong", "6764": "none", "729C": "dun", "76EC": "gu", "7EE3": "xiu", "8D1E": "zhen", "51EF": "kai", "5B3D": "yuan", "66AC": "xie", "749C": "huang", "7DAA": "qian", "8898": "yi", "505B": "cha", "5998": "yun", "6EF1": "kou", "98D5": "sou", "9F60": "tiao", "582F": "yao", "7150": "ying", "7578": "ji", "851E": "lou", "98D2": "sa", "6437": "chen", "6609": "fang", "7C76": "shen", "8F4A": "wei", "9043": "yan", "615A": "can", "65E6": "dan", "680B": "dong", "7A73": "zan", "8E60": "zhi", "512A": "you", "54E9": "li", "5F78": "zhong", "677A": "xin", "6BDD": "none", "7318": "zhi", "7D1B": "fen", "7DD3": "none", "8C54": "yan", "921C": "hong", "9B61": "diao", "5E88": "qin", "6D02": "yi", "71BD": "xiao", "7C4F": "qi", "8102": "zhi", "8E14": "chuo", "58E7": "yan", "822E": "lu", "8571": "shao", "92F5": "tu", "97BD": "qiao", "993B": "gao", "9E4F": "peng", "6101": "chou", "79BA": "yu", "9D68": "shu", "5B03": "xu", "6B0D": "none", "829F": "shan", "9329": "chang", "4E9A": "ya", "60B7": "li", "630D": "jiao", "66AF": "mo", "9752": "qing", "9C9F": "xun", "5D42": "lu", "9479": "cuan", "660C": "chang", "7F48": "tan", "6545": "gu", "6856": "xue", "6AE7": "zhu", "777C": "ti", "8147": "nei", "83E8": "jie", "9C0C": "qiu", "62BD": "chou", "6BAA": "yi", "844B": "qu", "9599": "nao", "5EAB": "ku", "7AE5": "tong", "7E18": "xi", "7EC2": "fu", "82AA": "qi", "85FF": "huo", "65A3": "dou", "8AB3": "qu", "4E3B": "zhu", "4FE6": "chou", "58A3": "pu", "5BDF": "cha", "674E": "li", "6B57": "xiao", "7851": "peng", "962B": "pei", "52C1": "jing", "728F": "pian", "762B": "tan", "8AC6": "qi", "6708": "yue", "8459": "xiang", "915C": "none", "9B4B": "tui", "6C99": "sha", "7ED1": "bang", "58B4": "huang", "6223": "kui", "6EC2": "pang", "731D": "cu", "736C": "xie", "7F58": "fu;fou", "8619": "yi", "8B7D": "yu", "8E2F": "zhi", "5769": "gan", "5E15": "pa", "6624": "ling", "73FD": "ting", "83CC": "jun", "5C64": "ceng", "5E5B": "zhang", "60DB": "hun", "6C1E": "none", "851C": "ao", "650D": "ying", "8FAA": "none", "95A2": "guan", "6892": "han", "6D8C": "yong;chong", "7C65": "yue", "7E23": "xian;xuan", "9873": "nie", "9F9A": "gong", "511C": "neng", "5181": "chan", "5B8B": "song", "79EF": "ji", "902E": "dai", "92F6": "liu", "9501": "suo", "5308": "xiong", "5525": "none", "67EE": "duo", "7A2E": "zhong;chong", "9DDE": "shuang", "58E6": "xun", "5AE7": "ce", "6BC5": "yi", "7503": "zhou", "78DE": "peng", "8305": "mao", "870F": "you", "8AB1": "jie", "8F88": "bei", "9D49": "luan", "563F": "hei;mo;hai", "5EC8": "sha;xia", "745A": "hu", "8549": "jiao;qiao", "86F5": "xing", "9537": "e", "4E3F": "pie", "5BA4": "shi", "5C72": "wa", "7784": "miao", "77CF": "mian", "7C49": "tai", "7F34": "jiao;zhuo", "99F6": "ju", "4F12": "jin", "77D3": "long", "4F07": "yi", "57CF": "shan", "8844": "nu", "935A": "yang", "4F31": "ni", "684E": "zhi", "6C92": "mei;mo", "8165": "xing", "54BE": "lao", "5A01": "wei", "6C9B": "pei", "999D": "bi", "9A55": "jiao", "591D": "qing", "612C": "su", "70A4": "zhao", "95CC": "lan", "99FA": "liang", "50CC": "ying", "5203": "ren", "54BD": "yan;ye", "6F5D": "xi", "718F": "xun", "823B": "lu", "9871": "lu", "98BE": "sao", "9F7D": "jin", "5590": "yu", "6E9F": "ming", "81B4": "hu", "853C": "ai", "8600": "tuo", "930C": "an", "98CF": "yang", "6EF9": "hu", "7B44": "yao", "886A": "yi", "4F05": "dun", "525B": "gang", "6B9F": "wen", "7B4B": "jin", "98EB": "yu", "5081": "sou", "66F6": "hu", "6785": "ji", "8599": "ti", "5453": "yi", "5476": "nao", "6AF2": "yu", "904A": "you", "5E3C": "guo", "5E6B": "bang", "98B9": "wei", "58BE": "ken", "7847": "nao", "798E": "zhen", "8B71": "shan", "5D29": "beng", "63C2": "jiu", "76B8": "jun", "83E9": "pu", "951A": "mao", "4EEB": "mu", "5C3F": "niao;sui", "68AA": "dou", "6D90": "e", "6E46": "qi", "72B4": "an;han", "72F9": "xia", "7D9C": "zong;zeng", "964A": "duo", "9964": "ding", "5010": "shu", "89D8": "chao", "9315": "kun", "5FBF": "long", "6BFD": "jian", "5C75": "e", "6378": "tu", "63B9": "none", "75B6": "xie", "86B3": "chi", "929D": "xiu", "9D24": "zhong", "5656": "yin", "65B2": "zhuo", "6DFB": "tian", "7C6F": "ying", "7FA4": "qun", "9296": "zhu", "99D7": "zhen", "9F01": "qu", "5255": "fei", "56C8": "yi", "5C89": "wu", "6463": "zha", "69A8": "zha", "6A03": "lang", "7EB4": "ren", "8810": "qi", "8A59": "ba", "62D6": "tuo", "8180": "bang;pang", "81F7": "die", "7E0B": "zhui", "81B9": "fen", "90D8": "lu", "993E": "liu", "5123": "kuang", "4EB0": "jing", "5200": "dao", "5541": "zhou;zhao", "58F4": "zhu", "5E0E": "dan", "6DFF": "mi", "78CE": "xi", "8807": "li", "83D6": "chang", "8F4E": "jiao", "976E": "di", "9C53": "shan", "5682": "han", "61CE": "se", "63B7": "zhi", "6A28": "xi", "73A6": "jue", "743C": "qiong", "7D29": "zhi", "7D40": "chu", "8644": "none", "88C8": "kun", "5425": "pou", "5446": "dai", "5526": "gou", "6BE2": "sai", "7E2C": "cu", "803B": "chi", "905B": "liu", "91F8": "xi", "933A": "zhui", "9AE7": "dan", "9E4E": "bei", "668B": "min", "7381": "xian", "73B3": "dai", "794A": "beng", "841A": "tuo", "8979": "shi", "9488": "zhen", "9832": "ting", "4E51": "zhong", "547E": "da", "6728": "mu", "70ED": "re", "721B": "lan", "86AD": "ni", "8EC4": "zhi", "9A4B": "bo", "9ACE": "liao", "4FC8": "ku", "5F9B": "qi", "5D7D": "di", "7E07": "none", "8D9B": "yin", "6607": "sheng", "7709": "mei", "8293": "zi", "8A54": "zhao", "8EA6": "zuan", "9A50": "dun", "9C16": "tuo", "611D": "yan", "649E": "zhuang;chuang", "72D5": "sheng", "4E63": "diu", "57D4": "pu;bu", "65C9": "fu", "6C0D": "qu", "6DD1": "shu", "6DF0": "nian", "81B2": "jiao", "8DD9": "ju", "92CC": "ting;ding", "52A3": "lie", "5970": "bei", "717D": "shan", "738F": "le", "73EA": "gui", "8634": "feng", "8880": "jun", "9316": "du", "9F72": "qu", "5C5E": "shu;zhu", "66BA": "dan", "74F5": "yi", "7712": "shen", "919D": "cuo", "5E70": "xian", "820E": "she", "7878": "none", "78C4": "tang", "7F09": "ji;qi", "4E92": "hu", "5935": "yan", "6536": "shou", "6E09": "she", "70BB": "shi", "73E1": "qin", "880E": "mang", "5295": "zhi", "5306": "cong", "5B4D": "yan", "66DB": "xun", "74FE": "meng", "883D": "jie", "89CD": "tian", "8A5B": "zu", "950F": "jian", "57C2": "geng", "5EC2": "xiang", "6002": "song", "764B": "he", "9F6B": "kun", "78BC": "ma", "79D4": "jing", "90CC": "gui", "96CF": "chu", "9755": "zhen", "5DBB": "za", "645B": "chi", "693C": "yan", "6C76": "wen", "753A": "ding;ting", "78E0": "lu", "91AD": "bu", "64BA": "cuan", "656F": "hun;min", "7207": "ruo", "7BF8": "sen", "901F": "su", "9C37": "tiao", "85D8": "lu", "8AF5": "nan", "8B21": "yao", "983F": "zi", "9A17": "pian", "59A6": "feng", "5E0B": "zhi", "6868": "jiang", "693D": "chuan", "6B51": "hu", "782A": "mu", "833A": "chong", "5076": "ou", "5718": "tuan", "5805": "jian", "6166": "jiu", "67E3": "zhi", "8A50": "zha", "8EC9": "yu", "8FE6": "jia", "904D": "bian;pian", "628D": "zheng", "7BBF": "ji", "9203": "jian", "9365": "qie", "57EA": "kong", "5AFD": "liao", "7183": "wu", "8B53": "hui", "662B": "xu", "697D": "le;yue", "6ADF": "li;yue", "779D": "chi", "8C46": "dou", "98AC": "xia", "9A75": "zang", "5B59": "sun", "6222": "ji", "8175": "jia", "8A3A": "zhen", "927A": "er", "72CE": "xia", "8D21": "gong", "9C4C": "xiang", "4F87": "yi", "60CB": "wan", "8207": "yu", "8EE1": "qian", "51EA": "none", "6A4B": "qiao", "6BB5": "duan", "78A3": "jie", "8E45": "cha", "63D6": "yi", "71C5": "xian", "7830": "peng", "7E93": "ying", "91FD": "pi", "929C": "xian", "99BF": "lu", "679A": "mei", "74C4": "du", "81B6": "run", "9065": "yao", "959F": "bi", "54AE": "zhou", "5D55": "zong", "67ED": "bo", "7482": "qi", "7AF0": "shao", "952B": "pei", "574F": "huai;pi;pei", "846B": "hu", "8A84": "lei", "507D": "wei", "511B": "wu", "59D6": "ju", "88A6": "na", "9793": "ting", "9AEB": "tiao", "556B": "zhe", "63D5": "zhen", "67CD": "yang", "6C7E": "fen", "8187": "zhui", "9C07": "rou", "5376": "shi", "587B": "mo", "6484": "ying", "746E": "li", "7F25": "piao", "8BC0": "jue", "7A39": "zhen", "923A": "yu", "4F40": "si;shi", "6CC0": "si", "712B": "cui", "84E9": "wu", "8BA3": "fu", "8BC5": "zu", "9ECB": "kuang", "5CB9": "tiao", "67E1": "yong", "67F8": "pei", "7033": "jian", "8DEA": "gui", "6873": "ben", "7037": "yi", "93BD": "none", "5A14": "ke", "699E": "yuan", "7474": "jue", "816D": "e", "847F": "mei", "8CA9": "fan", "4FB7": "ju", "5F12": "shi", "57A4": "die", "5D1A": "leng", "78F7": "lin", "8F23": "peng", "9DB8": "ruo", "6046": "heng", "6DEC": "cui", "7007": "wang", "7586": "jiang", "7601": "cui", "8564": "rui", "93B4": "xi", "5D1C": "duo", "5FD9": "mang", "7276": "quan", "535E": "bian", "58F9": "yi", "6CEB": "xuan", "75A9": "cui", "7881": "qi", "8899": "pa", "951C": "qi", "4E53": "pang", "5E05": "shuai", "7521": "shen", "78C1": "ci", "5345": "sa", "5F80": "wang", "68A7": "wu", "6A88": "xuan", "8A73": "xiang", "8B3A": "zhe", "8EDD": "qi", "99D0": "zhu", "589F": "xu", "5B10": "xian", "6E11": "mian;sheng", "6F02": "piao", "6F68": "zhong", "729D": "tong", "7A31": "cheng", "7AA2": "xu", "7C5D": "ying", "8B67": "lian", "9A1E": "huo", "584F": "kai", "5DC4": "long", "6848": "an", "6B07": "she", "747A": "chang", "86DC": "yi", "877A": "ju", "59CB": "shi", "661B": "ju", "6B5C": "chu", "72FC": "lang", "8FD1": "jin", "6DFC": "miao", "7798": "kou", "805A": "ju", "82CB": "xian", "4FB3": "cuo", "5CEF": "feng", "6D8B": "tu", "6DC4": "zi", "8EDC": "na", "950E": "kai", "5007": "wan", "62F5": "tun", "6396": "ye;yi", "712C": "xi", "71D4": "fan", "73B5": "an", "8B0D": "ying", "9C03": "wei", "9EF8": "lu", "5DC3": "long", "5E4B": "pan", "6393": "shu", "63C5": "yan", "6822": "bo;bai", "6AED": "jie", "6CBB": "zhi", "76C5": "zhong", "78C5": "bang;pang", "4F48": "bu", "5EAE": "you", "760B": "feng", "96EE": "mu", "55CC": "ai;yi", "5D26": "yan", "7D10": "niu", "87CB": "xi", "9235": "bing", "562C": "zuo;chuai;zhuai", "8AC3": "chen", "928D": "zhi", "55B4": "wei", "57D8": "shi", "60AC": "xuan", "6D2A": "hong", "8B13": "chen", "9197": "fa;po", "91EE": "qi", "4F16": "tang", "60EB": "bei", "759D": "shan", "8C6E": "fen", "8EAA": "lin", "96AE": "ji", "9AFD": "zhua", "61BB": "tan", "6E44": "mei", "7073": "none", "769C": "hao", "7936": "guan", "87ED": "jiao", "8A75": "shen", "54E8": "shao", "57AB": "dian", "5FEC": "yu", "6357": "bu", "6F94": "hao", "773D": "mo", "783A": "li", "88FE": "ju", "5B50": "zi", "72CF": "tuo", "8087": "zhao", "885D": "chong", "89ED": "ji", "8C2D": "tan", "980C": "song", "9DC0": "ci", "50AC": "cui", "7B47": "qiong", "81AA": "chuai", "8321": "zi", "9024": "suo", "5BD2": "han", "7879": "song", "7A60": "nong", "8023": "lun", "8327": "jian", "872F": "bang;beng", "50A1": "bing", "592F": "hang;ben", "5A75": "chan", "783B": "long", "9334": "lu", "93ED": "xi", "5BCA": "zhen", "5D21": "han", "5F9A": "none", "6110": "mian", "7D7C": "zhen", "8B6A": "ai", "963C": "zuo", "9649": "xing", "4E8F": "kui", "849E": "li", "8EB4": "lang", "51C8": "jing", "6D96": "li", "6ED3": "zi", "856B": "tong", "9D7D": "duo", "6696": "nuan", "74B4": "none", "7551": "tian", "8B38": "ao", "5095": "jue", "5E06": "fan", "6F40": "cong", "889D": "fu", "9D5D": "e", "4E86": "le;liao", "58B7": "ye", "5AAA": "ao", "6121": "zong", "6DF4": "hu", "8363": "rong", "55E5": "hao", "6414": "sao", "671B": "wang", "6EA9": "wu", "8C2B": "jian", "8DF3": "tiao", "54DD": "nong", "7F12": "zhui", "4F0E": "ji", "57B7": "xian", "6319": "ju", "65F0": "gan", "66F5": "zhuai", "7FE3": "sha", "87A8": "man", "8AB6": "sui", "8B64": "ji", "8FC3": "yu", "9928": "guan", "5DA3": "qiao", "5E9C": "fu", "6147": "yin", "66C4": "ye", "8FEB": "po;pai", "9122": "yan", "92E9": "mang", "9B8F": "xing", "5036": "ju", "5A71": "xian", "5AD0": "niao", "609C": "cheng", "6FB7": "man", "531A": "fang;xi", "5FBA": "jiao", "7891": "bei", "7A92": "zhi", "8791": "xiu", "8B68": "nou", "93D7": "keng", "9676": "tao;yao", "538F": "zha", "61E4": "chou", "64F9": "tan", "6E55": "jian", "71F7": "lan", "7F9C": "zhu", "8148": "jing", "891D": "none", "984D": "e", "5C53": "xi", "7B19": "sheng", "7D2F": "lei", "7D6F": "hai", "899F": "zhi", "99C2": "bao", "4F61": "xuan;san", "5740": "zhi", "5B34": "ying", "67BC": "ye", "81CD": "qi", "8C80": "duo", "982B": "fu", "50B8": "qiang", "541F": "yin", "6BB8": "qing", "7E8D": "lei", "8C39": "hong", "5276": "juan", "6A59": "cheng", "85CC": "mi", "86D0": "qu", "955C": "jing", "964B": "lou", "4EAE": "liang", "5229": "li", "5D16": "ya;ai", "8EE5": "qu", "8F84": "zhe", "5508": "yi", "5CCE": "lang", "65D5": "none", "7128": "feng", "84CF": "luo", "8CC1": "bi;ben", "91B1": "fa;po", "5202": "dao", "5265": "bo;bao", "5B9A": "ding", "6075": "hui", "6240": "suo", "75B1": "pao", "8E5F": "ji", "52F1": "mai", "53E2": "cong", "7206": "bao", "7EF2": "gun", "85C9": "jie", "5168": "quan", "5FAA": "xun", "9ECE": "li", "788D": "ai", "8D35": "gui", "9734": "dai", "5E25": "shuai;shuo", "5E8A": "chuang", "68D2": "bang", "76FB": "xi", "8F98": "lu", "523C": "jie", "57BB": "ba", "8CC9": "xu", "9C46": "zhang", "50A0": "fa", "54BA": "xuan", "76C7": "he", "8924": "yuan", "916A": "lao;luo", "9A26": "si", "9002": "shi;kuo", "95D1": "nie", "9BE8": "jing", "4FE2": "xiu", "54B8": "xian", "65A6": "yin", "8824": "qiu", "8A8F": "lang", "8FCF": "ti", "93D3": "huo", "9CDD": "shan", "5D81": "lou", "93AE": "zhen", "5171": "gong", "586B": "tian", "5DD3": "dian", "743D": "du", "7E7C": "ji", "83CA": "ju", "8D45": "gai", "9029": "ben", "5E36": "dai", "8091": "di", "8227": "fan", "4FC6": "xu", "54EE": "xiao", "575E": "wu", "5A8D": "fu", "6474": "shu", "7B5B": "shai", "81E5": "wo", "8221": "chuan", "8755": "shi", "9F83": "ju", "6C05": "chang", "6FCF": "se", "7CF3": "zuo", "55B7": "pen", "5628": "xiao", "6322": "jiao", "984B": "sai", "8C01": "shei;shui", "5110": "bin", "5C19": "shang", "6EC8": "hao", "94EA": "ha", "9A95": "su", "9BE4": "kun", "7097": "guang", "8E7B": "qiao", "98E4": "si", "99A1": "fei", "50B1": "song", "734F": "mo", "8D5D": "yan", "8F8C": "liang", "98C3": "piao", "9F7E": "ya", "5731": "qian", "5CBF": "kui", "6995": "rong", "69F2": "hu", "6A30": "none", "7AB3": "yu", "7314": "zong", "73EB": "chong", "76AF": "gan", "868E": "yue", "8763": "you", "9EC1": "nen", "5CD0": "gai", "6B14": "jue", "79A1": "ma", "8655": "chu", "8714": "dian", "98EA": "ren", "51AB": "bing", "792E": "pao", "5B2C": "xu", "8647": "quan", "560E": "ga", "61DA": "yin", "68FA": "guan", "6E2C": "ce", "8DAA": "huang", "7B38": "po", "89A0": "jun", "8A4D": "shi", "9241": "zhen", "95D7": "guan", "500C": "guan", "60D2": "he", "7512": "wu", "8576": "ling", "8BE2": "xun", "4E29": "jiu", "5D88": "qiang", "775E": "lai", "78D4": "zhe", "843D": "luo;la;lao", "6A89": "cheng", "7390": "ba", "8065": "yu", "933F": "none", "57B2": "kai", "6301": "chi", "84D6": "bi", "8DA9": "chi", "8100": "cheng", "8309": "mo", "9425": "shan", "4F9A": "xun", "51BB": "dong", "538D": "she", "5817": "tu", "6825": "zi", "8E06": "qun", "5CA2": "ke", "66F8": "shu", "7BA4": "ju", "971B": "ling", "796A": "gui", "55A8": "liang", "6294": "pou", "6B8A": "shu", "9062": "ta", "9F14": "gu", "5509": "ai", "5B1E": "dong", "6379": "ben", "7CAB": "mian", "7CDA": "zhuang", "8956": "ao", "53F8": "si", "655D": "bi", "67E2": "di", "7117": "ju", "8AC7": "tan", "96C9": "zhi", "639D": "huo", "7681": "zao", "9697": "wei;kui", "5329": "kuang", "68BF": "lian", "7EFF": "lu", "9B71": "hu", "5451": "tun", "60F4": "zhui", "7484": "ying", "7635": "zhai", "8E43": "nuo", "58BB": "qiang", "6B59": "she;xi", "6FE3": "wo", "7958": "suan", "886E": "gun", "9C56": "gui", "6459": "lian", "67B5": "xiao", "6DE8": "jing", "70E7": "shao", "716E": "zhu", "7AE1": "yi;gong;sheng;bai;bei;si", "5684": "huo", "6BDC": "none", "9209": "na", "4F13": "bei", "566B": "yi", "6080": "yong", "66D7": "ye", "6FEA": "jing", "71A5": "teng", "8CA8": "huo", "598F": "wen", "6225": "deng", "6AA9": "lin", "6DF7": "hun", "76D6": "gai;ge", "7B06": "ba", "7F5B": "gu", "7FC6": "cui", "986B": "zhan;chan", "6A97": "bo", "6B3A": "qi", "869C": "ya", "86A6": "ran", "909B": "qiong", "621B": "jia", "7973": "zhen", "9C6F": "huo", "9E16": "he", "763E": "yin", "77CD": "jue", "86D5": "hui", "9980": "yu", "9E76": "jin", "78DC": "qi", "61B4": "sheng", "6229": "jian", "67AF": "ku", "7D97": "jiong", "85D9": "yi", "4F92": "an", "51C7": "song", "5F90": "xu", "6B52": "ti", "6DBF": "zhuo", "7FAF": "jie", "829E": "qi", "8E07": "mou", "5C17": "shu", "6826": "chou", "786A": "wo", "7F21": "li", "889E": "gun", "6404": "geng", "8B26": "qing", "9B9A": "jie", "61C0": "wei", "6454": "shuai", "6482": "liao", "8E85": "zhu", "980D": "kui", "9C05": "yu", "5272": "ge", "5E09": "fen", "6273": "ban;pan", "62EE": "jie", "6F04": "ya", "7864": "xia", "78F5": "jian", "56D3": "nie", "6782": "yue", "6AF6": "xian", "72C4": "di", "78CF": "lian", "7E76": "yi", "867F": "chai", "9A91": "qi", "5CF5": "hong", "9B4A": "yu", "5002": "bing", "8519": "xuan", "90EA": "qi", "5CF9": "tu", "5EEF": "xian", "6260": "cha", "59C0": "he", "655E": "chang;tang", "91E5": "qiao", "69C4": "tao", "8014": "zi", "96E4": "xue", "9D3A": "ti", "5C71": "shan", "84DE": "none", "92D0": "hong", "548D": "hai", "624C": "shou", "8B5F": "zao", "8F64": "lu", "9178": "suan", "7504": "zhen", "8711": "dan", "87B4": "chen", "8AF9": "yang", "5145": "chong", "5472": "ci;zi", "5CB7": "min", "8A29": "xiong", "9169": "ming", "9863": "qi", "5B49": "quan", "680C": "lu", "6E59": "yi", "6EAF": "su", "7609": "yu", "7718": "shen", "78F6": "xi", "7961": "chai", "8324": "duo", "8850": "none", "95BA": "min;wen", "9D65": "none", "5DB0": "xie", "605E": "yi", "67FC": "yao", "7DE4": "xie", "6F6D": "tan", "8D36": "kuang", "9AB4": "ci", "4E9F": "ji;qi", "5481": "gan", "5743": "xun", "5792": "lei", "84F6": "wei", "9653": "wu", "9792": "qiao", "597E": "xian", "5FA9": "fu", "74EB": "pen", "92F8": "ju", "5FCF": "chan", "6539": "gai", "785E": "que", "5103": "shan", "8A6A": "hen", "8E4A": "xi;qi", "9818": "ling", "9C3C": "xi", "9D7A": "ye", "53C0": "zhuan", "56EA": "cong;chuang", "6BD2": "du", "6E8F": "tang", "7DAE": "qi;qing", "5A04": "lou", "60D1": "huo", "6644": "huang", "6FF4": "xing", "8825": "nie", "8CA6": "wan", "81AC": "cui", "9F5B": "shi", "519E": "mi", "5C33": "gu", "5C44": "bi", "96A1": "sa", "5A18": "niang", "732F": "tuan", "8C9D": "bei", "50C6": "lian", "65D2": "liu", "7274": "di", "8A6B": "cha", "9449": "ta", "9521": "xi", "4E66": "shu", "6146": "tao", "8017": "hao", "95E3": "dang", "9642": "po;bei;pi", "96C1": "yan", "97B8": "bi", "5291": "ji", "5CB0": "you", "727B": "mang", "75AE": "chuang", "90C1": "yu", "4FA6": "zhen", "5D9A": "liao", "76E0": "lu", "7AE3": "jun", "8278": "cao", "83EC": "zhao", "8510": "di", "944F": "ning", "5577": "lang", "5647": "zan", "8938": "lu", "6184": "zhi", "6355": "bu", "788F": "que", "5A6B": "kun", "5BA8": "tiao", "6558": "xu", "7A75": "wa", "8139": "zhang", "6EC5": "mie", "76DB": "sheng;cheng", "962A": "ban", "5AA4": "si", "8CF2": "bao", "65EA": "xie", "7DDD": "ji;qi", "9EB0": "mou", "97DC": "tao", "4EBB": "ren", "54DB": "none", "656D": "yang", "7394": "chuan", "720B": "xun", "7A55": "qie", "8D18": "none", "90A7": "yuan", "9E38": "er", "6453": "feng", "7142": "he", "7481": "cong", "75B9": "zhen", "8095": "ren", "8916": "tuan", "5BC5": "yin", "6144": "li", "615C": "min", "79F6": "zi", "4E2A": "ge", "4E49": "yi", "7638": "que", "81CC": "gu", "8385": "li", "8B6D": "hui", "59EF": "guang", "5D0F": "min", "54B0": "shuai", "5505": "han", "5DF1": "ji", "6B8C": "jue", "79FF": "fu", "8176": "duan", "8206": "yu", "84FC": "liao;lu", "8CE3": "mai", "9C68": "chang", "54E2": "long", "6A45": "mo;mu", "6EE8": "bin", "740B": "xi", "8D05": "zhui", "6F37": "kuo;huo", "7BB4": "zhen", "83BF": "ci", "8C76": "fen", "8E3C": "tang", "8F65": "lin", "91D4": "yi", "93C0": "lu", "9B67": "hang", "5732": "qian", "7000": "you", "7F3E": "ping", "527D": "piao", "7084": "niu", "7034": "ying", "70C5": "xu", "761C": "xi", "94AE": "niu", "9AF8": "none", "4F51": "you", "50DC": "deng", "5CFB": "jun", "7E04": "sheng", "80AA": "fang", "94FF": "keng", "9617": "tian", "58A9": "dun", "5A76": "shen", "636C": "fu", "6D2F": "qie;jie", "6F81": "se", "7C34": "ju", "9DC7": "kou", "565E": "yan", "60E3": "zong", "5EF5": "xun", "8EC6": "ti", "9205": "yue", "97DB": "bei", "9BCA": "sha", "5E35": "wan", "7542": "liu", "7557": "da", "76EA": "dang", "781F": "zha;zuo", "9A39": "li", "9CDF": "zun", "9D63": "la", "6B19": "lei", "8AA3": "wu", "8E95": "chu", "6149": "xu", "618A": "bei", "6AA7": "song", "7A5A": "jiao", "7DE1": "min", "815E": "zhuan;dun", "8AA5": "gao", "9985": "xian", "55B5": "miao", "5EC6": "hui", "681A": "zhen", "76C3": "bei", "9719": "ying;ji", "988D": "ying", "996B": "yu", "517D": "shou", "5E5E": "fu", "7B31": "gou", "878B": "sou", "9F69": "nie", "6FB6": "chan", "6FD3": "lian", "7F1E": "cui", "8CBA": "kuang", "9D7F": "sheng", "502A": "ni", "6958": "mu", "77F5": "qi", "8060": "ping", "818F": "gao", "7984": "lu", "7989": "you", "896A": "wa", "8A14": "yin", "58A7": "que", "5B74": "ni", "73B2": "ling", "8604": "qi", "883F": "zha", "608C": "ti", "622D": "yan", "65B8": "zhu", "70B0": "pao", "5454": "dai;tai", "557C": "ti", "6C1F": "fu", "700B": "shen", "8D68": "xiong", "9B54": "mo", "7A5C": "tong", "7F90": "you", "97C1": "jiang", "65CA": "fang", "66BE": "tun", "9A70": "chi", "9D2C": "ying", "594C": "dian", "5F4F": "jue", "6A6E": "liu", "86E9": "qiong", "6028": "yuan", "6384": "lun", "6A0B": "tong", "6BB3": "shu", "9A85": "hua", "9F57": "ken", "57C9": "jia", "76B3": "qiu", "7B3C": "long", "7F98": "zang", "8FDB": "jin", "9C39": "jian", "5A85": "dan", "68EF": "ren", "6FC7": "se", "8328": "ci", "855B": "ti", "9138": "meng", "58E0": "long", "5F94": "none", "6367": "peng", "6D72": "feng", "78DF": "lu", "7992": "xian", "7B41": "qu", "8EA7": "xi", "9B4E": "liang", "510B": "dan", "5987": "fu", "604B": "lian", "7B79": "chou", "9921": "xian", "7604": "xi", "8C15": "yu", "6C3A": "shui", "722C": "pa", "7393": "di", "5DE4": "lie", "7516": "ying", "7CA3": "ce", "8BD0": "bi", "914B": "qiu", "9B02": "bin", "635B": "lu", "73DA": "yan", "7E52": "zeng", "8CC5": "gai", "5B63": "ji", "61A9": "qi", "6D01": "jie", "72F1": "yu", "805B": "bi", "9116": "yun", "593F": "ba", "695E": "leng", "7F8E": "mei", "6DFA": "qian;jian", "72A3": "lie", "74B3": "tian", "76A6": "jiao", "8FA2": "la", "5474": "xu", "5994": "keng", "6690": "wei", "6F06": "qi;qu;xi", "5FAB": "wei", "68CB": "qi", "6C59": "wu", "7269": "wu", "7510": "lin", "82B2": "hua", "82FA": "mei", "9679": "none", "4FCF": "qiao", "5598": "chuan", "5CAC": "jia", "5FF3": "tun", "83CB": "wei", "8ABD": "na", "505D": "bei", "5B44": "lan", "6BE8": "xian", "8837": "qu", "8BB9": "e", "7F6F": "an", "9536": "si", "9E62": "yi", "63D4": "zong", "6F9D": "none", "7569": "none", "913A": "kuang", "97DE": "yun", "9B10": "qi", "59BA": "mo", "68A2": "shao;sao", "9A19": "pian", "9A6F": "xun", "5B54": "kong", "87E5": "huang", "99EA": "shen", "57A7": "shang", "59AA": "yu", "5B41": "ling", "5FE6": "ye", "7FD0": "zhi", "9343": "huo", "9816": "pan", "53FD": "ji", "6034": "xu", "6403": "zong", "795C": "hu", "820B": "xin", "854C": "lei", "8B3F": "chao", "58B3": "fen", "6B9B": "ji", "8425": "ying", "5A16": "chuo", "6BCA": "xiao", "6BEC": "qiu", "7F83": "mi", "7FFA": "ao", "84C4": "xu", "5114": "chou", "575B": "tan", "5C82": "qi", "5F93": "cong", "628C": "zhen", "702A": "fan", "90EC": "qing", "922C": "duo", "991E": "jian", "5496": "ka;ga", "6BBC": "ke;qiao;que", "8320": "xiu", "8888": "jia", "8997": "si", "8DD6": "zhi", "9285": "tong", "5B17": "shan", "6031": "zong", "8A0B": "diao", "92DC": "zhuo", "9CB2": "kun", "9F28": "tong", "9FA5": "yue", "6279": "pi", "6339": "yi", "64DF": "mi", "6AD8": "hui", "8F58": "huan", "9E35": "tuo", "64F0": "ning", "8553": "yun", "9E0F": "meng", "6FC0": "ji", "776B": "jie", "90BB": "lin", "9114": "wu", "56B8": "dian", "6176": "qing", "68CF": "de", "726D": "si", "7475": "zhao", "7612": "wen", "7C86": "sha", "7697": "chou", "8AF7": "feng", "91F5": "chai", "55ED": "none", "78BF": "su", "568C": "ji", "6122": "sai", "7917": "pin", "7929": "zhi", "91E0": "luan", "989F": "man", "99D8": "tai", "9C62": "sao", "503E": "qing", "5161": "bai;ke", "604A": "xie", "8E57": "lu", "576A": "ping", "6C12": "jue", "9A90": "qi", "9C9A": "ji", "4F0D": "wu", "6C43": "bin", "826D": "shuang", "95A1": "he", "979D": "zhang", "68BA": "none", "4F0B": "ji", "50AA": "zan", "518E": "gua", "6810": "yong", "6C33": "yun", "7F3A": "que", "58B6": "da", "6F61": "dun", "864F": "lu", "5BF4": "qin", "658A": "qi;ji", "77FA": "tuo", "4E6E": "none", "58D4": "dao", "6277": "ao", "7C4B": "mi", "864E": "hu", "8FFF": "xun", "5773": "ao", "58B9": "none", "5BAD": "qun", "60EF": "guan", "8177": "bi", "873E": "guo", "9836": "hu", "9E34": "xue", "9E3C": "zhou", "733A": "yao", "84E6": "mo", "4EC4": "ze", "5438": "xi", "5B9D": "bao", "5F67": "yu", "7014": "gu", "7A41": "rong", "7D79": "juan", "80B1": "gong", "64CA": "ji", "6FE1": "ru", "76FE": "dun;shun", "8F61": "pei", "9207": "fu", "952A": "huo", "5C2E": "duo", "68A9": "li", "7F8B": "mie", "86BF": "xian", "960C": "wen", "701B": "ying", "7232": "wei", "8EE8": "ling", "92F9": "chang", "58B1": "deng;yan", "5F24": "di", "6938": "yi", "725F": "mou;mu", "8058": "pin", "9007": "dun", "68E1": "gang", "8F05": "lu", "9815": "dan", "99DD": "tuo", "62C5": "dan", "73D3": "jiao", "77C0": "wei", "7EB3": "na", "8269": "qi", "83A8": "lang;liang", "896C": "bai", "8B4E": "jue", "5024": "zhi", "5079": "bei", "660D": "xuan", "67C5": "ni", "67D5": "mao", "70E2": "zhe", "8681": "yi", "9060": "yuan", "99BA": "sa", "9B21": "ning", "503D": "sha", "8640": "ji", "8803": "luo", "9547": "zhen", "99AD": "yu", "9B82": "qiu", "6347": "huo", "74A5": "jing", "7B0D": "zhui", "813C": "liang", "8251": "bian", "8476": "ting", "8607": "su", "63BF": "nuo", "72DC": "gu", "73D1": "long", "5EA3": "tiao", "6597": "dou", "7DAB": "xian", "96FF": "zhao", "67F5": "zha", "73A1": "ya", "90EB": "pi", "9330": "shu", "5231": "chuang", "6551": "jiu", "76D2": "he", "7783": "wen", "791E": "meng", "7DFC": "yun", "9276": "xing", "7E82": "zuan", "80D8": "xian", "85B5": "chou", "6F6C": "dan", "7944": "xie", "7FDA": "hui", "8550": "hua", "89F0": "zhu", "931C": "nie", "6812": "xun", "72BF": "huan", "807F": "yu", "8A60": "yong", "9483": "shu", "7210": "lu", "7322": "hu", "7E81": "xun", "526D": "wu", "57E6": "wan", "6084": "qiao", "72EC": "du", "741B": "chen", "8432": "xuan", "525E": "ji", "5728": "zai", "5BED": "hui", "5ED6": "liao", "6051": "gui", "7414": "dian", "7980": "bing", "526F": "fu", "723F": "pan;qiang;ban", "75A0": "li", "862F": "dang", "86F2": "nao", "8BC9": "su", "91F2": "si", "62BF": "min", "62DF": "ni", "72D6": "you", "7640": "huang", "7877": "jian", "787B": "keng", "9133": "meng", "91D9": "li", "5A32": "wa", "5E2C": "qun", "673B": "jiu", "7167": "zhao", "781B": "none", "7C33": "gan", "7EC6": "xi", "5344": "nian", "5635": "xiao", "8C7A": "chai", "9B76": "na", "5DC1": "li", "6B11": "zan", "72A4": "pi", "836C": "mai", "842A": "ke", "95C2": "xiang", "6FD0": "zhu", "72BD": "ya", "8891": "shao", "8B69": "yi", "8C0E": "huang", "756A": "fan;pan", "7A63": "rang", "9555": "rong", "959E": "bian", "9C99": "kuai", "6C60": "chi", "82DA": "rao", "92AC": "kao", "6291": "yi", "6AA8": "she", "6EE9": "tan", "8ADB": "yu", "96AD": "er", "5D93": "bo", "671E": "ji;qi", "6EFF": "man", "7AB4": "tian", "7EC3": "lian", "9652": "gui", "6927": "none", "782F": "ping", "8185": "tang", "8CC3": "lin;ren", "9882": "song", "9DC2": "yao", "59CC": "ran", "6086": "yu", "66B1": "ni", "7522": "chan", "78B3": "tan", "7EA9": "kuang", "82A2": "ren", "8A0D": "cha", "8D00": "wei", "9F63": "chu", "5A77": "ting", "5E12": "dai", "7A07": "kun", "803E": "hong", "889F": "zhi", "916B": "chuo", "7902": "xi", "9482": "tang", "9F8E": "pang", "5500": "you", "7818": "dun", "78EF": "ji", "856D": "xiao", "8FDF": "chi", "9013": "di", "601A": "ju", "6924": "luo", "8A44": "die", "547F": "qu", "56C3": "ca", "60FC": "bian", "72C8": "bei", "74BB": "zui", "7DC8": "xing", "973D": "ji", "9A98": "zhi", "53E0": "die", "7C12": "cuan", "82AD": "ba", "625B": "kang;gang", "6D86": "han", "7198": "liu", "7E0C": "ni", "8297": "xiang", "84C6": "xi", "8C4F": "xian", "8D4E": "shu", "90AB": "bang", "946C": "jian", "9601": "ge", "5902": "zhi", "67A0": "none", "94DB": "dang;cheng", "5E68": "dan", "5E87": "bi", "600E": "zen", "6039": "tan", "9BA8": "qi", "4FB8": "shu", "66E6": "xi", "7C64": "qian", "80FF": "none", "9286": "mo", "5F5C": "yi", "7180": "huang", "9C11": "yang", "7533": "shen", "9C98": "hou", "543D": "ou;hong", "68A4": "fen", "71D2": "shao", "83C6": "zou", "8E76": "jue", "9318": "chui", "99CD": "peng", "57CB": "mai;man", "64B9": "jiao", "7CF4": "di", "94F9": "lao", "5A9F": "xie", "6EB1": "zhen;qin", "71A6": "jue", "9F86": "tiao", "55AC": "qiao", "5F66": "yan", "7E79": "yi", "8035": "ding", "8219": "hua", "9161": "tuo", "5CD7": "wei", "600C": "pi", "73A3": "bian", "8CAD": "zhi", "9713": "ni", "9DDC": "lou", "4EFD": "fen", "633C": "nuo", "7A24": "none", "9943": "mo", "8A01": "yan", "96C3": "ya", "6111": "yong", "652F": "zhi", "6F82": "cheng;deng", "7F50": "guan", "8A71": "hua", "54A8": "zi", "6CC2": "jiong", "7A66": "none", "8085": "su", "975E": "fei", "5458": "yuan;yun", "5C11": "shao", "6888": "peng", "7722": "yuan", "7E3A": "lian", "8D17": "yan", "9094": "qi", "5012": "dao", "54C7": "wa", "5778": "gou", "5888": "kan", "84A8": "qian", "84EA": "tong", "935D": "yu", "59C9": "zi", "6920": "qian", "6B83": "yang", "6BF1": "ju", "6E99": "tai", "6FDD": "qi", "8BE0": "quan", "4F8F": "zhu", "5E00": "za", "6DE9": "ling", "7520": "qing", "7EC1": "xie", "86A0": "fen", "4E7C": "none", "5041": "cheng", "8D89": "zhu", "8E0D": "xiao", "9AB1": "jie;xie", "9E2F": "yang", "9EFB": "fu", "50B9": "qiang", "53FE": "none", "576C": "wa", "68C7": "cong", "791A": "ke", "9786": "mo", "979E": "bing", "989A": "e", "55B6": "ying", "95C7": "an", "9D4D": "huan", "5394": "zhi", "5CCB": "xun", "65FB": "min", "69FE": "man", "6E45": "lian", "75DC": "tu", "75EA": "huan", "89C0": "guan", "5658": "jue", "60CD": "jin", "6D36": "xiong", "6D41": "liu", "7E46": "mou;miao;miu", "8E41": "pian", "9DA6": "hu", "57D2": "lie;le", "59EB": "ji", "5DA0": "jiao;qiao", "62B9": "mo;ma", "7F66": "fu", "80A7": "pei", "9D34": "heng", "5189": "ran", "5D08": "chong", "5E99": "miao", "7C31": "qi", "89B3": "guan", "5F72": "chi", "6120": "yun", "632B": "cuo", "9CF6": "yuan", "6CF6": "xue", "6D84": "pin", "7093": "liao", "8F4B": "hun", "5DCC": "yan", "617A": "lu", "65F1": "han", "707F": "can", "72DA": "dan", "7D72": "si", "7F30": "jiang", "96E1": "liu", "51F0": "huang", "5ECE": "qing", "5463": "mou", "5FFF": "fen", "6689": "hui", "86FC": "che", "9125": "wu", "5619": "po", "5B86": "qiong", "6C07": "lu", "86A1": "fen", "8A23": "jue", "9402": "liu", "9C33": "le", "9E36": "si", "5E23": "juan", "614A": "qian;qie", "6EB8": "su", "83E0": "bo", "971D": "ling", "52BC": "jie", "773B": "yang", "8623": "tou", "8932": "ku", "531B": "jiu", "74D7": "xi", "7743": "suo", "78D6": "la", "8457": "zhu;zhe;zhao;zi;zhuo", "89A8": "e", "8C55": "shi", "958D": "beng", "95F9": "nao", "996C": "chi", "99DA": "yang", "9EAD": "pao", "55E2": "wa", "65B0": "xin", "6613": "yi", "6E28": "wei", "77C7": "meng", "980E": "qi", "9F70": "cuo", "54E1": "yuan;yun", "5E3E": "du", "6D9C": "du", "7BA0": "chui", "8070": "cong", "8758": "yan", "9833": "cheng", "6D19": "zhu", "72C1": "yun", "8B17": "bang", "9503": "zeng", "9F9B": "kan", "55DD": "ge", "575C": "li", "530D": "pu", "560D": "lou", "6BF9": "shu", "6EA3": "lun", "734B": "hao", "8306": "mao", "86C6": "qu;ju", "9283": "chong", "59D0": "jie", "5A12": "mu", "9581": "ma", "5C1D": "chang", "6967": "ying", "6AEC": "chen", "6D83": "kun", "7931": "long", "9AD1": "du", "56BF": "huo", "6BCD": "mu", "9795": "ying", "8613": "su", "8628": "yao", "8858": "xian", "4E2B": "ya", "549F": "huo", "68BB": "none", "7E8E": "xian", "8B4C": "e", "8BBF": "fang", "52D6": "xu", "668C": "kui", "66A2": "chang", "6AD0": "lei", "8498": "nu", "91BE": "mi", "5722": "ting", "8C34": "qian", "631B": "luan", "737D": "rang", "8FD3": "ya", "978B": "xie", "5167": "nei", "62D1": "qian", "8D8C": "jie", "9673": "chen", "528F": "tang", "5C56": "xi", "600F": "yang", "6C4F": "dai", "7359": "bi", "742E": "cong", "7790": "mao", "8098": "zhou", "56A0": "liu", "7FCF": "liu", "4EBA": "ren", "525A": "zi", "5A7C": "chuo", "5ABA": "mei", "6C96": "chong", "7ABB": "chuang", "9877": "qing", "6A36": "zui", "9B0E": "la", "676D": "hang", "9056": "none", "4F81": "shen", "5CA8": "qu", "9941": "ye", "4F69": "pei", "6E1E": "qiu", "717F": "bo", "789E": "yan", "92BD": "gua", "529F": "gong", "54A4": "zha", "57F6": "yi", "6505": "zan;cuan", "6A35": "qiao", "6E7D": "zi", "7888": "min", "95DF": "xi", "5155": "si", "7257": "none", "7515": "weng", "8109": "mai;mo", "89A4": "xi", "58EA": "none", "6A50": "tuo", "85D4": "none", "97AB": "ju", "67F0": "nai", "7044": "she", "89CF": "gou", "9018": "yi", "925B": "qian;yan", "4FE3": "yu", "6E95": "meng", "7D5F": "quan", "9058": "gou", "94DA": "zhi", "94F2": "chan", "9E95": "jun;qun", "5B7B": "nai", "61ED": "kuang", "74D5": "mi", "85B0": "xun", "8CDA": "lai", "933B": "none", "9BDD": "gu", "56B5": "chan", "652C": "lan", "6923": "none", "5D56": "cha", "5D76": "none", "8110": "qi", "8198": "biao", "88CD": "kun", "8DF4": "cai", "5468": "zhou", "6B0B": "qu", "6BAD": "jiang", "8462": "ge", "8BAE": "yi", "8C8A": "mo", "90B8": "di", "9AA7": "xiang", "55A2": "sha", "7AD5": "shi;fen;zhi;yi;gong;sheng", "7E85": "li", "8441": "jiang", "8A8C": "zhi", "9A32": "cao", "5A80": "yu", "6DA4": "di", "6F34": "chong", "748E": "ying", "7B83": "zou", "7E3D": "zong", "8A04": "qiu", "5144": "xiong", "5637": "hao", "6213": "ge", "6A5B": "jue", "730B": "biao", "7A9F": "ku", "7EFA": "liu", "5578": "xiao", "6961": "yu", "7F23": "jian", "57A5": "xie", "6798": "rui", "5335": "du", "53C4": "san", "808B": "lei", "9342": "none", "5361": "ka;qia", "538E": "zhi", "5777": "ke", "666C": "zui", "6983": "tan", "6DD6": "nao", "7922": "none", "82EF": "ben", "9AEF": "ran", "5D28": "jie", "7B2E": "ze;zuo", "82BA": "ao", "86B9": "fu", "924F": "chu", "9527": "zhi", "6350": "juan", "70C3": "ting", "75A5": "jie", "8893": "ju", "8F86": "liang", "9A14": "jie;ge", "7A25": "none", "89E1": "ge", "9ED5": "zhen", "5877": "lu", "5D2B": "jue", "6E9A": "ta", "837A": "yun", "94BA": "yue", "9CF1": "gan", "5F3E": "dan;tan", "6477": "zhao", "6982": "gai", "8F39": "fu", "56AB": "chen", "57C4": "peng", "876E": "fu", "952E": "jian", "9962": "nang", "79D3": "zhi", "8129": "xiu", "86ED": "zhi", "906D": "zao", "977D": "ban", "9AC6": "bo", "6797": "lin", "87C5": "zhe", "9E8B": "mi", "8966": "ru", "9D7B": "zhui", "9E48": "ti", "5AAF": "gui", "90A6": "bang", "96C4": "xiong", "9B14": "peng", "57D1": "zhe", "698B": "none", "4F22": "ya", "61AE": "wu", "7235": "jue", "8415": "qi;ji", "8BCC": "zhou", "914F": "yi", "97E0": "bi", "99F7": "song", "54B4": "hui", "5A5F": "hu", "613E": "kai", "8986": "fu", "8FCE": "ying", "56D2": "lan", "79C9": "bing", "8284": "wan", "86EE": "man", "6832": "kao", "68BC": "tao", "6C19": "xian", "76F8": "xiang", "7842": "quan", "810F": "zang", "8EFC": "yi", "56C6": "chai", "6053": "xi", "7BAA": "dan", "85F7": "zhu;shu", "8683": "xiang", "4EB6": "dan", "582E": "e", "587D": "shuang", "5A0F": "mang", "6AB3": "bin;bing", "707C": "zhuo", "88EE": "chang", "8D27": "huo", "9F3B": "bi", "5959": "ben", "571F": "tu", "609E": "wu", "9453": "qiang", "57AA": "none", "5CD5": "shi", "78A9": "shuo;shi", "91C7": "cai", "9737": "yang", "9D74": "ju", "4EBC": "ji", "5A34": "xian", "5B2A": "pin", "67B3": "zhi", "6C23": "qi", "7292": "kao;di", "81AD": "gui", "9BEA": "ling", "5F3D": "she", "5F85": "dai", "6137": "kai", "6F53": "hui", "748A": "man", "5459": "guo", "6AA0": "qing", "6ABF": "yan", "80D4": "zi", "814A": "la;xi", "8F55": "ge", "92D3": "chan", "9CF8": "hu", "4E28": "shu", "6761": "tiao", "683A": "zhi", "7838": "za", "8330": "yu", "8886": "hui", "9B49": "liang", "6097": "man", "6BEE": "none", "706E": "guang", "7B64": "lang", "7D90": "dui", "87D8": "te", "8B57": "zha", "9607": "du;she", "5D53": "yan", "72F7": "juan", "7659": "shu", "84D0": "ru", "899D": "lian", "8A09": "fan", "6740": "sha", "85E9": "fan", "96D6": "sui", "9769": "ge;ji", "50F3": "su", "527B": "fou", "5844": "leng", "61D0": "huai", "630E": "kua", "6737": "dao", "941D": "jue", "5B61": "tai", "8A74": "hui", "8EB5": "none", "5DD5": "nie", "64F6": "jian", "6579": "liao", "71C6": "qiao", "7C99": "zhou", "7FFE": "xuan", "83B6": "xian", "8901": "zhi", "7CA1": "tong", "85F0": "liu", "8AF6": "chen", "97A6": "qiu", "688A": "di", "91B3": "yi", "61DF": "dui", "6D76": "lao", "8C38": "qian", "95E6": "wen", "554E": "wu", "6694": "nan", "8897": "zhen", "9389": "ta", "93A6": "liu", "4FDF": "si;qi", "5845": "duan", "9846": "ke", "9D19": "zhi", "5FD6": "cun", "8686": "pa", "4E09": "san", "94F3": "chong", "9894": "han", "5319": "chi;shi", "53B2": "li", "5CB6": "po", "68CA": "qi", "7242": "zang", "8693": "yin", "8783": "pang", "9368": "kui", "835C": "bi", "6BB4": "ou", "77D2": "meng", "7A56": "ji", "8294": "hui", "8DDF": "gen", "9643": "bing", "570F": "quan;juan", "6B36": "shuo", "8FF5": "tong", "9DB2": "weng", "539D": "cuo", "634E": "shao", "66DA": "meng", "6F1C": "ye", "721A": "yue", "7E0E": "gu", "820D": "she", "88DC": "bu", "8E4D": "zhan", "9898": "ti", "5427": "ba", "5589": "hou", "58FF": "zun", "5EAC": "pang;mang", "5F26": "xian", "5F98": "pai", "7C09": "zao", "7C69": "bian", "8465": "qian", "89E3": "jie;xie", "8A7F": "gua", "8F26": "nian", "60E8": "can", "6BB1": "jian", "8FFC": "jie", "9572": "cha", "5132": "chu", "60B2": "bei", "771F": "zhen", "7C93": "gan", "4FBA": "shen", "529D": "quan", "52FA": "shao;shuo;biao", "6703": "hui;kuai", "673A": "ji", "76CE": "ang", "80A3": "qin", "54A0": "qi", "5F6E": "yong", "6617": "ze", "6E53": "pen", "7100": "hu", "7820": "qu", "79D6": "zhi", "86DB": "zhu", "891E": "yun", "51F5": "qu;kan", "5F7B": "che", "6CF4": "guan", "753C": "ting;ding", "8B25": "cong", "8E7D": "liao", "8F17": "ni", "9AB2": "bo", "5480": "ju;zui", "7A37": "ji", "84A7": "zhen", "99A4": "ai", "644A": "tan", "7ED0": "dai", "9827": "dui", "9B3A": "shang", "7E68": "da", "9426": "kai", "9DD7": "ou", "77AE": "che", "8631": "lei", "8750": "mai", "8D33": "shi", "9552": "yi", "96D9": "shuang", "4E5C": "mie;nie", "6570": "shu;shuo", "4EAF": "heng", "5F5E": "yi", "85D5": "ou", "50D9": "guang", "5B62": "bao", "698D": "xie", "793F": "yue", "8442": "wan", "9A67": "ju", "4ED2": "none", "5483": "tuo", "5BA2": "ke", "6200": "lian", "683F": "fa", "68BE": "lai", "81A2": "lu", "84FB": "ji", "867E": "xia;ha", "9A0C": "zong", "5E0D": "hu", "695C": "hu", "6AA3": "qiang", "7C57": "kuo", "7E34": "qian", "6C8A": "dan", "8359": "da", "5A90": "xi", "6BA3": "jin", "837C": "tu", "83F8": "yan", "8CB7": "mai", "5A81": "wei", "5E61": "fan", "6483": "ji", "665A": "wan", "685A": "zan", "9CEE": "ji", "4EB4": "you", "5377": "juan;quan", "9789": "tao", "53F4": "qiu", "5E78": "xing", "6E67": "yong;chong", "7B08": "ji", "7EF5": "mian", "95BC": "e;yan", "583F": "jian", "60C7": "dun", "85D1": "qiong", "863D": "lei", "6220": "shi;chi", "8CFD": "sai", "90C4": "qie", "5116": "lan", "55D6": "sou", "643B": "nuo", "8521": "cai", "8BD6": "gua", "9440": "ai", "5FFB": "xin", "7BF6": "yan", "80CF": "zi", "9AEE": "fa", "57FA": "ji", "7C18": "xiao", "854A": "rui", "884A": "mie", "948D": "tu", "95A7": "hong", "96DD": "yong", "9A28": "tuo;tan", "9F79": "chi", "4E1A": "ye", "555F": "qi", "8965": "pu", "906C": "su", "737B": "xian", "86EA": "qie", "87A3": "teng", "9992": "man", "54EF": "xian", "5B4C": "luan", "7CA4": "yue", "7FF1": "ao", "8DE9": "zhuai;shi", "91C0": "niang", "9ABC": "ge", "9BD8": "nei", "5E52": "zhong", "6434": "qian", "73DC": "yang", "87DB": "peng", "500B": "ge", "6930": "ye", "7143": "kui", "7E3B": "mi", "53A6": "sha;xia", "6CEC": "xue", "7E6A": "hui", "9D6D": "qin", "9F3D": "yan;qui", "51B7": "leng", "5EC0": "sou", "60C2": "kan", "7A0F": "ya", "8288": "mi", "8B9E": "yan", "8D4D": "ji", "9596": "min", "67A5": "li", "6858": "zhui", "6C08": "zhan", "724D": "du", "6CA9": "wei", "8925": "ru", "8D42": "lu", "9D3F": "ge", "6234": "dai", "7B56": "ce", "9AE2": "ti", "4E57": "cheng;sheng", "52BE": "he", "8954": "man", "89AC": "ji", "997F": "e", "6C2A": "ke", "6CAF": "zan", "7F96": "gu", "7FB3": "fan", "9B55": "ji", "7969": "zhu", "8772": "la", "4EB2": "qin;qing", "60EE": "dan", "7C2E": "zan", "8F38": "shu", "5882": "biao", "5AA6": "wei", "5C3E": "wei;yi", "7547": "yun", "7765": "pi;bi", "7D4E": "heng;hang", "612A": "yun", "679E": "zong;cong", "6B91": "qing", "6D99": "lei", "8E88": "qiao", "9266": "zheng", "536A": "jie", "6635": "ni", "690F": "ya", "7308": "ba;pi", "7350": "zhang", "78F9": "dian", "7E11": "jian", "8D70": "zou", "99D6": "ling", "79CF": "hao", "7D5C": "xie;jie", "8250": "zong", "60B5": "chang", "6CCE": "zhuo", "7C36": "lu", "8D01": "bai", "5912": "nao", "5D7F": "ding", "7B13": "pi", "7B28": "ben", "90D3": "yun", "90E2": "ying", "9447": "ji", "969C": "zhang", "9D0B": "fang", "50BE": "qing", "566F": "ai", "5971": "lian", "7247": "pian", "5B72": "ya", "605C": "chi", "6F0D": "guo", "7168": "wei", "73E0": "zhu", "84D5": "gui", "9297": "hou", "99F9": "mang", "51CC": "ling", "524E": "cha", "6409": "que", "6757": "mang", "72F6": "xi", "7E6B": "xi;ji", "8733": "dun", "9B1F": "huan", "6197": "yin", "5700": "guo", "6A3B": "kui", "7E84": "peng", "8C17": "chan", "553C": "sha", "55A7": "xuan", "6774": "xian", "76E2": "xu", "7E40": "sui", "530F": "pao", "6DE7": "mi", "6EF3": "shang", "4ED5": "shi", "5287": "ju", "65F3": "di", "6E8A": "none", "8625": "yue", "6531": "gui", "6809": "zhi", "790E": "chu", "7F38": "gang", "930E": "xian", "4E73": "ru", "5A9D": "qiu", "5EF0": "ting", "68C1": "zhuo", "977B": "zu", "5B4A": "mi", "7426": "qi", "80C2": "shen", "8692": "ran", "9604": "jiu", "5486": "pao", "648D": "zan", "69CB": "gou", "6B7E": "mo", "770E": "shi", "77DB": "mao", "8343": "quan", "88B6": "jiang", "89F9": "xi", "8E90": "lie", "9EEA": "can", "5251": "jian", "54D0": "kuang", "6D5F": "you", "6DC1": "qie", "6E2B": "xie", "7149": "lian", "7BF2": "hui", "8780": "jiang", "880F": "xie", "8909": "xie", "8B00": "mou", "999E": "bo", "9E17": "long", "9EF1": "dai", "50DE": "wei", "8C03": "diao;tiao", "5E1B": "bo", "6C50": "xi", "8E35": "zhong", "92C9": "su", "9583": "shan", "967A": "xian", "87A2": "ying", "8927": "jiong", "9950": "yi", "9D87": "dong", "51E4": "feng", "5CDF": "you", "5D01": "kan", "69E9": "gai", "8A0E": "tao", "8C9A": "tan", "8E20": "wan", "9021": "qun", "5943": "di", "6B78": "gui", "8C13": "wei", "8C63": "jian", "9D83": "e", "59CE": "yang", "6AB2": "none", "6CF3": "yong", "72BA": "kang", "7897": "wan", "7955": "mi", "7B95": "ji", "8B44": "zeng", "5C58": "man", "7295": "bei", "74D6": "xiang", "8394": "meng", "8690": "jun", "5ACD": "tao;yao", "72A9": "wei", "6066": "xiang", "6706": "fen", "7738": "mou", "80FA": "an", "9622": "wu", "4F9F": "jian", "5666": "hui;yue", "62FE": "shi;she", "638D": "gun", "8CB4": "gui", "8D83": "die", "5D96": "yan", "6045": "lao", "680A": "long", "6987": "chen", "7810": "e", "79B0": "ni;mi", "811D": "heng", "9420": "pu", "9E33": "yuan", "56A5": "yan", "6720": "ying", "7328": "yuan", "7F27": "lei", "7AF6": "jing", "8551": "jian", "85F1": "hui", "8794": "yi", "8E4C": "qiang", "78EB": "zong", "7BF1": "li", "80D7": "zhen", "811E": "cuo", "8DA5": "qiu", "7AD0": "chu", "7E95": "xiang", "91B7": "yi", "5B94": "guai", "5D61": "weng", "691A": "none", "71AC": "ao", "7477": "ai", "8032": "huai", "9B1C": "qian", "54C2": "shen", "9146": "feng", "9DC3": "yan", "509E": "suo", "5B5C": "zi", "6638": "dong", "6C65": "zhi", "76BA": "zhou", "836D": "hong", "842C": "wan;mo", "88FB": "du", "744A": "zhen", "84AE": "yu", "850F": "shang", "9E7A": "cuo", "5F36": "jiang", "6F9E": "yu", "79A6": "yu", "7CBD": "zong", "9A08": "pian", "4F65": "qian", "52D8": "kan", "6DE4": "yu", "7090": "pang", "8B97": "huo", "8F04": "guang", "9730": "xian;san", "519A": "kan", "6A21": "mo;mu", "70C2": "lan", "7A20": "chou", "80B7": "qian", "8B95": "lan", "91D6": "dao", "99F0": "yin", "61C3": "qin", "6342": "wu", "8A36": "he", "535C": "bu;bo", "5417": "ma", "7E3C": "xuan", "7EF0": "chuo;chao", "808C": "ji", "77C9": "bin;pin", "7B15": "jian", "7DFE": "chan", "84AB": "cuo", "5381": "none", "61B5": "pi", "69AA": "ma", "792B": "li", "90A5": "shen", "5F3A": "qiang;jiang", "8D55": "dan", "5E19": "zhi", "6408": "yong", "93D2": "qiao", "6455": "di", "6E78": "liang", "9B45": "mei", "9C1E": "wu", "5676": "ga", "6237": "hu", "744F": "chuan", "5B2E": "yan", "6D9D": "lao", "7F85": "luo", "8DE2": "dai", "90F8": "dan", "6EDA": "gun", "8271": "jian", "8323": "wu", "992A": "nuan", "9EF2": "can", "5D6A": "qiao", "6502": "lei", "6AE5": "chu", "6FC8": "ji", "835F": "hui", "9CF4": "ming", "7CFF": "you", "8D06": "biao", "8DC8": "nian", "96CD": "yong", "4F3F": "yi", "522B": "bie", "6391": "qi", "6F2C": "zi", "642C": "ban", "6D0F": "er", "6F2E": "kang", "87F8": "li", "583C": "heng", "7BD1": "kui", "6B65": "bu", "6B88": "xu", "74B6": "jin", "7DC0": "qi", "82F1": "ying", "8767": "ying", "8856": "long", "9AFB": "ji", "5C37": "gan", "8DC2": "qi", "94A6": "qin", "9E47": "xian", "4EFB": "ren", "5BD6": "jin", "978E": "hen", "98F0": "fan", "5D31": "ze", "61EA": "bo", "6E42": "e", "769A": "ai", "56E5": "kang", "5FAF": "xi", "6057": "hu", "6151": "she", "61FC": "ju", "6DEB": "yin", "7DD8": "jian", "8E36": "di", "51F9": "ao;wa", "5FD8": "wang", "68B1": "kun", "6F9A": "ao", "87C4": "zhe;zhi", "9064": "none", "930D": "pi", "9E9D": "she", "4ECB": "jie", "55CE": "ma", "6F6E": "chao", "7345": "shi", "76DD": "lu", "827E": "ai;yi", "8410": "sha", "8544": "meng", "8559": "hui", "8B8F": "wei", "9184": "tao", "4E0B": "xia", "50CE": "zhuan", "790F": "ji", "793B": "shi", "7BE0": "xiao", "8DFA": "duo", "9023": "lian", "956F": "zhuo", "5223": "zhong", "62D5": "tuo", "7DC2": "tan", "7EED": "xu", "8764": "you;qiu", "62BA": "mo", "4F36": "ling", "54F2": "zhe", "6CB3": "he", "780A": "kang", "818A": "bo", "56A4": "mo", "6328": "ai", "715B": "jiong", "8E08": "shu", "5CF0": "feng", "64C8": "pu", "67FE": "jiu", "683D": "zai", "698F": "yi", "7D48": "pa", "8539": "lian", "887A": "xie", "88DA": "ji", "8BB6": "ya", "8BBB": "xiong", "6595": "lan", "7A91": "yao", "90FF": "mei", "582B": "zong", "6A83": "yin", "6C03": "tong", "7FDB": "shu", "896F": "chen", "8B27": "li", "9D3B": "hong", "6F23": "lian", "7130": "yan", "7275": "qian", "95AC": "lang", "59E4": "gou", "650C": "han", "6D04": "hui", "6D38": "guang;huang", "7AB6": "ju", "8B11": "xi", "90AE": "you", "9487": "yi", "94C2": "bo", "6352": "shu", "653B": "gong", "6D65": "yi", "7ECC": "chu", "88C4": "none", "94E4": "ting;ding", "5D89": "zui", "7402": "yan", "793C": "li", "512B": "hao", "5733": "zhen", "5C29": "wang", "71FF": "yao", "7AA4": "none", "7F69": "zhao", "92B5": "keng", "51AF": "feng;ping", "5EC9": "lian", "7C97": "cu", "8666": "zhan", "8789": "weng", "98F6": "bi", "8C4C": "wan", "9B1A": "xu", "9E5F": "weng", "9F25": "ba", "8589": "wei", "9B41": "kui", "4E19": "bing", "73B9": "xuan", "6639": "ai", "671C": "tun", "9AC7": "xiao", "5C09": "wei;yu", "5DF8": "yi", "5FA1": "yu", "5FEE": "zhi", "79BF": "tu", "894E": "fan", "923B": "si", "9579": "jiu", "590B": "qun", "5DCB": "kui", "74A9": "qu", "8ADF": "shi", "8D0C": "none", "72AF": "fan", "7451": "zhuan", "788E": "sui", "8859": "ya", "55FA": "cui", "6996": "gu", "7129": "ping", "79A7": "xi", "88AE": "none", "94E9": "sha", "9875": "ye", "9E64": "he", "4E83": "lin", "7366": "ge", "7699": "xi", "7A11": "lu", "5CDA": "mi", "65B3": "qin", "68A0": "lu", "752E": "none", "8632": "lei", "8DEB": "qiong", "96F4": "li", "9920": "bing", "4EA1": "wang;wu", "5CB1": "dai", "8C57": "hui", "8EC2": "lao", "9457": "li", "72BB": "bo", "8F73": "lu", "5CE3": "yao", "5ED3": "kuo", "74B9": "shu", "7CB3": "jing;geng", "7F78": "fa", "8421": "none", "90E0": "geng", "9208": "bu", "9641": "tuo", "994A": "san", "7643": "long", "8427": "xiao", "981D": "qiao", "9F48": "nong", "55D4": "chen", "6261": "chi", "6EA8": "cai", "82B6": "gou", "968B": "sui", "5271": "jian", "602A": "guai", "68FF": "nie", "6DB9": "wo", "73DF": "su", "8B7E": "jian", "4E84": "yi", "6999": "ta", "736B": "xian", "7A4E": "ying", "8506": "leng", "8A91": "kuang", "8B33": "ou", "95DE": "kan;han", "57B9": "bang", "5894": "cui", "5E0C": "xi", "65B5": "zhuo", "68B4": "chan", "75AC": "li", "833F": "zhu", "8C5D": "ba", "99B8": "xin", "541E": "tun", "584A": "kuai", "6932": "wei", "6E68": "ju", "748B": "zhang", "8119": "qiu", "89D2": "jiao;jue", "989E": "nie", "9A5C": "ye", "5023": "fang", "5D6C": "wei", "65BA": "xie", "7952": "tiao", "7B69": "tong", "7C30": "pai", "81FF": "cha", "9236": "yi", "9716": "lin", "5836": "tuo", "64D6": "ge", "66CD": "hao", "6A7F": "jiang", "9BA4": "lie", "566D": "jiao", "5DD6": "yan", "60DA": "hu", "63C6": "kui", "6ACE": "guang", "7755": "wan", "7BBC": "wu", "871F": "yu", "9C66": "sheng", "9D0D": "wen", "50E4": "dan", "75A2": "chen", "7726": "zi", "7B62": "pa", "8199": "jiang", "8417": "ce", "8D90": "xue", "9791": "da", "9AA1": "luo", "771B": "mei", "7A50": "qiu", "7E32": "lei", "9070": "zhi", "9174": "tu", "7171": "gua", "8799": "du", "882D": "feng", "8A26": "chen", "5AEE": "hu", "7D6B": "lei", "564B": "tun", "5D18": "lun", "65AF": "si", "7727": "chao", "8993": "mi", "9BF7": "ti", "51BC": "xian", "5CB3": "yue", "79AD": "sui", "8712": "yan", "91DB": "he", "9221": "zhong", "9628": "e", "96EB": "na", "99B6": "zhi", "5719": "lue", "5E9B": "ci", "61F5": "meng", "6A9C": "gui;hui;kuai", "6CFF": "yin", "6FB2": "ye", "7A81": "tu", "8E3E": "fu", "9AB5": "ti", "664D": "tong", "900D": "xiao", "6A70": "gao", "7A7E": "yao", "85FE": "lai", "925A": "liu;mao", "9704": "xiao", "4F1F": "wei", "5008": "lai", "594F": "zou", "59A4": "yu", "66C0": "yi", "802D": "ji", "8DF5": "jian", "8F87": "nian", "916C": "chou", "528E": "jian", "55A4": "huang", "59D2": "si", "76D3": "yu", "7B36": "shi", "7D30": "xi", "874B": "la;zha", "98BC": "sou", "6C11": "min", "735C": "lin", "73D6": "guang", "96E0": "chou", "5194": "xu", "5AE9": "nen", "6335": "long;nong", "6D91": "su", "9DAD": "fang", "9F19": "pi", "5CDC": "ji", "5F5D": "yi", "6062": "hui", "64A9": "liao", "71C8": "deng", "7FAB": "qiang", "839A": "yan", "9199": "sou", "9760": "kao", "521D": "chu", "54B3": "ke;hai;ka;kai", "5F7C": "bi", "64A1": "cao", "7804": "jue", "89B8": "jian", "8FA0": "zui", "5A09": "ping", "6187": "qi", "6BDA": "chan", "7607": "zhong", "9042": "sui", "9382": "mei", "9DD1": "li", "5A0B": "shao", "5F9E": "cong;zong", "6133": "ju", "7A65": "yu", "7C01": "xi", "7C44": "kui", "8DD1": "pao", "8F7C": "shi", "9AA4": "zhou", "514C": "dui", "53B1": "lan", "7156": "nuan;xuan", "77AD": "liao", "7A5F": "sui", "8D93": "duo", "9041": "dun", "6405": "jiao", "714B": "xing", "757F": "ji", "8952": "bie", "620F": "xi;hu", "7230": "yuan", "86D4": "hui", "5C4A": "jie", "7112": "none", "724E": "yong", "7B33": "jia", "7A0E": "shui", "7C81": "qian", "7D07": "he;ge", "7FDE": "jiang", "86DA": "lie", "89E2": "zhi", "8DF2": "jia", "8E25": "qie", "77BF": "ju;qu", "7A78": "xi", "7F0E": "duan", "86CB": "dan", "5375": "luan", "56DB": "si", "5781": "zhi", "6094": "hui", "8985": "none", "9993": "san", "55DB": "qian", "6430": "hu", "64C1": "yong", "66D6": "ai", "69EB": "tuan", "7F03": "xiang", "9CC1": "wen", "5182": "jiong", "59DE": "ji", "5A2A": "wu", "75F9": "bi", "7B99": "fu", "8F25": "gun", "932C": "lian", "5910": "xiong", "7F3D": "bo", "9813": "dun", "5996": "yao", "6803": "none", "7670": "yong", "8F1C": "zi", "5E5D": "chan", "709D": "qiang", "72C6": "zhong", "7AAE": "qiong", "7B63": "li", "5E77": "bing", "6076": "e;wu", "757B": "cheng", "89D1": "qu", "90ED": "guo", "9BA9": "bing", "9DBA": "ji", "5C28": "mang;pang", "6A86": "shan", "759F": "nue;yao", "9250": "shi", "9468": "long", "51B0": "bing", "5ABB": "pan", "7796": "yi", "7B39": "none", "7C13": "none", "7CAF": "xian", "8744": "wang", "929A": "yao;diao;tiao", "96CE": "ju", "92FC": "gang", "994D": "shan", "5588": "jie", "623A": "shi", "7692": "e", "9864": "yao", "5A8E": "jie", "69A1": "su", "8941": "qiang", "8E9B": "wei", "9477": "nie", "96E2": "li", "5299": "li", "6A14": "chao", "99C0": "you", "5814": "chen", "69E5": "hui", "73BC": "ci", "76D4": "kui", "7BD9": "gao", "821A": "tian", "8C77": "yi", "90B2": "bi", "920D": "dun", "5065": "jian", "5BEB": "xie", "6E79": "chan", "6F43": "xiu", "7460": "liu", "7509": "xian", "8374": "fu", "89BD": "lan", "95B0": "yan", "6BC3": "que", "71F9": "xian", "7C8E": "chi", "7FDD": "hong", "82D3": "ling", "960B": "xi", "66D5": "none", "7582": "die", "9B7E": "pi", "5ABC": "ao", "5F0B": "yi", "6641": "chao;zhao", "6F22": "han", "791B": "jian", "9BA6": "tong", "617B": "juan", "7ADF": "jing", "9BBE": "nei", "513D": "lei", "52D0": "meng", "559A": "huan", "5FC4": "xin", "6436": "qiang;chuang", "4F10": "fa", "573A": "chang", "5D15": "ya", "7391": "ji", "83B7": "huo", "8F07": "quan", "90EF": "tan", "8B54": "zhuan", "94AA": "kang", "604E": "die", "616E": "lu", "714A": "xuan", "8D23": "ze", "9847": "cui", "9E8D": "liu", "7995": "yi", "951B": "ben", "9DF3": "xian", "5869": "yan", "88E2": "lian", "9802": "ding", "9826": "ke", "9BD2": "yong", "51E5": "ju", "5EB2": "lai", "61B6": "yi", "82AC": "fen", "9708": "pei", "5BD7": "ning", "5C16": "jian", "5CC0": "xiu", "67B2": "xi", "6B40": "kuan", "728D": "jian;qian", "7D57": "hu", "8563": "shun", "8BD2": "yi", "906B": "su", "95D9": "qi", "6A46": "wu", "81AF": "teng", "87BB": "lou", "97C3": "da", "5DED": "none", "81CF": "bin", "8BD5": "shi", "97FC": "peng", "5DF5": "zhi", "82D7": "miao", "5416": "a", "6A96": "sui", "9C82": "fang", "9F81": "he", "4E9D": "qi", "509F": "wang", "5689": "duo", "614D": "yun", "9074": "lin", "51FA": "chu", "74F0": "none", "82B8": "yun", "615E": "zhang", "6C9A": "zhi", "7834": "po", "846C": "zang", "9667": "nie", "52DE": "lao", "5D00": "lang", "7DA2": "chou", "4F14": "chen", "55C6": "qiang", "5F64": "tong", "8E47": "jian", "903A": "yuan", "940B": "tang", "87AE": "di", "4FDE": "yu;shu", "5052": "tang", "608B": "lin", "6458": "zhai;zhe", "77BE": "zhao", "6DB6": "tuo", "8E6F": "fan", "6331": "suo", "73C8": "jia", "83FC": "tan", "6C22": "qing", "7004": "jie", "770D": "kou", "6829": "xu", "6E29": "wen", "7133": "jue", "8FE8": "dai", "9E65": "yi", "77A3": "huan", "7924": "ca", "8797": "tang", "8E6A": "tui", "525D": "bo", "5A99": "wei", "7768": "ni", "890B": "die", "8D13": "zang", "8D8A": "yue", "9229": "lu", "5950": "huan", "687E": "jun", "5423": "qin", "5F5B": "yi", "6669": "wan", "8369": "jin", "92C0": "dou", "9424": "ding", "5617": "chang", "5EF8": "di", "5CF2": "li", "7F44": "qing", "893B": "xie", "70C4": "jiao", "7373": "nou", "73C6": "yi", "9A72": "ri", "9EB9": "qu", "6270": "rao", "79C4": "zi", "8D88": "zhan", "9E1F": "niao;diao", "6F56": "pa", "68FD": "chen", "6B7F": "mo", "6E12": "pi", "83A0": "you", "5CA4": "xue", "785A": "qiao", "8067": "kui", "9693": "hui", "508D": "bang", "551A": "qin", "5A94": "mian", "9F98": "ta", "5ED0": "jiu", "7E0D": "bang", "80F4": "dong", "8262": "qiang", "8AD4": "zhu", "8F11": "yun", "90E6": "li", "98A3": "lei", "9B18": "man", "6A27": "sha", "73FA": "jun", "828E": "xiong", "8E31": "duo", "6741": "none", "852C": "shu", "5C7F": "yu", "6F31": "shu", "86FF": "han", "4EE6": "chao", "87DE": "bie", "90F6": "bu", "686C": "suo", "8EAE": "none", "98B6": "ju", "9AD8": "gao", "508B": "gou", "6427": "shan", "6581": "yi;du", "66B7": "chuan", "74A4": "none", "8575": "sun", "9C22": "ma", "64C0": "gan", "678B": "fang", "67B8": "gou;ju", "8496": "zhen", "888D": "pao", "98E0": "shi;si", "50FE": "ai", "5FC3": "xin", "80EF": "kua", "831B": "gen", "908B": "la", "92E7": "xian", "93FE": "san", "50D1": "qiao", "5FE4": "wu", "701C": "rong", "4F18": "you", "5B08": "rao", "7EF4": "wei", "897B": "pan", "97A5": "yi;eng", "5288": "pi", "53F1": "chi", "59B7": "zhi", "6108": "yu", "622F": "xi;hu", "76FF": "min", "81CB": "tun", "9EB6": "chi;li", "8229": "chuan", "8238": "ge", "89D9": "ji", "9621": "qian", "9E3A": "xiu", "9E45": "e", "9F80": "chen", "4FD2": "hun", "51AA": "mi", "588D": "ji", "6368": "she", "7CC3": "tang", "4E5D": "jiu", "50CB": "qiu", "601B": "da", "6695": "jian", "675E": "qi", "94BF": "dian;tian", "4F6E": "ge", "6058": "qiu", "606A": "ke;que", "63D2": "cha", "6B60": "chuo", "6C38": "yong", "7252": "die", "739C": "hong", "7598": "gong;gang", "69C1": "gao", "6AF7": "none", "6D77": "hai", "71DD": "none", "83D2": "gao", "86C1": "diao", "8DFD": "ji", "9344": "liang", "9733": "long", "9BBC": "qin", "9E04": "ji", "5D5B": "yu", "5D97": "lao", "6FDF": "ji", "79F8": "jie", "7BC1": "huang", "9E56": "he", "58B5": "tan", "6047": "kuang", "62A3": "none", "65DE": "sui", "874A": "none", "54FC": "heng;hng", "87B1": "wei", "9E7F": "lu", "50E5": "jiao;yao", "9AB9": "qiao", "6359": "yi", "661E": "bing", "67A7": "jian", "70A2": "zhu", "74B0": "huan", "7BC2": "xing", "863A": "li", "5530": "shua", "5674": "pen", "5D60": "xi", "66E4": "huo", "7C92": "li", "8D5B": "sai", "8E44": "ti", "93CF": "wei", "9B0F": "jiu", "52C2": "hao", "55BA": "xi", "7975": "kun", "7CE5": "nuo", "88BF": "gui", "621A": "qi", "7701": "sheng;xing", "7CAC": "qu", "5016": "xing", "509C": "yao", "510F": "none", "74CB": "zhe", "85DE": "la", "86DE": "kuo", "5A62": "bi", "5B3B": "du", "60F1": "nao", "550D": "guan", "5FEA": "zhong;song", "8D4B": "fu", "961F": "dui", "5782": "chui", "5E50": "teng", "8D2A": "tan", "8DC1": "pa", "9620": "xin;shen", "5703": "pu", "75FF": "wei", "76D5": "fan", "8766": "xia;ha", "5BDB": "kuan", "699B": "zhen", "93B9": "rong", "717A": "tui", "7380": "luo", "7600": "yu", "7C9D": "li", "89A3": "wei", "9279": "chi", "6711": "none", "68F9": "zhao;zhuo", "70F1": "jiong", "757C": "chang", "7633": "chou", "5691": "none", "5C25": "liao", "608A": "zhe;qi", "8E19": "ju", "503C": "zhi", "574D": "tan", "6ACB": "mian", "8873": "zhong", "8E30": "yu", "9DE0": "yu", "5151": "dui", "55D8": "ji", "5CA5": "bo", "6431": "zhi", "66A5": "yan", "784C": "luo;ge", "985F": "liao", "5963": "weng", "6356": "huan", "6EE5": "lan", "77AC": "shun", "79CD": "zhong;chong", "9467": "none", "686A": "xun", "7713": "huo", "77BD": "gu", "7B8D": "gu", "970B": "qi", "9A34": "yan", "8420": "meng", "5A7F": "xu", "703B": "dai", "7377": "guang", "9437": "ye", "5EB5": "an", "84E3": "yu", "8C5C": "jian", "9CC9": "jiang", "5501": "yan", "6162": "man", "61EB": "zhi", "61F9": "rang", "6859": "yu", "6BDF": "none", "7A04": "ze", "8002": "none", "8192": "none", "5256": "pou", "5E57": "guo", "6DAE": "shuan", "808E": "ken", "9850": "hun", "66DD": "pu;bao", "817E": "teng", "5BC4": "ji", "5D98": "zhan", "63EF": "geng", "664B": "jin", "6845": "wei", "7070": "hui", "7348": "yi", "7BA2": "yuan", "7F7F": "tong", "96B8": "li", "637E": "wo", "674A": "xun", "7D56": "kuang", "9551": "bang", "52C0": "ke", "54F3": "zha", "5D3B": "zhi", "9068": "ao", "9F46": "weng", "556C": "se", "661F": "xing", "757A": "jiang", "8B60": "zhan", "91D2": "jin", "954B": "tang", "5620": "ga", "86CF": "cheng", "88A4": "mao", "9139": "zou", "56FF": "you", "6FCE": "ding", "75BA": "fa", "77A7": "qiao;ya", "7B86": "bi", "812F": "fu;pu", "91CB": "shi", "59DD": "shu", "715F": "wu", "819C": "mo", "995C": "yan", "6937": "jian", "878F": "ji", "8B4B": "lan", "5F48": "dan;tan", "6DB2": "ye;yi", "78D1": "wei", "9FA4": "xie", "50E2": "chuan", "8CD0": "xun", "975D": "tian", "9DCB": "tu", "5235": "er", "575D": "ba", "5D1D": "cheng", "6783": "yun", "7A15": "zhun", "8687": "chi", "9562": "jue", "5029": "qian", "550A": "jia", "5999": "miao", "5DE6": "zuo", "664E": "hong", "9C0B": "yan", "7A44": "ji", "7C8F": "tai", "8212": "shu", "8DC0": "yue", "8EFE": "shi", "5312": "da", "5650": "qi", "95CE": "none", "9C65": "gui", "6C6E": "jun", "731A": "ya", "7F6B": "gua", "81F9": "xiu", "8570": "wen", "8A16": "qi", "97EC": "tao", "9CA1": "li", "4F83": "kan", "5DA5": "jue", "5E14": "pei", "6535": "po", "6BC7": "hui", "7916": "yu", "8248": "none", "95ED": "bi", "9C76": "xiang", "5517": "dou", "5D3F": "e", "563C": "xu", "5A97": "xuan", "61F3": "none", "6AB5": "ji", "78C7": "pi", "7950": "you", "8B50": "zun", "8B90": "chou", "5AB7": "ru", "7CB7": "ju", "8D03": "zhuan", "926C": "mu", "95C1": "none", "4E18": "qiu", "585F": "zang", "6B9C": "ye", "7486": "qiu", "8601": "wu;e", "8958": "hui", "98B3": "gua", "5B75": "fu", "647E": "jiang", "6935": "jia", "6E26": "wo;guo", "72ED": "xia", "8446": "bao", "873F": "wan", "9C32": "ao", "6BCC": "guan", "8A5D": "zhu", "8F93": "shu", "919A": "mi", "55E0": "luo", "6CB0": "tuo", "7942": "ta", "9D31": "ai", "5E2F": "dai", "75F5": "ji", "8A15": "shan", "9244": "tie", "534B": "shi", "5E9D": "tong", "61BE": "han", "647A": "zhe", "6A71": "chu", "8E0C": "chou", "90F4": "chen", "9173": "yin", "9BFE": "bian", "5051": "feng", "6F49": "none", "70F7": "wan", "939B": "bo", "629A": "fu", "991B": "hun", "69D5": "zhuo", "797B": "gu", "7BCD": "qiu", "990A": "yang", "74EA": "ban", "7A6A": "cheng", "7D67": "tong", "8391": "feng", "8FD2": "hang", "560B": "xiao", "5843": "huang", "6E30": "yan", "774C": "wan", "813E": "pi", "8D34": "tie", "904C": "e", "58AB": "zun", "6897": "geng", "8532": "kou", "85F9": "ai", "94C8": "shi", "4E03": "qi", "50ED": "jian", "5C78": "long", "6148": "ci", "667A": "zhi", "6EE0": "she", "932B": "xi", "623E": "li", "6DBE": "ta", "71A7": "zong", "7ECF": "jing", "9030": "you", "999C": "ni", "5715": "tu;shu;guan", "5A47": "cai", "62C0": "chu", "7258": "du", "96F9": "bao", "9F10": "nai", "5158": "shi", "5D6D": "beng", "6853": "huan", "6E38": "you", "7236": "fu", "9DC5": "li;piao", "547D": "ming", "65BC": "wu;yu", "6E0F": "none", "785B": "none", "8A69": "shi", "9A10": "yan", "5240": "kai", "697E": "none", "72B8": "ma", "7DC9": "liang", "82F3": "dong", "5BB3": "hai", "65DD": "guai", "745E": "rui", "7F11": "gou", "8191": "bin", "8B37": "ao", "8CEB": "ji", "5AF6": "qiao", "689A": "wan", "68D1": "pai", "7B17": "dong", "84C5": "liu", "896E": "bo", "8EE6": "huang", "572B": "yu", "5901": "yi", "633B": "shan", "7049": "yong", "76D9": "fu", "843C": "e", "8BA6": "jie", "9155": "mao", "586E": "xie", "60BF": "tian", "7577": "chuo", "8D2B": "pin", "934A": "lian", "9ADF": "biao;shan", "6A84": "xi", "6C52": "mang", "6F66": "liao;lao", "758D": "dan", "77B1": "ye", "7C8D": "li", "8906": "shi", "696D": "ye", "71DE": "none", "724A": "shao", "7279": "te", "8405": "chun", "8E7F": "cuan", "9EE9": "du", "555C": "chuo;chuai", "6994": "lang", "69B3": "ting", "6AF3": "long", "7660": "ji", "817B": "ni", "87BF": "jiang", "8AE3": "hua", "94C1": "tie", "9F4C": "ji", "5ED7": "dai", "65F8": "yang", "69CE": "cha", "6A19": "biao", "745C": "yu", "9718": "dong", "6E69": "zhong", "6F7F": "wei", "7DCB": "fei", "7F24": "bin", "9A99": "kui", "5061": "zhan", "6136": "xie", "82C6": "none", "8AFF": "qi", "8BE1": "gui", "95E7": "none", "9EA9": "fu", "643A": "xie", "7695": "bi", "868A": "wen", "91B0": "tan", "9A22": "xia", "5A40": "e", "5D3E": "yao", "8445": "ju", "8A05": "qiu", "96E6": "ji", "9C2A": "ge", "5A30": "si", "6D33": "ru", "71E8": "xi", "5C87": "ang", "5E7D": "you", "6B7A": "dai", "6C89": "chen", "8DFE": "shu", "945C": "shang", "4FC1": "yu", "5DE3": "chao", "5E27": "zhen", "8D6B": "he", "8E8C": "wu", "933E": "zan", "952D": "ding", "9696": "wu", "5A39": "xian", "64FD": "lue", "6A10": "lu", "78DB": "chan", "7E59": "fan", "80AB": "zhun", "5F33": "jing", "667D": "lin", "7D31": "fu", "868D": "pi", "8B0A": "huang", "9720": "yin", "5348": "wu", "6962": "you", "74E2": "piao", "96F7": "lei", "523F": "gui", "542C": "ting;yin", "88C0": "yin", "6262": "gu", "87C8": "guo", "9461": "chuo", "9710": "weng", "4E4C": "wu", "5D4C": "qian;kan", "71CB": "jiao", "74A2": "liu", "7E35": "man", "7EAE": "hong", "8579": "weng", "8688": "qian", "51C1": "shu", "5977": "qian", "7C50": "teng", "80A5": "fei", "8FCD": "zhun", "9255": "po", "9448": "nie", "601D": "si;sai", "7C46": "yue", "9BA3": "yin", "652B": "jue", "6625": "chun", "797C": "guan", "94A4": "qian", "9C79": "guan", "5FB6": "bie", "6020": "dai", "6633": "die", "668F": "du", "7A77": "qiong", "7AAA": "wa", "7FB7": "lian", "9825": "yi", "6DA3": "huan", "77F0": "zeng", "7EAB": "ren", "907D": "ju", "5B6D": "mie", "9084": "huan;hai;xuan", "4E32": "chuan", "6407": "qin", "6A81": "lin", "6E84": "none", "73E7": "yao", "83DB": "men", "8777": "li;xi", "56E8": "pian", "5BCB": "jian", "6A16": "ke", "781E": "mo", "7D11": "fou", "7F26": "man", "9353": "ji", "9592": "xian", "9E6B": "jiu", "51FF": "zao;zuo", "5F44": "kou", "61DB": "dai", "69A5": "huang", "6C39": "dang", "7785": "chou", "7912": "wo;yi", "79CC": "qiu", "84E4": "none", "8D74": "fu", "8E5D": "xi", "58D9": "kuang", "6816": "qi;xi", "79DB": "pi", "7DA1": "liang", "8B14": "nue;xue", "9C50": "su", "4E15": "pi", "5175": "bing", "55DF": "jie;jue", "6D94": "cen", "8F0C": "liang", "9225": "huo", "9E9B": "mi", "8372": "chu", "51D5": "ming", "5310": "fu", "7844": "kuang", "835B": "rao", "4E95": "jing", "6884": "you", "6C0B": "meng", "6C2D": "dong", "5450": "na;ne", "612D": "qi", "8C47": "jiang", "4F8C": "yin", "7C26": "deng", "7F2E": "shan", "859A": "tang", "97EB": "yun", "58FB": "xu", "6837": "yang", "7D8E": "ting", "9332": "lu", "9B32": "li;ge", "508F": "tang", "7781": "xu", "7A42": "sui", "8665": "zhan", "87AD": "chi", "8A42": "fu", "9469": "e", "97FE": "yin", "5830": "yan", "704A": "qian", "75F6": "tian", "891A": "chu;zhu", "6557": "bai", "7336": "you", "7657": "lei", "77D6": "xi", "7E43": "beng", "67C2": "yi", "7291": "ju", "770C": "xian", "962F": "zhi", "7175": "xia", "7452": "yang", "8B9A": "zan", "5DB4": "ao", "6449": "sou", "69EF": "cui", "755F": "ce", "76F1": "xu", "7949": "zhi", "806E": "lian", "9857": "yi", "9CD8": "min", "5FFE": "kai", "73CF": "jue", "8346": "jing", "85C4": "qi", "9A74": "lu", "5105": "dang", "5360": "zhan", "5A0A": "xian", "5BC2": "ji", "5D4D": "wu", "63F9": "bei", "6947": "huo", "7ABE": "kuan", "7D02": "zhou", "8E38": "chen", "5BCC": "fu", "6DBC": "liang", "73E4": "bao", "75DB": "tong", "78A6": "ke", "812D": "cheng", "81F6": "jian", "8D8E": "chu", "95B9": "yan", "9EBD": "mo;me", "5507": "chun", "5AC6": "yong", "6390": "qia", "64F5": "mo;ma", "6CF5": "beng", "8682": "ma", "580B": "peng;beng", "6D31": "er", "6FD6": "shu", "7132": "yi", "7428": "kun", "809B": "gang", "60A2": "liang", "69E4": "lian", "6B13": "dang", "74EC": "fang", "9B7F": "ling", "9C9D": "zha", "58C1": "bi", "5D4A": "sheng", "6216": "huo", "6AFB": "ying", "8244": "shao", "9CCC": "ao", "80F3": "ge;ga", "4E2D": "zhong", "4EA0": "tou", "6946": "yao", "6E7B": "chun", "7AA3": "su", "7B8E": "chi", "7DE2": "miao", "7FC4": "chi", "8765": "mao", "93A0": "gang", "60EC": "qie", "687B": "feng", "70EF": "xi", "7848": "jia", "7962": "mi;ni", "7966": "wu", "5C15": "ga", "746C": "liu", "9F36": "si", "5570": "luo", "7F63": "gua", "8CB1": "bi", "9346": "men", "4FDB": "mian", "5060": "yao", "6B29": "chao", "8477": "hun;xun", "9145": "xi", "918A": "chuo", "4E27": "sang", "7A0D": "shao", "9273": "bei", "9F4B": "zhai", "5297": "cuan", "6BCE": "mei", "6D37": "zhi", "6DA1": "wo;guo", "8768": "shi", "8B0E": "mi;mei", "5F6A": "biao", "69C0": "kao", "8541": "qian;xun", "99CF": "ju", "65C0": "none", "65F2": "tai", "72D4": "ni", "7D8D": "fu", "8BE9": "xu", "988C": "he;ge", "5F6F": "piao", "86F7": "qiu", "4F62": "ju", "566C": "shi", "5D2F": "yin", "63DA": "yang", "6887": "long", "7433": "lin", "74C8": "li", "7EA4": "xian;qian", "4E7A": "none", "51FD": "han", "66CC": "zhao", "708C": "kai", "756C": "yu", "8BED": "yu", "5AF7": "tuo", "6135": "ta", "720F": "li", "9EAC": "fu", "5554": "qi", "7125": "yue", "7558": "nan", "7B37": "mao", "7D5B": "tao", "89D4": "jin", "4E14": "qie;ju", "4F17": "zhong", "7088": "yi", "7E94": "cai", "85A9": "sa", "9B7C": "qu", "6618": "fang", "8469": "pa", "89FB": "li", "94AB": "fang", "96D5": "diao", "55EC": "he", "7199": "xi", "730F": "jian", "7C8B": "cui;sui", "801C": "si", "9690": "yin", "5905": "xiang", "71EF": "ling", "8E8A": "chou", "957D": "liao", "9DF0": "yan", "5C9C": "ba", "630C": "ge", "74E7": "none", "973C": "xi", "5C1C": "ga", "62AC": "tai", "62B1": "bao", "8029": "jiang", "8223": "yi", "84D1": "suo", "8694": "qi;chi", "5A2D": "xi", "60A3": "huan", "6512": "zan;cuan", "8B84": "lei", "99DC": "bi", "4F20": "chuan;zhuan", "5429": "fen", "9339": "ken", "9D96": "qiu", "4F99": "chi", "6070": "qia", "6750": "cai", "7346": "hao", "9F33": "ju", "6078": "tong", "7D52": "chou", "85EE": "qiao", "8FBA": "bian", "5636": "si", "5A89": "wu", "6B18": "zhu", "6E97": "sheng", "7889": "diao", "7A0A": "ti", "8557": "lu", "8F28": "guan", "92C3": "lang", "5206": "fen", "601C": "lian;ling", "774D": "xian", "99CB": "zhao", "503A": "zhai", "5D03": "lai", "639A": "liang", "6802": "mei", "6BA9": "cuan", "6F32": "zhang", "7CB1": "liang", "72CD": "pao", "737C": "mi", "725B": "niu", "934D": "du", "99EB": "jiong", "631A": "zhi", "78C9": "sang", "8194": "lu", "922A": "none", "9972": "si", "5E1A": "zhou", "5E6C": "chou;dao", "5EDC": "tu", "6283": "bian", "6C9D": "zhui", "7326": "feng", "8D6E": "xia", "9E11": "yue", "93AC": "hao;gao", "5E7F": "guang", "636F": "dao", "66F3": "ye;zhuai;yi", "793E": "she", "8C0F": "jian", "9D64": "none", "6854": "jie;ju", "6A2B": "jian", "72C3": "niu", "8560": "ru", "93FB": "lin", "9B9F": "an", "54CE": "ai", "5986": "zhuang", "6F59": "wei", "779E": "man", "5B56": "zi", "91CD": "zhong;chong", "9411": "jie", "7707": "miao", "979F": "kuo", "61E3": "men", "6EF2": "shen", "8538": "dou", "558F": "re;nuo", "5779": "xue", "69C7": "dian;zhen", "752B": "fu", "816E": "sai", "5050": "yan", "5BA0": "chong", "6037": "xi", "6780": "song", "6BF2": "duo", "7C0D": "lou", "85E2": "zhi", "9AB3": "bi", "75E3": "zhi", "8585": "hao", "545C": "wu", "5485": "pou", "58AE": "duo;hui", "7674": "luan", "8BF1": "you", "99E5": "rong", "5D5E": "tu", "5F03": "qi", "65CB": "xuan", "6F41": "ying", "997B": "xi", "7AA9": "wo", "8929": "ban", "9326": "jin", "778B": "chen", "75D7": "mei", "7FDF": "zhai;di", "8B43": "xu", "8F1F": "chuo", "9418": "zhong", "59E0": "shang", "6D95": "ti", "9E70": "ying", "4E1C": "dong", "570C": "chui", "7974": "gai;jie", "8F49": "zhuan;zhuai", "96D7": "han", "6772": "gao", "6B39": "yi;qi", "83B3": "shi", "9057": "yi;wei", "60E2": "rui", "7342": "yuan", "7E33": "zhuan", "4FE9": "liang", "80B8": "xi", "8255": "bang", "9944": "tang", "52E5": "qiang", "85F2": "shu", "8C83": "mo", "5FD5": "dai", "600D": "zuo", "7B30": "fu", "7F2F": "zeng", "822A": "hang", "9284": "shang", "5A53": "fei", "5B55": "yun", "5ECF": "jiu", "6BC4": "ji", "7FD5": "xi", "93FA": "po", "9481": "jue", "9A3A": "zhi", "9EA4": "cu", "5D85": "ao", "79F7": "zhi", "894F": "bo", "5A9A": "mei", "5ED9": "yi", "6341": "jiao", "731E": "she", "8015": "geng", "5E59": "mu", "6249": "fei", "69A3": "yao", "69C8": "nou", "4F49": "qu", "5EAA": "gui", "67EF": "ke", "6820": "ren", "75E2": "li", "7CB6": "lu", "8CDE": "shang", "9705": "zha", "5849": "ji", "5C8D": "qian", "5F16": "hu", "6AA2": "jian", "6ABC": "yin", "6543": "min", "6C58": "qian", "7D22": "suo", "85FD": "chen", "89F5": "gong", "91DF": "ba", "94EB": "yao;diao;tiao", "6BF8": "sui", "918E": "xian", "93B0": "yi", "944E": "kui", "658B": "zhai", "7030": "mi", "7606": "shen", "765F": "bie", "8113": "nong", "907E": "shi", "5249": "cuo", "63A1": "cai", "64C3": "kuo", "75AB": "yi", "769F": "ze", "7E9C": "lan", "9955": "tao", "9E21": "ji", "5576": "ding", "56F0": "kun", "5C5F": "xie", "6382": "dian", "7684": "de;di", "86AE": "te", "86DF": "jiao", "9510": "rui", "9542": "lou", "969D": "dao", "5711": "pu", "7B09": "zhen", "8152": "ju", "838F": "suo", "8685": "e", "62F8": "chi", "8739": "rui", "9354": "e", "54D3": "xiao", "6E52": "ji", "8821": "li", "53A7": "dian", "7086": "wen", "7CD9": "cao", "874D": "ji", "9059": "yao", "5523": "zao", "64C6": "zhuo", "78B4": "cha", "947F": "zao;zuo", "9636": "jie", "673F": "ci", "76ED": "li", "809D": "gan", "9DAB": "none", "8AFD": "ge", "9550": "hao;gao", "705A": "jiao", "742B": "beng", "8F75": "zhi", "953D": "huang", "6915": "bin", "6C0F": "shi;zhi", "6F6A": "di", "7553": "none", "6B17": "lan", "7FD9": "hui", "5267": "ju", "57EF": "an", "6968": "zhen", "79DD": "li", "8730": "fei", "97AD": "bian", "5303": "gai", "70B7": "zhu", "8264": "yi", "99E9": "quan", "5CA7": "tiao", "6FCA": "hui", "97FD": "yin;an", "62A1": "lun", "64ED": "huo", "69C9": "ji", "6D8E": "xian", "6FD8": "ning;neng", "8FA7": "bian", "93E5": "xiu", "9762": "mian", "5439": "chui", "54B7": "tao", "5BFB": "xun;xin", "5DCE": "nao", "6B6E": "se", "70EA": "none", "71CA": "shen", "77B7": "jian", "7DBF": "mian", "936A": "mou", "9897": "ke", "9A53": "zeng", "9C3F": "ji", "59ED": "xian", "7080": "yang", "70D5": "tong", "837B": "di", "674B": "fan", "7762": "sui", "81EB": "jiao", "8792": "han", "9DF1": "kao", "57C5": "fang", "5F2C": "yi", "63D1": "nie", "6CFB": "xie", "7766": "mu", "80F5": "zhi", "5556": "dan", "6461": "gai;xi", "6490": "cheng", "6D3F": "wu", "813B": "jie", "9E9A": "jia", "51A5": "ming", "52A4": "jing", "5770": "jiong", "5E8D": "bai", "6517": "mei", "97A2": "xie", "9D61": "wu", "4EBE": "wang", "79B8": "rou", "96DE": "ji", "5352": "zu;cu", "6E57": "feng", "7CB0": "fu", "5ADE": "yong", "61A3": "fan", "7B01": "zhu", "9B5C": "ren", "9D43": "zhou", "5796": "dui", "5A58": "quan", "7A5E": "lu", "7CF8": "mi", "8395": "xing", "7145": "duan", "7E56": "san", "88B9": "mo", "9603": "kun", "98A8": "feng", "5332": "lian", "584E": "yong", "5A3D": "lu", "75E4": "cuo", "7736": "kuang", "77FF": "kuang", "8318": "li", "8784": "si;shi", "57E4": "pi;bei;bi", "5E64": "bi", "9335": "hua", "4E21": "liang", "4EE9": "shang", "53F6": "ye;xie", "61B7": "chu", "73FC": "bei", "7D78": "jian", "8B19": "qian", "8CA5": "hang", "9614": "kuo", "9B2C": "dou", "4ED3": "cang", "8419": "none", "85FB": "zao", "9745": "fei", "5673": "yu", "642B": "pan", "73E3": "xun", "76A9": "huang", "86BB": "zha", "8F5D": "yu", "9B0C": "duo", "9D76": "ya", "507B": "lou;lu", "5415": "lu", "5A06": "rao", "794F": "shi", "5015": "chui", "5928": "ze", "5C42": "ceng", "6179": "zhi", "6A32": "er", "791C": "yu", "9B36": "gui", "6C6D": "rui", "96BD": "juan;jun", "4F46": "dan", "5E71": "lan", "847E": "yuan", "898D": "bian", "8A25": "ne;na", "95C4": "yao", "54CB": "di", "5C13": "er", "60CC": "yuan", "6945": "bi", "8407": "chang", "5E02": "shi", "7109": "yan", "88AC": "yu", "9421": "tie", "524A": "xue;xiao", "6D59": "zhe", "84C8": "lang", "93BF": "na", "96E9": "yu", "98C4": "piao", "5E5A": "bang", "62EC": "kuo;gua", "6FA6": "yu", "705D": "hao", "7590": "zhi", "768F": "peng", "8748": "guo", "8870": "shuai;cui", "4EC9": "zhang", "5663": "zhou", "79AF": "nong", "80EB": "jing", "9219": "qin", "8C98": "mo", "9817": "po", "9BE1": "fei", "5B7C": "nie", "6DA9": "se", "71EB": "lian", "8A7D": "yan", "51DC": "lin", "6375": "chen", "66A1": "weng", "6C93": "ta;da", "84C0": "sun", "8A86": "kuang", "5E1E": "mo", "668E": "ying", "769B": "jiong", "7F31": "qian", "8312": "none", "864C": "bie", "8BDB": "zhu", "9D58": "jun", "6B93": "lian", "7254": "bo", "5C9B": "dao", "6827": "yi", "730D": "li", "7628": "dian", "8DAE": "zao", "93AD": "zhen", "53EC": "zhao;shao", "586C": "yuan", "6610": "fen", "6B6A": "wai", "6CE8": "zhu", "72E2": "he;hao;mo", "50EB": "e", "6A9B": "zhua", "77C2": "ji", "7E25": "zhen", "77B4": "wu", "8AA0": "cheng", "6353": "ye", "6D97": "shui", "6F44": "shu", "74AB": "dang", "74FC": "none", "8BE5": "gai", "4F7F": "shi", "5610": "xiao", "5E8E": "jie", "8878": "xie", "9A58": "luo", "9AD6": "kuan", "8EE0": "ren", "9096": "shan", "9516": "qing;qiang", "516D": "liu;lu", "63E6": "la", "98CA": "none", "506F": "yi", "5CCD": "lu", "6C6B": "qing", "6DBA": "ju", "4F3E": "pi", "51D1": "cou", "5233": "ku", "8475": "kui", "88F5": "pei", "98C5": "liu", "8EDE": "mao", "92A7": "guang", "9B65": "que", "6192": "kui", "6B94": "yi", "6D17": "xi;xian", "91A2": "hai", "509A": "xiao", "54F8": "sui", "6CDF": "cheng", "7B04": "ji", "84D8": "gun", "4FC5": "qiu", "55BF": "cao", "5EC1": "ce;ci", "6548": "xiao", "6C48": "diao", "710A": "han", "8381": "wu", "8AC9": "wei", "57B6": "xing", "9571": "yi", "97D6": "rou", "56A1": "none", "7AAB": "ya", "4EDB": "cha", "5A98": "none", "5D78": "zong", "69A2": "jia", "6D56": "lie", "716F": "none", "8F48": "chao", "95B6": "chang", "5E80": "pi", "7B4C": "quan", "9DF8": "yu", "593D": "yun", "60D5": "ti", "629F": "tuan", "738B": "wang", "7FE7": "xuan", "9299": "kua", "97B1": "tao", "97F4": "za", "98B4": "xuan", "4EC8": "ba", "799D": "ji", "7AF1": "zhuan", "7E77": "nao", "8439": "pian;bian", "8E58": "liao", "9576": "xiang", "6A9A": "chu", "6DC7": "qi", "6DCC": "tang", "80DB": "jia", "9F35": "tu", "6AC2": "zhao", "6BA5": "yin", "8A61": "xu", "56B0": "mo", "815A": "ding", "8332": "zi", "8C31": "pu", "8D98": "xi", "8FDD": "wei", "9D40": "ren", "9EF7": "du", "5753": "xing", "5E16": "tie", "6B37": "xi", "97C7": "du", "56EB": "hu", "70FD": "feng", "73F1": "ying", "9C3D": "qiu", "9C4A": "jue", "5907": "bei", "5EAF": "bu", "67A2": "shu", "6B8B": "can", "6C98": "bi", "52D1": "lai", "62CA": "fu", "639E": "shan", "77E8": "ying", "9778": "sa", "9D8E": "none", "5403": "chi;ji", "8326": "ce", "96AF": "dao", "987A": "shun", "9DBB": "gu;hu", "9EC4": "huang", "57A2": "gou", "6634": "mao", "6CB4": "li", "74EF": "ou", "7D12": "jie", "7E65": "xi", "825A": "cao", "838B": "ji", "8911": "yuan", "9A02": "xing", "9AF0": "ti", "9D32": "zhi", "9D3C": "luo", "997C": "bing", "7F8F": "yang", "86E5": "she", "561C": "ma;mo", "87A5": "cang", "9E7B": "jian", "4F2D": "xuan", "7411": "suo", "887E": "qin", "8BB8": "xu", "9664": "chu", "670E": "ling", "6823": "ren", "6D57": "qiu", "8088": "zhao", "893C": "xian", "8BD7": "shi", "53AB": "ao", "6CAE": "ju", "7385": "miao", "7CE1": "jiang", "8910": "he", "64D5": "xie", "65DC": "zhan", "660F": "hun", "6630": "shi", "9CBB": "zi", "6602": "ang", "6642": "shi", "8001": "lao", "80F9": "er", "9336": "biao", "9EB4": "qu", "5876": "lu", "5EA4": "zhi", "6BBF": "dian", "6C21": "dong", "81F0": "chou;xiu", "8F97": "zhan", "937E": "zhong", "9661": "dou", "5F49": "kuang", "524B": "ke", "5A57": "ni", "5C6E": "che", "79C3": "tu", "7D71": "tong", "7F1F": "gao", "83AB": "mo", "87EE": "shan", "8A07": "hong", "8A17": "tuo", "8BF8": "zhu", "9017": "dou", "9C1B": "wen", "61E9": "yang", "6B0F": "luo", "6F93": "fu", "720A": "ao", "75A7": "xi", "7E1D": "zhen", "8F52": "fen", "5B76": "zi", "67B9": "bao;fu", "814D": "ren", "874C": "ke", "9E1E": "luan", "60BE": "kong", "64A4": "che", "6CC7": "jia", "7EDB": "jiang", "9D01": "yiao", "4F19": "huo", "5025": "kong", "5DC7": "xi", "69C2": "sun", "8B02": "wei", "8E9A": "xian", "924B": "bao", "6008": "yi", "67E0": "ning", "803A": "yun", "8FEE": "ze", "579C": "duo", "5ADD": "kang", "5FF0": "cui", "6343": "jun", "823F": "none", "8B5E": "xuan", "9C20": "sao", "521F": "ju", "6608": "hu", "8907": "fu", "9372": "min", "9EFA": "fen", "5A07": "jiao", "62AE": "zhen", "8492": "shi", "9D30": "gua", "4EBF": "yi", "5298": "mo", "63B0": "bai;bo", "9736": "pang", "98CC": "feng", "52B3": "lao", "5699": "nie", "6079": "yan", "8030": "you", "8358": "zhuang", "9271": "kuang", "93CA": "ao", "9A03": "ai", "58E9": "ba", "8068": "lian", "5567": "ze", "5686": "hao", "813F": "biao", "8C43": "han", "91BB": "chou", "5018": "tang;chang", "58A0": "shan", "79F0": "cheng", "8DB2": "zan", "92F2": "none", "51A7": "none", "59B8": "e", "6957": "jian", "69D6": "tuo", "78B1": "jian", "8B6C": "pi", "981A": "jing;geng", "6AC5": "ji", "89DD": "di", "9A73": "bo", "6364": "none", "8C33": "yan", "6682": "zan", "6A15": "su", "8E27": "cu", "9A40": "mo", "9DD0": "chen", "9EC0": "zou", "4E41": "yi", "4F41": "ai", "5E41": "xu", "703D": "jian", "77C5": "yao", "8A2E": "xian", "97D5": "none", "5495": "gu", "6323": "zheng", "8627": "qu", "8F09": "zai", "9016": "ti", "9143": "ling", "91F6": "ta;tuo", "5125": "du", "6991": "fu", "6C74": "bian", "6DAA": "fu", "6FB4": "huan", "72CA": "ju", "7828": "e", "9ED1": "hei", "9F64": "quan", "5921": "qi", "5C4B": "wu", "61C5": "qu", "641E": "gao", "69CF": "qian", "985D": "ku", "9B74": "fang", "5268": "huo", "76C1": "ying", "51FC": "dang", "6C02": "li", "809C": "rong", "853D": "bi", "9D1B": "yuan", "5564": "pi", "58D6": "ruan", "5AE8": "han;ran", "70FA": "lang", "77F9": "wu", "9152": "jiu", "9309": "min", "94C7": "bao", "9B75": "fen", "4EEA": "yi", "52FD": "bao", "5313": "jiu", "59E9": "nian", "5FE1": "chong", "6358": "jun", "654E": "jiao", "7F60": "min", "92B7": "xiao", "9CD3": "le", "51B6": "ye", "6727": "long", "7DEC": "mian", "7E06": "geng", "9BFA": "ju", "9E57": "e", "619A": "dan", "7280": "xi", "7440": "yu", "8311": "niao", "8BD4": "lei", "9EAB": "mian", "57A0": "yin", "7C19": "bo", "8CBE": "chi", "93D9": "cui", "6CFE": "jing", "7233": "none", "78FE": "di", "89DF": "hua", "57C8": "jun", "66A0": "gao", "7789": "kou", "6E31": "hong", "7F5D": "ju", "9577": "chang;zhang", "9C1C": "jian", "5543": "ken", "7039": "yue", "7996": "mei", "8344": "gai", "92AB": "se", "9933": "xing;tang", "555B": "cui", "5A3B": "dong", "625C": "yu", "8865": "bu", "8E62": "di;zhi", "92B6": "qiu", "96DF": "sui", "5E73": "ping", "5612": "hui", "6A2D": "none", "77D1": "lu", "90BE": "zhu", "9249": "xuan", "92E4": "chu", "86BD": "pi", "96A7": "sui", "9AD5": "bin", "51D0": "yin", "6C83": "wo", "76C6": "pen", "7868": "che", "893D": "wei", "8D31": "jian", "6E3D": "zai", "6FE6": "yin", "7AC0": "cheng", "7C72": "xu;yu", "7E36": "zhi", "92ED": "rui", "5B02": "zhi", "6555": "chi", "6FFF": "li", "708E": "yan", "7523": "chan", "8141": "pian", "8E51": "nie", "9BA0": "wei", "4ED0": "san", "5C5C": "ti", "6566": "dun;dui", "7344": "yu", "7E2D": "li", "84DC": "none", "9C83": "ba", "53FF": "hong", "6622": "pei", "6A22": "niao", "7662": "yang", "5072": "si;cai", "5B77": "li", "5C1A": "shang", "893E": "biao", "8A5E": "ci", "9ED7": "tuan", "4F70": "bai", "5511": "zuo", "5CC8": "luo", "66EB": "luan", "7F0B": "hui", "865E": "yu", "8945": "none", "8B0F": "xiao;sou", "8FFE": "lie", "52FC": "jiu", "564E": "ye", "60C0": "lun", "6E61": "yu", "77F8": "gan", "7832": "pao", "9000": "tui", "9C8B": "fu", "4EF9": "feng", "5358": "dan;chan", "8809": "xuan", "8CCF": "ying", "5E26": "dai", "758B": "pi;shu;ya", "99B7": "pei", "5630": "ji", "5765": "qu", "5831": "bao", "5956": "jiang", "5E49": "none", "5FC5": "bi", "60E6": "dian", "8662": "guo", "50AB": "lei", "620D": "shu", "77CE": "xuan", "881A": "he", "8BD9": "hui", "9E27": "cang", "5CAA": "fu", "7910": "que", "820A": "jiu", "84BD": "en", "4EAD": "ting", "55F4": "none", "5D48": "huan", "665B": "xian", "7ED5": "rao", "58A5": "dong", "7E75": "chan", "7085": "gui;jiong", "7400": "han", "953E": "huan", "74A8": "can", "75C6": "nie", "90D5": "cheng", "98AA": "none", "5C40": "ju", "9E5E": "yao", "5224": "pan", "6680": "wang", "6978": "qiu", "6C29": "ya", "708A": "chui", "51CA": "qing;jing", "582C": "yu", "5BF6": "bao", "62C4": "zhu", "7F4C": "ying", "55D7": "gong", "599A": "pei", "5F27": "hu", "795A": "zuo", "86CA": "gu", "9625": "yin", "9E8A": "mi", "5043": "yan", "53C3": "can;cen;shen;san", "58AF": "duo", "5B70": "shu", "5E83": "guang", "7854": "hong", "8FFA": "nai", "92A4": "mi", "594E": "kui", "6D98": "si", "7940": "si", "51A8": "fu", "6AB6": "qian", "744B": "wei", "800C": "er", "814C": "a;yan", "5A0E": "xie", "6960": "nan", "7E53": "zuo", "844F": "lu", "93CD": "luo", "4E0F": "mian", "5BB1": "zha", "6735": "duo", "6973": "mei", "8484": "guan", "9820": "wei", "63E7": "la", "8481": "shu", "9806": "shun", "6878": "xi", "7384": "xuan", "8DDE": "li;luo", "514E": "tu", "53B6": "si", "61C6": "cao", "6BB6": "zhu", "8B5B": "zen", "9306": "qing;qiang", "9386": "none", "5985": "hong", "8624": "wei", "8998": "zhan;chan", "8E0F": "ta", "5E1D": "di", "5FFC": "kang", "6089": "xi", "6D35": "xun", "7213": "yan", "7904": "qiao", "7CF0": "tuan", "8955": "lan", "8CC8": "jia;gu", "5873": "peng", "7D45": "jiong", "9B59": "zhan", "5B6B": "sun", "9117": "hao", "97BA": "tang", "56C1": "nie", "57A9": "e", "6096": "bei", "6554": "yu", "8268": "meng", "532D": "gui", "8E9C": "zuan", "9A7B": "zhu", "55CD": "suo", "5E60": "hu", "648B": "ruan", "6D46": "jiang", "7D15": "pi", "8942": "sen", "8C3E": "hong", "920F": "yin", "969E": "ao", "529A": "zhu", "5B57": "zi", "6497": "huang", "6704": "yin", "958C": "kang", "4FEF": "fu", "6794": "xun", "7A72": "li", "4E46": "jiu", "7CFB": "xi;ji", "9959": "fen", "50B0": "peng", "5F74": "zhuo", "5FB8": "chong", "7C53": "fan", "596A": "duo", "5C93": "qi", "73A0": "jie", "7BE4": "du", "8BDF": "gou", "9686": "long", "7131": "yan", "80FC": "pian", "5FDD": "tian", "6025": "ji", "70DC": "xuan", "8E78": "lin", "5C81": "sui", "6A7E": "shu", "7F51": "wang", "82D5": "tiao;shao", "92CA": "yu", "6AD4": "none", "8026": "ou", "917C": "hai", "96E5": "za", "5104": "yi", "57F9": "pei", "6473": "kou", "798D": "huo", "7D0A": "wen", "9966": "tuo", "5339": "pi;ya", "5A86": "ruan", "716B": "sui", "8E16": "ji", "9998": "guo", "9CD1": "pang", "5AE4": "jin", "6975": "ji", "8B75": "zhui", "9080": "yao", "94B4": "gu", "5126": "biao", "53D8": "bian", "68DA": "peng", "7089": "lu", "7A8C": "jiao", "7D27": "jin", "9D44": "chi", "5346": "zu", "641C": "sou", "7919": "ai", "7AFC": "peng", "84BC": "cang", "857E": "lei", "8DCB": "ba", "9568": "pu", "97AE": "di", "5CAE": "tuo", "7480": "cui", "9E97": "li", "6596": "wei", "96F8": "an", "61F4": "chan", "6C46": "cuan", "7538": "dian", "77E1": "jue", "7ACD": "shi;gong;sheng", "7FA5": "qian;qiang", "5280": "gua", "596C": "jiang", "5C24": "you", "6C85": "yuan", "7BB1": "xiang", "8F19": "zhe", "5B8E": "yao", "65DF": "yu", "6D4D": "hui;kuai", "73C7": "zu", "751C": "tian", "7D92": "fu", "948B": "po", "53C1": "san", "5DB5": "zui", "6734": "po;piao;pu", "8ABB": "ta", "9554": "bin", "9E6C": "yu", "4E30": "feng", "4F88": "chi", "58A1": "shan", "790D": "ke", "7935": "shuang", "7AAD": "ju", "5EBC": "qing", "7201": "lan", "8A82": "tiao;diao", "64E8": "ye", "6663": "zhe", "6B01": "nong", "8718": "zhi", "9151": "yu", "6314": "lu", "7737": "juan", "7DF4": "lian", "85D7": "su", "8717": "wo", "9990": "xiu", "9E2C": "lu", "5307": "none", "8F41": "tao", "9E66": "ying", "5698": "you", "58B0": "tan", "595F": "beng", "77B6": "kui", "7C3A": "sai", "83FA": "jian", "9994": "zhuan", "9F00": "cu", "5815": "duo;hui", "6A93": "hui", "72AD": "quan", "8ABA": "chi", "9CBA": "shi", "52E8": "xiang", "588F": "qiang", "6DDC": "peng", "6EA6": "wei", "8511": "mie", "98D9": "biao", "50FA": "qiao", "5AFB": "xian", "674D": "zi", "73BB": "bo", "890A": "bian", "8BA5": "ji", "9D26": "yang", "5ED2": "ao", "64A0": "ji", "6830": "fa", "7872": "yu", "83E6": "qin", "8B88": "li", "5FA7": "bian", "621C": "die", "7CBF": "guo", "82DD": "pei", "8704": "zhen", "5941": "lian", "5C38": "shi", "76A0": "cui", "6464": "chuang", "6870": "kuo", "7816": "zhuan", "7D58": "ci", "8354": "li", "850C": "su", "6A0A": "fan", "7378": "shou", "7464": "yao", "7BD8": "chou", "50C8": "man", "629D": "ao", "7D2A": "qi", "7E8B": "you", "8D7C": "ci", "8FF9": "ji", "979B": "beng", "5D33": "yu", "6284": "chao", "6731": "zhu", "764C": "ai;yan", "91E3": "diao", "94D7": "jia", "9D1A": "ge", "9E26": "ya", "565B": "nie", "680F": "lan", "7A94": "yao", "82B1": "hua", "5CFA": "geng", "8190": "lu", "9D94": "rou", "6C34": "shui", "767F": "qie", "8282": "jie", "850E": "she", "9E41": "bo", "5D0E": "qi", "7455": "xia", "9370": "huan", "6134": "chuang", "621D": "cai", "63BA": "chan;shan;can", "83BE": "mang", "843A": "mao", "9680": "chong", "9ABF": "pian", "6A8E": "qin", "7524": "rui", "80F6": "jiao", "8138": "lian", "5F77": "pang;fang", "6A56": "tang", "9416": "ji", "973E": "mai", "66B5": "han", "8A49": "nao", "9474": "xi", "52CB": "xun", "7288": "quan", "74C3": "lei", "50B2": "ao", "5A56": "tian", "5BB0": "zai", "761A": "jue", "8857": "jie", "8CCC": "gai", "5D1E": "guo", "7788": "weng", "77E7": "shen", "9CAD": "qing;zheng", "5544": "zhuo", "55A5": "du", "5B51": "jie", "642E": "li", "6D0A": "jian", "741F": "wei", "7CA7": "zhuang", "7F49": "none", "8BAC": "tuo", "58CF": "lan", "507A": "za;zan", "526B": "duo", "7255": "bang", "7261": "mu", "79A0": "chi", "80BD": "tai", "83F6": "beng", "8517": "zhe", "8CED": "du", "4E8E": "yu", "62B0": "yang", "6871": "jing", "68C3": "li", "7022": "wei", "7A4F": "wen", "65E1": "ji", "672E": "zhu", "7954": "fu", "876B": "zhu", "8D02": "chen", "5E28": "shui", "6538": "you", "667F": "chang", "86E4": "ha;ge", "8747": "ying", "8BFF": "wei", "4FCA": "jun;zun;juan", "5176": "qi;ji", "52B9": "xiao", "54ED": "ku", "6D40": "qu", "772B": "mi", "8E32": "dun", "90CA": "jiao", "91D3": "ga", "94B0": "yu", "76BD": "zhan", "7F2D": "liao", "80FB": "xing", "92C5": "xin", "92F0": "li", "9410": "liao", "5365": "xi", "633A": "ting", "64DA": "ju", "68C5": "bing", "6E4A": "cou", "74CE": "la", "7943": "ma", "88DD": "zhuang", "5B9E": "shi", "7355": "cui", "7C87": "kang", "8A5A": "da", "9975": "er", "9A35": "yuan", "5385": "ting", "5D8F": "bo", "6EC4": "cang", "7A52": "none", "7A8D": "qiao", "7E08": "ying", "823C": "hong", "8720": "jun", "9703": "chen", "5173": "guan", "6739": "qiu", "6B1F": "none", "6CF9": "dan", "7052": "zan", "70DB": "zhu", "755B": "zhen", "84C3": "none", "8BE6": "xiang", "8C59": "yi", "55F9": "lian", "5AE3": "yan", "6B62": "zhi", "7099": "zhi", "757E": "lei", "76CD": "he", "78AF": "nao", "802A": "pang", "9A09": "kun", "5D5C": "qi", "623C": "mao", "8CE5": "sui", "5340": "qu;ou", "5C36": "gan", "6389": "diao", "6F17": "cong", "705E": "ba", "8340": "xun", "602F": "qie;que", "6A8C": "zui", "7513": "pi", "7650": "guai", "587F": "lou", "58A2": "ba", "58EF": "zhuang", "5CE0": "none", "5E92": "none", "7A69": "wen", "7AAF": "yao", "5A27": "tui", "8FBB": "none", "93A7": "kai", "9A4F": "zhan", "5AED": "hu", "8A92": "e", "9CC3": "sai", "6371": "ai", "60FE": "zong", "9E68": "liu", "76A2": "xiao", "5A22": "han", "6C5C": "si", "6D48": "zhen", "82B9": "qin", "957B": "die", "5806": "dui;zui", "8F08": "zhou", "9201": "fang", "9923": "ye", "5EB7": "kang", "5F2F": "wan", "6452": "bing", "65E5": "ri", "7CD3": "gu;yu", "85CB": "di", "942E": "lian", "5BCF": "huan", "67FD": "cheng", "704E": "yan", "796B": "xia", "843E": "ying", "85DC": "li", "8977": "none", "849D": "yuan", "8B24": "biao", "8C6D": "jia", "9797": "tiao", "9D55": "xun", "577E": "zhu", "6A1A": "lu", "805C": "di", "84DF": "ji", "88A8": "xuan", "8C51": "zhi", "55E3": "si", "5687": "xia;he", "6C79": "xiong", "7579": "wan", "879F": "ming", "896B": "shi", "5F70": "zhang", "623F": "fang", "6AC6": "kui", "6BB2": "jian", "7B1A": "xia", "8172": "wei", "8ADE": "pian", "905D": "ta", "97B6": "pan", "558E": "kuai", "62E5": "yong", "70FF": "rong", "719E": "jian", "7D7D": "lu", "89DB": "dan", "9B3B": "yu", "9DCE": "liu", "6E9C": "liu", "72C0": "zhuang", "7C70": "yue", "8C00": "yu", "653F": "zheng", "802B": "ze", "97A4": "bang", "9CED": "diao", "6D11": "fu", "70A7": "duo", "7776": "chun", "9452": "jian", "9D27": "rong", "5BBB": "mi", "654A": "chu", "76A3": "ye", "7A1F": "bing", "8A7A": "ming", "8DDC": "ni", "511A": "meng", "517A": "none", "5AFE": "lian", "63D7": "shun", "6E6F": "tang;shang", "7416": "zhan", "841C": "tie", "5DCD": "wei", "6428": "ta", "6E13": "xi", "77A8": "pu", "7987": "zhe", "86F6": "lie", "9189": "zui", "531F": "kang", "7035": "fen", "767A": "fa", "851B": "hu", "9238": "ba", "92FF": "chang", "967C": "zhu", "98A4": "zhan;chan", "67E5": "cha;zha", "6D6F": "wu", "6F13": "li", "7383": "qu", "73B6": "ping", "92A2": "yong", "9953": "cheng", "529B": "li", "88CE": "cheng", "892C": "sang", "993F": "sou", "6EFC": "fan", "7B88": "chi", "7BE7": "zhuo", "8350": "jian", "8360": "ji;qi", "8B93": "rang", "8BF4": "shuo;shui;yue", "5068": "chai", "5201": "diao", "659B": "hu", "7362": "xiao", "84EC": "peng", "9156": "dan;zhen", "5F0F": "shi", "6776": "chun", "7979": "tao", "814E": "shen", "898B": "jian;xian", "9AE9": "bin", "52B2": "jing", "5ACA": "su", "6D03": "hui", "7BFD": "yu", "8669": "xi", "8C7C": "pi", "5654": "deng", "7C91": "ba", "8464": "zhou", "97A3": "rou", "6A31": "ying", "8336": "cha", "87D0": "none", "6065": "chi", "7968": "piao", "82FC": "sheng", "9E75": "lu", "7937": "lan", "8F3B": "fu", "9211": "ban", "6023": "you", "60D7": "nie", "6163": "guan", "6D2C": "su", "6D6B": "han", "71A1": "lou", "7463": "suo", "7F36": "fou", "8930": "qian", "5FB2": "chi", "68F2": "qi;xi", "89F8": "chu", "965B": "bi", "998F": "liu", "58F1": "yi", "7506": "ci", "7CE7": "liang", "825B": "lou", "8795": "bi", "9834": "ying", "9A8D": "xing", "9F17": "tao", "75C0": "ju", "76AD": "jiao", "7DA0": "lu", "93F3": "zheng", "9C0D": "qiu", "9F07": "ao", "59FA": "xian", "5AF8": "zhan", "60F8": "qiong", "6F8B": "heng", "8487": "chan", "8D7A": "qin", "993C": "xi", "572E": "pi", "7251": "bian", "7B0A": "zhao", "8982": "feng", "68EB": "yu", "6E5F": "huang", "86F4": "qi", "9471": "chan", "5579": "none", "6992": "nuo", "6C4E": "fan", "6D74": "yu", "768E": "jiao", "8059": "jing", "94BC": "mu", "556D": "zhuan", "5F8E": "cheng", "704C": "guan", "854D": "yu", "9358": "zha", "9682": "yin", "6631": "yu", "9840": "chui", "7324": "hu", "79F9": "ren", "862E": "ji", "8731": "pi", "9695": "yun", "5163": "li", "5741": "zhi", "58F6": "hu", "5D6E": "dian", "4E8A": "shi", "5938": "kua", "7082": "zhong", "82F5": "die", "9313": "kong", "99B3": "chi", "5706": "yuan", "581A": "hun", "5EE1": "wu", "600B": "min", "62CD": "pai", "6736": "duo", "7B76": "gao", "8DC6": "tai", "938A": "bang", "949A": "bu", "655C": "nie", "6F51": "po", "7057": "dan", "79D0": "yun", "867D": "sui", "90B3": "pi", "92DE": "xing", "9B56": "xu", "62DA": "pan;pin", "640E": "sun", "6D64": "hong", "7EDF": "tong", "829B": "wei", "85E0": "jiao", "8C6B": "yu", "8F8B": "wang", "99AB": "xing", "515B": "qian", "661D": "zan", "87F5": "none", "9BC6": "fu", "9CE3": "shan", "5207": "qie", "5B1D": "niao", "94A9": "gou", "6CBF": "yan", "8120": "shan", "6F4D": "wei", "8163": "di", "8668": "ban", "97E9": "han", "5AE6": "chang", "6D18": "kao", "78AC": "xia", "7AD3": "qian;fen;zhi;yi;gong;sheng", "8C82": "diao", "5196": "mi", "536E": "zhi", "576E": "tai", "6C0E": "die", "803F": "geng", "84AC": "yuan", "8987": "ba", "8C14": "e", "9DD6": "yi", "9F1D": "yuan", "5215": "li", "5AF3": "bi", "5C9F": "yang", "6715": "zhen", "6959": "mao", "6F7B": "shu", "7647": "xian", "91C5": "yan", "99A8": "xin;xing", "4FF6": "ti;chu", "5811": "qian", "6C25": "xi", "7339": "cha", "7DFA": "gua", "8086": "si", "83F4": "an", "5A93": "huang", "6B72": "sui", "7EE7": "ji", "863F": "luo", "5320": "jiang", "5629": "hua;ye", "6E71": "huo", "8603": "rui", "8E6E": "xian", "53E5": "ju;gou", "6AEE": "e", "6C51": "tuo", "773A": "tiao", "77C4": "xun", "7938": "zan", "98C1": "xi", "9D18": "bian", "59A3": "bi", "5F0C": "yi", "81F5": "ge", "8698": "hui", "8737": "quan", "9C4D": "bo", "5F14": "diao", "6FFC": "luo", "7AA6": "dou", "88D4": "yi", "8950": "xiang", "8CAF": "zhu", "9C4B": "qu", "559F": "kui", "81DF": "zang", "83A7": "xian", "8D48": "zhen", "8DB4": "pa", "542B": "han", "5467": "di", "6CBD": "gu", "7764": "pi", "94D3": "mang", "7559": "liu", "8EF9": "zhi", "9AA8": "gu", "4E25": "yan", "685F": "zhan", "6C55": "shan", "7CE4": "san", "81E6": "guang;wang", "6D7C": "mei", "6E6A": "none", "7F81": "ji", "80C3": "wei", "9638": "e", "4E55": "hu", "6850": "tong", "703E": "lan", "7AB2": "liao", "8FBD": "liao", "5BF8": "cun", "8609": "mang", "5F3C": "bi", "677E": "song", "7690": "gao", "7EB2": "gang", "808F": "cao", "888B": "dai", "918C": "kun", "9861": "yi", "4F9B": "gong", "5E44": "wo", "81F4": "zhi", "9D8A": "geng", "5B5B": "bei;bo", "69B2": "yun", "9B03": "zong", "5077": "tou", "5678": "dun", "57B0": "none", "75BC": "teng", "8164": "an", "84F1": "ping", "8848": "er", "5D94": "qin", "84E1": "can", "4EE5": "yi", "66E0": "kuang", "78B5": "none", "7A97": "chuang", "871C": "mi", "87D9": "zhi", "8F76": "yi", "9979": "le", "9EE1": "yan", "59FF": "zi", "5F54": "lu", "60C5": "qing", "82A8": "ji", "8474": "xian", "8684": "fang", "89C3": "yan", "4E85": "jue", "55F8": "ao", "570D": "wei", "8BFB": "du;dou", "8DCE": "tuo", "946D": "lan", "65E8": "zhi", "72B9": "you", "9E0A": "pi", "62F3": "quan", "755C": "chu;xu", "7F56": "none", "7F84": "zhao", "81CE": "cui", "8F51": "lao", "91F4": "yi", "9BD6": "qing;zheng", "9E9F": "lin", "6036": "pi", "8A33": "yi", "52FF": "wu", "6E85": "jian", "7BDE": "nie", "9A7F": "yi", "9DCD": "jiao", "614F": "ming", "62B3": "ni", "636E": "ju", "6F98": "shan", "8222": "shan", "945A": "zuan", "52E4": "qin", "7026": "zhu", "804A": "liao", "8479": "shi", "8E83": "bi", "6143": "yang", "7B68": "han", "7C35": "du", "990D": "yan", "9AC9": "bo", "7564": "zhi", "8E99": "lin", "9099": "mang", "93F0": "beng", "50BC": "han", "55C1": "ti", "56D5": "none", "867A": "hui", "4FEB": "lai", "5515": "zao", "5528": "zuo", "97CA": "lan", "9901": "ren", "5204": "ren", "5398": "li", "59F2": "yan", "8304": "qie;jia", "8D16": "shu", "5152": "er", "5913": "xia", "638B": "di", "6B8D": "piao", "904B": "yun", "9CC6": "fu", "6C5F": "jiang", "7D76": "jue", "545E": "shi", "7FC3": "hong", "8B08": "bo", "9651": "er", "5881": "man", "5606": "tan", "5DBC": "yu", "6044": "xi", "60FB": "ce", "7249": "pan", "60B6": "men", "7436": "pa;ba", "84CB": "gai;ge;he", "88CA": "niao", "859D": "zhan", "8A22": "xin", "9534": "kai", "9907": "tong", "5F97": "de;dei", "5FE5": "xi", "63E0": "ya", "79D7": "yu", "9F71": "chuo", "505A": "zuo", "53E1": "rui", "562D": "peng", "6677": "gui", "6C8E": "huo", "6D67": "ying", "70AA": "zhuo", "7ED7": "hang", "824B": "meng", "89B5": "jian", "5550": "cui", "7865": "mang", "7908": "zhui", "7EEE": "qi", "8B9B": "yi", "9128": "bi", "9C6D": "ji", "5014": "jue", "5F63": "zhang", "890D": "duan", "9028": "zui", "6F96": "xian", "7668": "huo", "9A36": "zou", "543C": "hou", "8435": "wo", "9558": "man", "9BAA": "wei", "9CAF": "qi", "605A": "hui", "8894": "he", "9775": "niu", "5534": "qiang", "5DD1": "cuan", "5E24": "ru", "6D5E": "zhuo", "7620": "ji", "8602": "rui", "8752": "mian", "89CE": "yu", "9824": "yi", "9D2D": "zhui", "58D7": "none", "6C1A": "chuan", "7CDF": "zao", "7EFE": "wan", "8156": "dong", "871B": "ju", "5927": "da;dai", "6C67": "qian", "7540": "bi", "5487": "bie", "5980": "ji", "5B0C": "jiao", "654B": "ge", "7CA5": "zhou;yu", "4F30": "gu", "5ECA": "lang", "6287": "hu", "9493": "diao", "9530": "meng", "5727": "ya", "6880": "cu", "8B5C": "pu", "4FA0": "xia", "6529": "dang", "6A52": "yun", "709F": "da", "7D33": "shen", "8C1F": "mo", "9909": "xiang", "527A": "li", "5657": "pu", "5AA0": "tuo", "653E": "fang", "735E": "tong", "9978": "he", "55E1": "weng", "6072": "peng", "60DF": "wei", "8E39": "chuai", "4FE4": "ti", "54C4": "hong", "56AA": "dan", "56E7": "jiong", "63DD": "zan", "6503": "sa", "6EE4": "lu", "73E9": "heng;hang", "7488": "ao", "74E4": "rang", "9EB8": "fu", "9EC8": "tou", "9F47": "zha", "5EE9": "lin", "5F60": "huo", "906A": "ce", "91FA": "qian", "504E": "wei", "5581": "yong", "5EED": "none", "6781": "ji", "684D": "ku", "69B5": "rong", "7066": "xian", "5092": "xi", "5615": "xian", "6003": "wu", "74FD": "dang", "7CB8": "qi", "86FB": "tui;shui", "8B4D": "ying", "8CFC": "gou", "9AD2": "zang", "5923": "meng", "5DF3": "si", "79F2": "zhi", "83D0": "pu", "8597": "yuan", "88E8": "bi;pi;bei", "4F1A": "hui;kuai", "5E85": "mo", "69DD": "none", "7945": "yao", "7CB9": "cui", "50C7": "lu", "61E7": "nuo", "8DD8": "pan", "9619": "que", "9982": "jun", "9E24": "shi", "6059": "yang", "88F2": "liang", "8A00": "yan", "9154": "zui", "6123": "leng", "6FAE": "kuai;hui", "7730": "die", "83C1": "jing", "8C5A": "tun", "56E6": "yuan", "6AB9": "yi", "6B00": "xiang", "799B": "zhen", "7A7D": "jing", "7B51": "zhu", "822C": "ban;bo;pan", "8E37": "zha", "514F": "chang;zhang", "6971": "cou", "7F1B": "ru", "6520": "mi", "7EAA": "ji", "977C": "da", "60BB": "xing", "74C9": "zan", "9500": "xiao", "4F86": "lai", "5DB9": "dao", "65E7": "jiu", "8706": "xian", "8890": "bi", "5725": "lu", "5D9F": "zun", "6844": "guang", "75E7": "sha", "8411": "huan", "8567": "fu", "900B": "bu", "6547": "ce", "86F8": "shao;xiao", "9EBA": "mian", "613F": "yuan", "6592": "ban", "67BD": "sang", "6C10": "di", "793D": "reng", "7C82": "none", "81A3": "zhi", "8928": "suo", "4EBD": "none", "671F": "qi;ji", "7732": "er", "8A47": "yang", "9F0F": "mi", "52BA": "mou", "5C90": "qi", "608D": "han", "68D9": "li", "7C48": "zhen", "87E1": "gui", "90F9": "ju", "9A3D": "xi", "9CF5": "bao", "5462": "ni;ne;na", "5879": "qian", "6EDB": "yin", "8136": "luo", "9513": "qin", "52F3": "xun", "55C4": "a;sha", "5BF3": "bao", "6807": "biao", "77EB": "jiao", "84E0": "li", "8D22": "cai", "5A78": "yang", "9B8B": "you", "574B": "fen", "5A21": "zhi", "5D4F": "zong", "9B83": "ping", "9F55": "he", "6112": "kai;qi", "7629": "da", "9455": "zhi", "9654": "gai", "52D4": "mian", "531C": "yi", "6FDE": "bi", "70A5": "fu", "710B": "zhuang", "7B48": "gua", "7FAC": "xian", "8C8B": "an", "9991": "jin", "503F": "none", "6CF7": "long;shuang", "799A": "zhuo", "7A9A": "cheng", "7F64": "ti", "7FCC": "yi", "84FA": "yi", "9010": "zhu", "9BDF": "dong", "51BE": "xia", "5802": "tang", "635C": "sou", "63ED": "jie", "625A": "diao", "64BB": "ta", "65F7": "kuang", "8536": "ze", "8A76": "chou", "94FC": "lai", "9808": "xu", "554A": "a", "5D1F": "yin", "6948": "xu", "726C": "bei", "80F2": "hai;gai", "8D91": "zi", "8FA4": "ci", "9112": "zou", "5C18": "chen", "6E8E": "gui", "8931": "huai", "5618": "xu;shi", "8531": "sha", "52C7": "yong", "59E6": "jian", "5CC2": "tong", "85F3": "gao", "879C": "hu", "61D6": "gua", "71AA": "yi", "8A4B": "zhou", "8CCE": "jian", "8E8B": "ji", "551D": "gong", "667E": "liang", "6D5D": "mang", "9A66": "shuang", "4E4A": "none", "5338": "xi", "66B0": "cong", "7D74": "xiang", "8182": "lu", "82FF": "wei", "840A": "lai", "910D": "ming", "9B5D": "ji", "9180": "wei", "9450": "xu", "5334": "suan", "5444": "ge", "6BC1": "hui", "6C28": "an", "6CDB": "fan", "7DD2": "xu", "7DF8": "yin", "9351": "fu", "9352": "rou", "3007": "ling", "590E": "zuo", "7024": "huai", "76B7": "gu", "7DB4": "zhui", "8127": "juan", "5AD9": "xuan", "8884": "ao", "9684": "ti", "5342": "xin", "68D7": "zao", "723B": "yao", "97CF": "juan", "5771": "yang", "68B5": "fan", "6F08": "ji", "8367": "ying", "5750": "zuo", "6B6F": "chi", "76B5": "que", "53BB": "qu", "5AB4": "yuan", "68CD": "gun", "7091": "mu", "7B2A": "da", "8841": "huang", "8A1A": "yin", "94B7": "po", "9CCD": "qi", "5066": "xu", "519B": "jun", "5CA9": "yan", "63FC": "none", "6419": "nu", "7003": "si", "8183": "wa", "54E4": "mang", "8401": "ji;qi", "8F83": "jiao", "6FAA": "ling", "942A": "lu", "9526": "jin", "987D": "wan", "61F8": "xuan", "6EF4": "di", "75EE": "zhang", "85BF": "ni", "88EB": "yuan", "89E5": "gong", "5FD7": "zhi", "7DEB": "zong", "9CD0": "yao", "5632": "chao;zhao", "56F2": "wei", "5BA5": "you", "6F21": "shang", "7641": "fu", "7D9F": "li", "5B19": "qiang", "6D30": "ju", "72F0": "zheng", "90AC": "wu", "50FD": "zhou", "796C": "zhi", "7F74": "pi", "87E4": "zhuan", "8BF0": "gao", "8E02": "nie", "940D": "jue", "9F29": "qu", "5091": "jie", "599D": "zhuang", "7CB5": "yue", "876F": "yuan", "87B7": "pi", "9106": "yun", "6B4F": "jin", "849F": "ju", "932D": "tao", "564F": "xi", "6692": "qing", "6CDA": "ci", "8970": "lai", "9CCE": "ta", "73C5": "shen", "7D2B": "zi", "8106": "cui", "5B7E": "ying", "62EA": "qian", "694C": "yan", "83A2": "jia", "8AF0": "xi", "8F9B": "xin", "964F": "duo", "6C81": "qin;shen", "87E6": "fei", "8D6A": "cheng", "64AA": "ben", "7102": "shu", "74D9": "dao", "7630": "luo", "7B4F": "fa", "8DBA": "fu", "944D": "ying", "59C7": "fu", "6C04": "rong", "7174": "yun", "7239": "die", "871D": "qi", "8E93": "zhi", "9A6C": "ma", "5363": "you", "7505": "none", "89C5": "mi", "9A7D": "nu", "6707": "pi;bi", "717B": "tang", "7555": "jiang", "860E": "ji", "8770": "kui", "5424": "jie", "5F82": "cu", "7990": "yuan", "59CA": "zi", "5DAC": "yi", "63CC": "sai", "67D1": "gan", "71D3": "fen", "80E8": "dong", "84F8": "cao", "8C70": "hu", "9B95": "gu", "4E36": "zhu;dian", "5101": "jun;juan", "6778": "shu", "79E0": "pi", "79F1": "tong", "7AF4": "cun", "947D": "zuan", "986E": "bin", "542E": "shun", "563D": "chan", "5D35": "yang", "5DE5": "gong", "6A09": "shuang", "810B": "xie", "8FDC": "yuan", "9B48": "xiao", "8C25": "shi", "943A": "dang;cheng", "99C8": "qu", "4FD6": "pai", "59D9": "ren", "5C48": "qu", "6B41": "kan", "6C26": "hai", "70B6": "han", "84BF": "hao", "7615": "jia;xia", "7EEB": "ling", "9A06": "zhou", "650B": "la", "6F57": "ji", "7F94": "gao", "7FC1": "weng", "873D": "liang", "955B": "yong", "9606": "lang", "98C9": "liao", "9DFE": "yi", "5848": "ji", "8ABE": "yin", "90BD": "gui", "5328": "cang;zang", "6E40": "kui", "6EEE": "biao", "711C": "kun", "7ED9": "ji;gei", "832B": "mang", "855A": "e", "996D": "fan", "9A07": "she", "9BB4": "none", "9BD0": "none", "9DB9": "liu", "533E": "bian", "57E9": "zheng", "5911": "none", "67BB": "yi", "725E": "jiu", "764F": "guan", "8A39": "xu", "9812": "ban", "4F2B": "zhu", "924A": "zhao", "619B": "tan", "6C31": "yang", "6FEF": "zhuo", "5BB7": "shen", "7C0A": "ji", "8E70": "chu", "942B": "juan", "561F": "du", "743E": "jie", "7DEE": "fu", "83ED": "tai", "9124": "fan", "54AA": "mi", "58D2": "kai", "599F": "yan", "7224": "lan", "8F00": "er", "5102": "nong", "7CAD": "none", "90A0": "bin", "5FF5": "nian", "7016": "huo", "713E": "none", "8FD6": "ta", "527E": "kou", "5466": "you", "5ABE": "gou", "5DCF": "quan", "6511": "qian", "6A1D": "zha", "6B6D": "chi", "8123": "chun", "8C1B": "di", "5277": "chan", "5AA9": "hu", "68B8": "li", "7DE6": "si", "8455": "yan", "8E7E": "dun", "9006": "ni", "9C72": "lie", "5CB8": "an", "7B81": "pu", "7FF5": "qu", "859F": "lian;xian", "902F": "lu", "4F73": "jia", "5006": "lia;liang", "77AA": "deng", "79C8": "xian", "7DB8": "lun;guan", "7F1D": "feng", "8089": "rou", "8596": "ke", "6E75": "you", "783F": "kuang", "7A88": "yao", "7C39": "dang", "96EA": "xue", "5C47": "tian", "5CF1": "nao", "5F8F": "zhi", "6C90": "mu", "6D07": "yin", "72D3": "pi", "8345": "da", "9C7B": "xian", "6259": "zhang", "6AE9": "yan", "7AE9": "yi", "8193": "chang", "9880": "qi", "5473": "wei", "9C1D": "hao", "5EB4": "ji", "6651": "xiang", "6E94": "yao", "7EB0": "pi", "6BBE": "xun", "6C14": "qi", "7CED": "zong", "9A1F": "yu", "5D79": "jiang", "7F3C": "que", "84F2": "qiu;ou", "4F4B": "shao", "4FA3": "lu", "4FD8": "fu", "5D37": "qiu", "6233": "chuo", "7176": "none", "7E48": "qiang", "51C9": "liang", "558B": "die;zha", "7A82": "lao", "7E7E": "qian", "8633": "tong", "8A24": "xiao", "4EEF": "chao", "6FED": "ai", "74C2": "gai", "77F1": "huo", "833C": "tong", "5183": "mao", "62E1": "kuo", "64DD": "none", "64EA": "ye", "7038": "jian", "71F5": "none", "7536": "fu", "9541": "mei", "9E07": "zhan", "617D": "qi", "767E": "bai;bo", "76A5": "hao", "8676": "yu", "4E54": "qiao", "634A": "pou", "8806": "chai", "709A": "guang", "7907": "yu", "9EBE": "hui", "4E69": "ji", "4FBB": "tuo", "525C": "wan", "57BA": "pei", "6EF6": "ao", "798A": "xi", "8DD2": "qia", "8C68": "xi", "8D50": "ci", "9598": "zha", "990B": "yang", "99F8": "qin", "4FEC": "si", "5217": "lie", "5F45": "none", "7DD9": "ke", "99F2": "none", "7C6D": "shai", "846D": "jia", "6333": "keng", "6EF7": "lu", "73F9": "cheng", "8054": "lian", "92E8": "e", "9942": "yun", "5470": "zi", "5FCE": "ren", "8240": "fu", "8590": "leng", "5BB8": "chen", "5EF9": "po", "6264": "wu", "6B80": "yao", "74D4": "ying", "8525": "cong", "7918": "qi", "8134": "pi", "8616": "nie", "511F": "chang", "5712": "yuan", "69F0": "beng", "713A": "sheng", "74D3": "lan", "8512": "xun", "886C": "chen", "8ACE": "ze", "8AEC": "qi", "5D0A": "none", "629C": "ba", "7301": "li", "7E44": "yi", "8B62": "sui", "6318": "none", "696F": "shun;dun", "6CE5": "ni", "71CF": "yu", "7D03": "xun", "7D26": "ba", "95DB": "tang", "99C4": "tuo;duo", "5000": "chang", "5552": "hu", "5BE8": "zhai", "60FF": "ti", "62E4": "qia", "65A2": "tiao;tou", "8DFF": "tu", "9EB1": "fu", "5E3B": "ze", "74C7": "rou", "8A96": "bei", "4EA3": "ta", "52EF": "dan", "6330": "cheng", "7896": "lun", "816A": "yun", "9D25": "yu", "9D57": "xi", "5035": "wu", "504B": "bing", "66B3": "hui", "6A74": "none", "80F0": "yi", "82E5": "ruo;re", "8AB5": "xiao", "8D61": "shan", "8E68": "nian", "92C6": "yun", "4E67": "none", "540C": "tong", "5F07": "yan", "749F": "jing", "802E": "lao", "8387": "zhu", "4FF9": "ya", "542A": "e", "6470": "chi", "6D7E": "cheng", "81F8": "zhi", "512E": "li", "5EDE": "xin", "8654": "qian", "871E": "qi", "8FFD": "zhui", "682C": "zui", "88E7": "tan", "51BD": "lie", "57AF": "da", "7915": "pi", "82F2": "zha", "86CE": "li", "89F3": "hu", "8CF7": "ji", "5646": "can", "6EAA": "xi;qi", "7ACE": "fu", "84B0": "pan", "590A": "sui", "6FEE": "pu", "7C1A": "mi", "98C7": "biao", "545F": "quan", "6280": "ji", "628F": "wan", "64DC": "none", "6FC9": "sui", "7B7D": "none", "8746": "yang", "90FA": "yong", "80F7": "xiong", "779A": "shun", "84F3": "jin", "942F": "zhuo", "52BD": "lie", "53C9": "cha", "5DF0": "qiu", "5E9F": "fei", "6860": "ya", "8B0C": "ge", "9A3C": "lu", "9C2D": "qi", "9E1A": "ying", "5F56": "tuan", "667B": "an", "877E": "rong", "88B4": "ku", "8EA5": "cuan", "9434": "bi", "94CF": "xing", "4EA5": "hai", "544E": "chi", "79B4": "yue", "7FE8": "shi", "8334": "hui", "8342": "kua", "8437": "xiao", "8696": "yuan", "86D9": "wa", "8CBF": "mao", "912B": "ceng", "9B33": "juan", "6CE3": "qi;xie", "707D": "zai", "7948": "qi", "7F6E": "zhi", "8AAE": "none", "9200": "ba;pa", "60D6": "ti", "7058": "tan", "5C4F": "ping;bing", "6412": "bang;peng", "6ADD": "du", "8728": "die", "8EFA": "yao", "953A": "zhong", "5190": "mao;mo", "6E21": "du", "7EB6": "lun;guan", "8A5F": "zhe", "505E": "ye", "658E": "zhai", "702F": "ying", "7245": "die", "7B4A": "jiao", "7BF5": "cong", "914C": "zhuo", "57E1": "wu;ya", "5A19": "keng", "5E40": "zhen;zheng", "6FFE": "lu", "5AF1": "qiang", "5B68": "chan", "7CC4": "bian", "8112": "mi", "859C": "bi;bo", "8641": "nao", "96C2": "qin", "5262": "zhuo", "546E": "qi", "73EC": "xu", "7F8C": "qiang", "81A1": "ying", "8FB6": "chuo", "9338": "lai", "6F7A": "chan", "8155": "wan", "8D25": "bai", "922D": "zi", "9EF3": "yi", "5BA9": "shi", "5E32": "ping", "640C": "zhan", "7D55": "jue", "8F2B": "pai", "565C": "lu", "5AEB": "mo", "61E1": "mo", "695F": "ting", "6D24": "quan", "763D": "jin", "7BF3": "bi", "8F91": "ji", "937C": "zhen", "9F5A": "ze", "4FBF": "bian;pian", "501A": "yi", "5624": "ying", "5EE4": "none", "675B": "gong", "7E13": "quan", "54EA": "na;nei;nai", "6E50": "mo", "846E": "duan", "52D2": "le;lei", "6EB6": "rong", "7029": "dui", "7947": "zhi;qi", "9092": "ting", "9B5F": "hong", "7491": "wu", "768B": "gao", "7893": "dui", "7A4C": "su;wei", "7BEC": "qiang", "8FF7": "mi", "5955": "yi", "5A70": "dian", "617C": "qi", "6A6C": "cen", "7C00": "ze;kui", "9348": "ying", "97B3": "ta", "52AA": "nu;nao", "5B31": "can", "6380": "xian", "76BE": "du", "790C": "lei", "83C9": "lu", "9B0D": "hu", "5469": "shi", "5CAD": "ling", "64D0": "huan", "862C": "kui", "56C7": "li", "5C0D": "dui", "6161": "shuang", "78DD": "ao", "865A": "xu", "9287": "lei", "9618": "da;ta", "4FFD": "xin", "67E4": "zha", "743B": "none", "5C5A": "lou", "7C71": "zhuo", "8122": "mei", "94E0": "kai", "59F6": "yan", "5C26": "liao", "7B1B": "di", "7F52": "gang", "909E": "fu", "6BBA": "sha;shai", "9331": "zhen", "4F02": "pei", "5393": "ya", "60A9": "nao", "633E": "xie;jia;xia", "7124": "fu", "73CC": "bi", "7E71": "cong", "95FF": "kai", "536D": "qiong", "5F9D": "zhi", "6E27": "di", "6FFD": "luo", "8E77": "jue", "5521": "liang", "5D72": "nie", "6485": "jue", "7043": "feng", "7D6E": "xu", "8E21": "quan", "578F": "lu", "68F3": "zhuo", "6FCC": "ta", "74EE": "weng", "78B7": "none", "8F56": "se", "8F8D": "chuo", "5113": "tai", "5760": "zhui", "59F3": "ming", "62BE": "qu", "9A56": "tie", "5CFE": "yin", "6B5B": "lian", "72F2": "sun", "8FF8": "beng", "912D": "zheng", "5761": "po", "6587": "wen", "817C": "mian", "4E7E": "qian;gan", "736F": "xun", "82BF": "reng", "8418": "nai", "9D08": "yan", "754A": "geng", "97C5": "xian", "4E8C": "er", "58C7": "tan", "58CA": "huai;pi", "64FF": "zhi", "7272": "sheng", "76BF": "min", "8186": "su", "9631": "jing", "5186": "yuan", "587A": "mei", "5CC9": "e", "8300": "fu", "831D": "chai", "885F": "dao", "9AAA": "wei", "546D": "yi", "5705": "han", "57AC": "hong", "5B35": "mian", "5C3B": "kao", "7797": "diao", "8C62": "huan", "950B": "feng", "967B": "yin", "5264": "ji", "546B": "zhan", "6A08": "qing", "8440": "gua", "8DA6": "zi", "9912": "nei", "9BCF": "none", "62B6": "chi", "75CD": "yi", "7E72": "jie", "824F": "shou", "93C9": "shou", "99B5": "zhu", "9D5E": "e", "551E": "dou", "8482": "di", "92C8": "wu", "5254": "ti", "56A6": "li", "8680": "shi", "8887": "ran", "569C": "mo", "6106": "qian", "6591": "ban", "7869": "che", "7C59": "lu", "7DE9": "huan", "8468": "wei", "9635": "zhen", "4E72": "none", "5A03": "wa", "5B7F": "luan", "68E7": "zhan", "7D75": "hui", "808A": "yi", "8D09": "tan", "91C1": "xin", "9C85": "ba", "6444": "she", "709E": "bian", "774B": "e", "813D": "shui", "87AB": "shi;zhe", "54D2": "da", "598B": "fu", "6C6F": "hong", "6E16": "shen", "7195": "none", "8C5E": "hou", "8F50": "pu", "939E": "bi", "5B64": "gu", "5BFF": "shou", "663C": "zhou", "9CE8": "li", "4F7C": "jiao", "513F": "er", "823E": "xi", "941C": "dui", "4EDF": "qian", "5305": "bao", "603A": "none", "6621": "xuan", "75B2": "pi", "7AA7": "none", "7E39": "piao", "8C61": "xiang", "9265": "shu", "93D6": "ao", "98F2": "yin", "65C8": "liu", "67DE": "zuo;zha", "7FB4": "shan", "89A7": "lan", "98B8": "si", "9BA7": "yi", "9F1F": "teng", "61F0": "liu", "64F4": "kuo", "6B1D": "yu", "7500": "chui", "875B": "wei", "8CE9": "cong", "69A9": "qian", "84CA": "weng", "8FCB": "wang", "5B9B": "wan;yuan", "63E1": "wo", "7B5F": "fu", "95A8": "gui", "961A": "kan;han", "9A51": "liu", "9B9B": "shua", "9D95": "fu", "694B": "la", "6F86": "jiao", "7546": "mu", "93A9": "sha", "9EA7": "ge", "5E8C": "ya", "7194": "rong", "52B6": "kou", "6771": "dong", "6DD7": "ju", "7499": "liao", "9565": "lu", "970C": "chou", "5DD8": "yan", "6227": "chuang;qiang", "63CA": "pi", "7154": "tian", "7F7D": "ji", "8C18": "zi", "9999": "xiang", "6243": "jiong", "70E5": "none", "9046": "ti", "5DEE": "cha;chai;ci", "6006": "chuang", "6913": "zhuo", "6D9F": "lian", "8107": "xie", "8ED4": "ren", "9E8C": "wu", "9E99": "yan", "6DE2": "yu", "8769": "chong", "895F": "jin", "8F5A": "ji", "94CB": "bi", "56AF": "huo", "58DC": "tan", "7757": "shi", "90E1": "jun", "9414": "tan;chan;xin", "4E93": "qi", "50F5": "jiang", "6366": "qin", "7D14": "chun", "9506": "gao", "9A61": "peng", "9F2F": "wu", "5FCB": "gai", "61BF": "jiao", "6F7C": "tong", "7A08": "gan", "9A44": "cong", "95E4": "huan", "963A": "di", "98D4": "si", "9F08": "bie", "6AAA": "li;yue", "56A9": "mo", "5889": "yong", "5D49": "ting", "6699": "chun", "76A1": "hao", "80BA": "fei", "957E": "mi", "9BC8": "chou", "664F": "yan", "6D09": "hou", "7753": "tian", "52BB": "kuang", "5C77": "none", "5CF3": "you", "6806": "none", "7203": "rong", "75B7": "qi", "89C1": "jian;xian", "5B43": "niang", "66E1": "die", "760E": "shen", "847B": "lan", "88BC": "ge", "54CF": "gen", "5870": "none", "62DC": "bai", "679C": "guo", "7048": "qu", "7265": "fang", "7DE3": "yuan", "6F62": "huang", "706F": "deng", "866A": "shu", "9196": "yun", "4F6B": "he", "580C": "gu", "7779": "du", "8988": "he", "8F45": "yuan", "9595": "xia", "5BB6": "jia;gu;jie", "6209": "yue", "6C91": "rou", "7A22": "yu", "7BA7": "qie", "7E22": "teng", "8552": "mai", "8A8A": "teng", "6383": "sao", "9CA3": "jian", "5D69": "song", "69B4": "liu", "71E7": "sui", "7793": "shui", "7BD5": "he", "9B07": "zheng", "578A": "none", "5C98": "xian", "646B": "gui", "780B": "zhi", "7DA5": "qi", "831F": "yu", "890F": "xiu", "9535": "qiang", "9757": "cheng", "684B": "yi", "6875": "rui", "737E": "huan", "7496": "qu", "9033": "yu", "946F": "jian", "4F2E": "nao;nu", "64AC": "qiao", "67BA": "mo", "74A6": "ai", "6426": "nuo", "6773": "yao;miao", "6AFA": "ling", "6CD2": "gu", "6E14": "yu", "7870": "cuo", "5988": "ma", "5C63": "xi", "6747": "wu", "6E41": "shi", "6E7C": "nie", "6FEB": "lan", "7873": "none", "960D": "hun", "9A43": "piao;biao", "66AB": "zan;zhan", "85B3": "wei", "5510": "tang", "6504": "shu", "7FFB": "fan", "8FF2": "none", "9525": "zhui", "53B3": "yan", "68EA": "yan", "6CCC": "mi;bi", "8031": "mo", "8D81": "chen", "5669": "e", "59AD": "ba", "74F6": "ping", "88D3": "ge", "9F41": "hou", "6D32": "zhou", "7F68": "yan", "91ED": "gong;gang", "5137": "li", "6013": "nao", "75EB": "xian", "8FB1": "ru", "930A": "zui", "98A7": "quan", "5039": "jian", "6513": "qian", "6D16": "wu", "8F66": "che;ju", "8AA1": "jie", "5063": "yan", "5BE9": "shen", "71D5": "yan", "7A2D": "jie", "7B82": "lai", "932A": "dian", "9788": "jia", "8A1C": "fen", "96DB": "chu", "67D0": "mou", "7576": "dang", "767C": "fa", "80A4": "fu", "7F71": "lan", "9AB6": "di", "6E82": "la", "7599": "ge", "91D7": "zhao", "59FE": "quan", "68AF": "ti", "7F93": "ba", "93C3": "zu;cu", "9587": "bi", "9EDC": "chu", "5A6A": "lan", "5EB0": "bing", "6B22": "huan", "848B": "jiang", "5803": "kun", "7DE7": "qiu", "7F19": "jin", "9E4D": "kun", "77F3": "shi;dan", "80E0": "qu", "848F": "none", "5668": "qi", "8090": "ge", "826C": "chan", "83DD": "ba", "87F9": "xie", "974A": "feng", "9B3D": "mei", "5F39": "dan;tan", "70B4": "yang", "7841": "keng", "8BF3": "kuang", "51EC": "feng", "54C9": "zai", "6763": "none", "7B6F": "zhu", "81BF": "nong", "83AC": "wen", "8426": "ying", "85DD": "yi", "4F89": "kua", "5584": "shan", "6568": "dou", "8F9C": "gu", "55C0": "huo", "7FAA": "yang", "8339": "ru", "83A1": "cuo", "8C1D": "pian", "8D76": "gan", "8DA8": "qu;cu", "9B6C": "fan", "9C67": "li", "9CEF": "feng", "5C74": "li", "5D3C": "shi", "6851": "sang", "71DF": "ying", "74E9": "qian;wa", "7BD2": "none", "8A66": "shi", "8FAD": "ci", "5C8C": "ji", "61EC": "xing", "69D4": "gao", "69F5": "huan", "7358": "bi", "89FE": "yan", "987F": "dun", "7566": "qi;xi", "792D": "que", "79B6": "zan", "8AC8": "chui", "51C0": "jing", "61A7": "chong", "719A": "bi", "93B5": "jia", "95CA": "kuo", "9D88": "qi", "53FA": "chi", "7CAE": "liang", "8DAC": "qiao", "97BC": "gui", "6528": "wa", "696E": "chu", "9881": "ban", "6F1D": "xi", "7D4A": "zui", "822F": "zhong", "6219": "dong", "9304": "lu", "9646": "lu;liu", "81E8": "lin", "91EF": "mang", "4F24": "shang", "509D": "ta", "5D58": "rong", "7200": "he", "7C08": "ping", "8B3D": "jiang", "9D59": "ju", "4ED4": "zi;zai", "52D3": "kai", "6494": "heng", "6A4A": "liu", "6B99": "hun", "859B": "xue", "8A2F": "sa", "975B": "dian", "5751": "keng", "611F": "gan", "63B2": "jie", "678C": "fen", "69FC": "gui", "7371": "bian", "78EE": "none", "4F78": "huo", "5DD4": "dian", "6165": "zao", "7B20": "li", "8643": "jian", "8742": "ban", "9612": "qu", "9634": "yin", "520D": "chu", "5D20": "dong", "74F9": "juan", "7FF6": "none", "83C2": "di", "8A21": "yin", "5835": "du", "6CCF": "chu", "7517": "yan", "77DF": "shuo", "8230": "jian", "982D": "tou", "99EC": "er", "9C12": "fu", "9CC2": "wei", "7AF8": "jing", "8AFC": "xuan", "8EF6": "e", "63B1": "shou;pa", "65AD": "duan", "79D8": "mi;bi;lin", "7EC8": "zhong", "983D": "tui", "5571": "yan", "5EC4": "jiu", "645C": "guan", "65B1": "zhuo", "682B": "jian", "777B": "xuan", "79E7": "yang", "80CC": "bei", "969A": "tang", "9CEC": "fu", "9DC4": "ji", "895B": "nong", "95FD": "min", "99E7": "dong", "9B97": "none", "5BAA": "xian", "69F6": "kui", "6EFB": "chan", "4FC7": "kuang", "5875": "chen", "5F87": "xun", "5FA0": "lai", "60DD": "chang", "6FA1": "zao", "81A5": "chun", "92E0": "shen", "962D": "yun", "548C": "he;huo;hai", "564A": "yu", "6749": "shan", "768D": "ji", "8A3C": "zheng", "4F67": "ka", "53DF": "sou", "5460": "pen", "5A6F": "li", "6267": "zhi", "6686": "yi", "677F": "ban", "6B3B": "hu", "8E05": "xue", "8E17": "nie", "9D0C": "feng", "517B": "yang", "6465": "tang", "6881": "liang", "7027": "long;shuang", "737F": "nao", "7382": "qi", "798B": "yin", "862B": "lan", "9C5D": "fen", "68DE": "hun", "70E3": "hui", "754B": "tian", "85A6": "jian", "86EC": "gong", "8947": "jian", "8E8F": "lin", "9BA2": "zhu", "55F2": "dia", "5958": "zhuang;zang", "5D10": "kun", "6196": "yin", "7BEE": "lan", "814F": "chuo;duo", "8DC9": "ling", "97E5": "du", "9E3E": "luan", "9F73": "nian", "569F": "li", "5CBC": "none", "6532": "qi", "7368": "du", "7A06": "lu", "7FF4": "lian", "9C31": "lian", "9E6E": "huan", "5651": "hao", "81ED": "chou;xiu", "8798": "yi", "9E9C": "li", "4F1E": "san", "6931": "fu", "7B93": "lu", "5CEC": "bu", "6033": "huang", "6626": "hao", "6E54": "jian", "70A6": "ba", "740D": "li", "8B52": "bo", "9783": "hong", "9958": "zhan", "9E3D": "ge", "9F6C": "yu", "5071": "xun", "5362": "lu", "5559": "zi", "7556": "wa", "9DB7": "xia", "5AF2": "none", "60E0": "hui", "651E": "luo", "71BB": "xi", "7562": "bi", "7581": "liu", "8272": "se;shai", "4F5E": "ning", "54D9": "kuai", "5C86": "yao", "6B2C": "kai", "7C7E": "ni", "8ACC": "jian", "921E": "jun", "5030": "leng", "71E5": "zao", "73D8": "zhou", "76CF": "zhan", "9DD5": "yao", "50EA": "jue", "511E": "ni", "64B7": "xie", "6583": "bi", "6939": "shen;zhen", "7FD2": "xi", "914D": "pei", "9AD4": "ti", "9DFC": "xian", "64CE": "qing", "778C": "ke", "7DB9": "liu", "8776": "die", "912A": "bi", "9937": "cha", "9A23": "zong", "5D04": "xian", "6F48": "none", "86A5": "fu", "8DE1": "ji", "5412": "zha", "7005": "ying", "7A26": "yi", "817F": "tui", "8428": "sa", "55A3": "xu", "5DA7": "yi", "5E6F": "jie", "7B7A": "kuang", "7BF4": "di", "7BFE": "mie", "6204": "jue", "63AE": "qian", "5BB5": "xiao", "5DE2": "chao", "5DFB": "juan", "60C1": "xi", "8490": "sou", "8840": "xue;xie", "8D1A": "long", "4E17": "shi", "608E": "hao", "7568": "pan", "8520": "zhong", "8D9C": "ju", "9724": "liu", "69AD": "xie", "6D45": "qian;jian", "6EAB": "wen", "8A19": "xun", "91DA": "qiu", "5294": "jian", "639C": "yi", "7B3D": "none", "82DF": "gou", "85DF": "lei", "8781": "tun", "94E8": "quan", "626C": "yang", "672C": "ben", "7205": "mo", "7BEA": "chi", "8491": "yin", "5F17": "fu", "7774": "gun", "7837": "shen", "7C4D": "ji", "84EE": "lian", "4FF0": "he", "5C43": "xi", "64B1": "tuo", "8881": "yuan", "8E3F": "zu", "9494": "men", "9EA1": "qi", "6AE4": "none", "7AC8": "zao", "9E7E": "cuo", "6569": "xiao", "6E4F": "xu", "7B61": "tu", "901B": "guang", "54FF": "ge", "898A": "ji", "5C9E": "zuo", "9DA9": "mu;wu", "52C5": "chi", "5549": "lin", "5EBF": "miao", "697A": "rou", "5214": "jue", "5EB1": "cheng", "7787": "mi", "93DD": "man", "9CAE": "ling", "744C": "ruan", "7623": "lei", "803D": "dan", "8352": "huang", "8CD6": "she", "5405": "xuan", "559E": "ji", "88D0": "juan", "99C3": "kuai", "578B": "xing", "7E4E": "ran", "4E0E": "yu", "4FB6": "lu", "57EE": "tan", "5FD3": "gan", "6381": "cheng", "70BD": "chi", "7E1C": "yun", "8226": "tai", "5430": "hu", "552A": "feng", "976D": "ren", "4EC1": "ren", "5180": "ji", "569E": "zhe", "5A88": "none", "67A9": "song", "7ABC": "ju", "7F72": "shu", "8DA7": "ti", "5219": "ze", "6A17": "chu;shu", "8F92": "wen", "549C": "zha", "5B3E": "lan", "61C4": "qin", "62FB": "hui", "6B90": "su", "6DC5": "xi", "6E43": "pai", "805D": "guo", "9A2D": "zhi", "5108": "kuai", "5A38": "qi", "6789": "wang", "715D": "mei", "7264": "mang", "7AEB": "jing", "962C": "keng", "5F7A": "wang", "656E": "xia", "7544": "liu", "77DC": "jin;qin;guan", "7D83": "xiao", "7DE0": "di", "92EF": "gao", "9345": "none", "9A8E": "qin", "51EB": "fu", "5389": "li", "6F27": "qian", "79EC": "ju", "8A0A": "xun", "5FB1": "piao", "6060": "guai", "64E7": "ju", "661C": "yang", "791D": "ruan", "82A4": "kou", "9C71": "li", "5746": "fen", "8CE1": "geng", "99A9": "fen", "5B79": "bo", "7652": "yu", "7F8A": "yang", "85CD": "lan", "861E": "lian", "9233": "ke", "9809": "yi", "6295": "tou", "6E20": "qu", "88B1": "fu", "5680": "ning", "5863": "cheng", "5FC1": "bao", "6265": "tuo", "6460": "zong", "7398": "qi", "81C8": "la;xi", "9F87": "zi", "6C0C": "lu", "75A8": "xia", "8556": "qu", "902D": "huan", "9CC8": "quan", "686E": "bei", "87BD": "zhong", "9B81": "ba", "5DFA": "xun", "604C": "tiao", "6E62": "bi", "79F5": "yin", "9363": "zhao", "6F19": "tuan", "959C": "ke", "64B5": "nian", "6744": "qian", "6A24": "tiao", "7098": "xin", "7548": "fan", "9725": "meng", "9D33": "yan", "5D73": "cuo", "5FA4": "jian", "63D0": "ti;di;shi", "671A": "huang", "6A0D": "ji", "7419": "yu", "814B": "ye;yi", "8B9F": "du", "5A1E": "sui", "6717": "lang", "697F": "gui", "99D4": "zang", "50BD": "zhang", "52E6": "jiao;chao", "6175": "yong", "6DAC": "xing", "7065": "quan", "71F3": "zhao", "89A2": "shan", "5969": "lian", "5B87": "yu", "7FA2": "rong", "857A": "ji", "87C6": "ma", "87CF": "xiao", "9754": "qi", "5960": "dian", "5AC9": "ji", "5E72": "gan", "627D": "dun", "68D0": "fei", "6FF6": "kuo", "8F32": "chuan", "90CF": "jia", "9D5F": "kuang", "9E1C": "qu", "56DE": "hui", "7705": "pan", "776F": "hun", "789B": "qi", "7911": "dang", "795D": "zhu", "5F8D": "wang", "7FD8": "qiao", "8ECA": "che;ju", "94E2": "zhu", "99A7": "wen", "4F80": "xing", "54E6": "e;o;wo", "5FA3": "jie", "6D9A": "shui", "9005": "hou", "90DD": "hao", "947C": "luo", "4E04": "shang", "5A3E": "ai", "73BE": "jia", "9CD6": "bie", "67E6": "dan", "7163": "rou", "71F0": "wei", "74B7": "fu", "7BC3": "mei", "8096": "xiao", "8499": "meng", "8DE4": "jiao", "55A9": "yu", "7424": "cheng", "7587": "chou", "7F59": "mi", "6F7D": "pu", "74BE": "ji", "7D89": "xiu", "8A87": "kua", "8AA2": "xian", "5A5A": "hun", "63EB": "jiu", "8608": "tui", "87E2": "xi", "4E6F": "none", "6F15": "cao", "7009": "xie", "7BB7": "shi;yi", "8995": "mie", "8D52": "zhou", "8D8B": "qu", "9744": "ai", "9A80": "tai;dai", "9DD3": "zhe", "4E12": "chou", "691B": "none", "75FC": "gu", "91F9": "nu", "58CC": "rang", "5B8A": "tu", "666F": "jing;ying", "6953": "feng", "7069": "yan", "7621": "chuang", "7680": "bi", "9123": "zhang", "6944": "bian", "6FA8": "shi", "775B": "jing", "877F": "ying", "5045": "zhong", "6103": "xuan", "6FD9": "ying", "83AF": "mu", "8AAD": "du;dou", "9B27": "nao", "6098": "yi", "6A62": "tuo", "70E4": "kao", "7812": "pi", "7B4E": "ru", "830E": "jing", "90F1": "ping", "94FD": "te", "5A4D": "qi", "5B48": "shuai", "69F7": "yi", "6D54": "xun", "7208": "di", "5B42": "jiao", "7EA0": "jiu", "8056": "sheng", "4E77": "sha", "646D": "zhi", "6993": "mi", "73C4": "sheng", "7AEC": "qu", "7AED": "jie", "9640": "tuo", "98AE": "biao", "53D7": "shou", "5E38": "chang", "5F47": "xiao", "602B": "fu;fei", "6102": "bei", "6302": "gua", "71FA": "kao", "885E": "wei", "9409": "chuan", "97A1": "la", "5252": "cuo", "5983": "fei", "5BBF": "su;xiu", "9D1E": "xiao", "9EDB": "dai", "62F2": "gong", "6698": "yang", "688F": "gu", "731C": "cai", "8D64": "chi", "9615": "que", "96E7": "ji", "9DBF": "zi", "9E40": "wu", "55A0": "zhong", "79DF": "zu", "83A6": "shao", "8436": "chun", "89FF": "xi", "9085": "zhan", "910E": "xi", "99D3": "pi", "9AA0": "piao;biao", "5C6D": "xi", "79EE": "tai", "7C96": "mo", "911A": "mao", "5868": "gong", "6447": "yao", "6B05": "ju", "758E": "shu", "7A2F": "zong", "86D7": "fu", "91DE": "zhi", "9CEA": "bu", "7572": "she", "7D1D": "ren", "8101": "tiao", "82D4": "tai", "899B": "mo", "95B2": "yue", "9C1A": "none", "554D": "tun", "5827": "ruan", "5C55": "zhan", "6064": "xu", "6118": "qia", "8267": "huo", "89E9": "qiu", "5A46": "po", "626F": "che", "8E9D": "lan", "6AD2": "sa", "7E54": "zhi", "98D7": "liu", "4FE5": "che", "6801": "liu", "6E8D": "jin", "6EA0": "zha", "9B3F": "qi", "6F5E": "lu", "74CA": "qiong", "7B7C": "yun", "88EC": "ling", "8BEA": "zhou", "936F": "huo", "553D": "xi", "6722": "wang", "6791": "hu", "68CC": "cai", "72E9": "shou", "8921": "da", "53AE": "si", "6B75": "cuo", "9320": "ding", "5724": "yan", "58DF": "long", "5D87": "qu", "86B1": "zha", "8C2F": "qiao", "8317": "ming", "718A": "xiong", "8174": "yu", "8534": "ma", "8653": "xiao", "86D2": "ge", "4EA7": "chan", "522D": "jing", "7688": "gui", "7DB2": "wang", "88B7": "jia;qia", } ���������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pinyin/pinyin.go���������������������������������������������������������������������000664 �000000 �000000 �00000003164 13753517240 016200� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pinyin import ( "strconv" "strings" "unicode" ) func HansToPinyin(hans string) []string { return getPinyinFromKey(hans) } func getPinyinFromKey(key string) []string { rets := []string{} for _, c := range key { if unicode.Is(unicode.Scripts["Han"], c) { array := getPinyinByHan(int64(c)) if len(rets) == 0 { rets = array continue } rets = rangeArray(rets, array) } else { array := []string{string(c)} if len(rets) == 0 { rets = array } else { rets = rangeArray(rets, array) } } } return rets } func getPinyinByHan(han int64) []string { code := strconv.FormatInt(han, 16) value := PinyinDataMap[strings.ToUpper(code)] array := strings.Split(value, ";") return array } func rangeArray(a1, a2 []string) []string { rets := []string{} for _, v := range a1 { for _, r := range a2 { rets = append(rets, v+r) } } return rets } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pinyin_search/�����������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015664� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pinyin_search/pinyin_search.go�������������������������������������������������������000664 �000000 �000000 �00000010700 13753517240 021044� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package pinyin_search import ( "bytes" "sort" "strings" "unicode" "github.com/mozillazg/go-pinyin" ) func GeneralizeQuery(q string) string { var buf bytes.Buffer for _, r := range q { if unicode.IsSpace(r) || unicode.IsPunct(r) { continue } else { buf.WriteRune(unicode.ToLower(r)) } } return buf.String() } func strSliceUniq(slice []string) []string { length := len(slice) if length == 0 { return nil } else if length == 1 { return slice } else if length == 2 { if slice[0] == slice[1] { return slice[:1] } else { return slice } } else { return strSliceUniqAux(slice) } } func strSliceUniqAux(in []string) []string { // In-place deduplicate sort.Strings(in) j := 0 for i := 1; i < len(in); i++ { if in[j] == in[i] { continue } j++ // preserve the original data // in[i], in[j] = in[j], in[i] // only set what is required in[j] = in[i] } return in[:j+1] } type Blocks []block var pinyinArgs pinyin.Args func init() { pinyinArgs = pinyin.NewArgs() pinyinArgs.Heteronym = true } func Split(str string) Blocks { if str == "" { return nil } var result Blocks var buf bytes.Buffer for _, r := range str { pys := pinyin.SinglePinyin(r, pinyinArgs) pys = strSliceUniq(pys) if len(pys) > 0 { // 是汉字 if buf.Len() > 0 { result = append(result, commonBlock(buf.String())) buf.Reset() } result = append(result, zhBlock{ zh: r, pys: pys, }) } else if unicode.IsSpace(r) || unicode.IsPunct(r) { if buf.Len() > 0 { result = append(result, commonBlock(buf.String())) buf.Reset() } } else { r = unicode.ToLower(r) buf.WriteRune(r) } } if buf.Len() > 0 { result = append(result, commonBlock(buf.String())) } return result } type block interface { isBlock() } type zhBlock struct { zh rune pys []string } func (zb zhBlock) isBlock() { } func (zb zhBlock) getList() []string { var result []string result = append(result, string(zb.zh)) for _, py := range zb.pys { result = append(result, getPyList(py)...) } return result } func getPyList(py string) []string { // zhong -> zhong,zhon,zho,zh,z if len(py) == 0 { return nil } result := make([]string, len(py)) for i := 0; i < len(py); i++ { result[i] = string(py[:len(py)-i]) } return result } type commonBlock string func (c commonBlock) isBlock() { } func (blocks Blocks) Match(query string) bool { if query == "" { return false } for i := 0; i < len(blocks); i++ { if matchBegin(blocks[i:], query) { return true } } return false } func matchBegin(blocks []block, query string) (result bool) { //log.Printf("start match %#v %#v\n", blocks, query) //defer func() { // log.Printf("end match %#v %#v, result: %v\n", blocks, query, result) //}() if query == "" { return false } qIdx := 0 blocksIdx := 0 for { if blocksIdx >= len(blocks) { break } if qIdx >= len(query) { break } b := blocks[blocksIdx] switch block := b.(type) { case commonBlock: bbs := string(block) query0 := query[qIdx:] // commonBlock 匹配条件: 全部,或因为 query0 不足够,只能匹配部分。 isMatch, end, n := matchAux(bbs, query0) if isMatch { if end { return true } else { qIdx += n blocksIdx++ } } else { return false } case zhBlock: list := block.getList() query0 := query[qIdx:] for _, value := range list { // compare value and query0 isMatch, end, n := matchAux(value, query0) if isMatch { if end { return true } else { if blocksIdx+1 < len(blocks) { if matchBegin(blocks[blocksIdx+1:], query0[n:]) { return true } } else { // blocks end return false } } } } return false } } return false } // 当 isMatch 为 true 时, end 和 n 才有意义。 // 当 end 有意义时,如果 end 为 false, n 才有意义。 func matchAux(target, query string) (isMatch bool, end bool, n int) { if len(query) == len(target) { if query == target { isMatch = true end = true } else { isMatch = false } } else if len(query) < len(target) { // target: dong, query: do if strings.HasPrefix(target, query) { isMatch = true end = true } else { isMatch = false } } else { // target: dong, query: dongx if strings.HasPrefix(query, target) { isMatch = true n = len(target) } else { isMatch = false } } //log.Printf("isMatch: %v, end: %v, n: %v\n", isMatch, end, n) return } ����������������������������������������������������������������go-lib-5.6.0.9/pinyin_search/t1_test.go�������������������������������������������������������������000664 �000000 �000000 �00000006521 13753517240 017602� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package pinyin_search import ( "testing" "github.com/stretchr/testify/assert" ) func TestGeneralize(t *testing.T) { ret := GeneralizeQuery("Firefox - Browser") assert.Equal(t, "firefoxbrowser", ret) } func Test_strSliceUniq(t *testing.T) { ret := strSliceUniq(nil) assert.Nil(t, ret) ret = strSliceUniq([]string{"a"}) assert.Equal(t, []string{"a"}, ret) ret = strSliceUniq([]string{"a", "a"}) assert.Equal(t, []string{"a"}, ret) ret = strSliceUniq([]string{"a", "b"}) assert.Equal(t, []string{"a", "b"}, ret) ret = strSliceUniq([]string{"b", "c", "a", "b", "c"}) assert.Equal(t, []string{"a", "b", "c"}, ret) } func Test_getPyList(t *testing.T) { ret := getPyList("zhong") assert.Equal(t, []string{"zhong", "zhon", "zho", "zh", "z"}, ret) ret = getPyList("z") assert.Equal(t, []string{"z"}, ret) ret = getPyList("") assert.Nil(t, ret) } func Test_matchAux(t *testing.T) { isMatch, end, n := matchAux("dong", "dong") assert.True(t, isMatch) assert.True(t, end) _ = n isMatch, end, _ = matchAux("dong", "don") assert.True(t, isMatch) assert.True(t, end) isMatch, end, n = matchAux("dong", "dongsh") assert.True(t, isMatch) assert.False(t, end) assert.Equal(t, 4, n) isMatch, _, _ = matchAux("dong", "sh") assert.False(t, isMatch) } func TestSplit(t *testing.T) { ret := Split("") assert.Nil(t, ret) ret = Split("中文汉字") assert.Equal(t, Blocks{ zhBlock{zh: '中', pys: []string{"zhong"}}, zhBlock{zh: '文', pys: []string{"wen"}}, zhBlock{zh: '汉', pys: []string{"han"}}, zhBlock{zh: '字', pys: []string{"zi"}}}, ret) ret = Split("的不") assert.Equal(t, Blocks{ zhBlock{zh: '的', pys: []string{"de", "di"}}, zhBlock{zh: '不', pys: []string{"bu", "fou", "fu"}}, }, ret) ret = Split(" english word web-browser ") assert.Equal(t, Blocks{ commonBlock("english"), commonBlock("word"), commonBlock("web"), commonBlock("browser"), }, ret) ret = Split(" hello-world! 中文 english word ") assert.Equal(t, Blocks{ commonBlock("hello"), commonBlock("world"), zhBlock{zh: '中', pys: []string{"zhong"}}, zhBlock{zh: '文', pys: []string{"wen"}}, commonBlock("english"), commonBlock("word"), }, ret) } func Test_matchBegin(t *testing.T) { blocks := Split("钟南") ret := matchBegin(blocks, "zhongnan") assert.True(t, ret) ret = matchBegin(blocks, "zn") assert.True(t, ret) ret = matchBegin(blocks, "z") assert.True(t, ret) ret = matchBegin(blocks, "n") assert.False(t, ret) ret = matchBegin(blocks, "zhongna") assert.True(t, ret) ret = matchBegin(blocks, "zhona") assert.True(t, ret) ret = matchBegin(blocks, "zhna") assert.True(t, ret) ret = matchBegin(blocks, "钟nan") assert.True(t, ret) blocks = Split("open web browser") ret = matchBegin(blocks, "open") assert.True(t, ret) ret = matchBegin(blocks, "op") assert.True(t, ret) ret = matchBegin(blocks, "openwebbrowser") assert.True(t, ret) ret = matchBegin(blocks, "openweb") assert.True(t, ret) ret = matchBegin(blocks, "opweb") assert.False(t, ret) } func TestMatch(t *testing.T) { blocks := Split("李钟南") ret := blocks.Match("zhongnan") assert.True(t, ret) blocks = Split("启动firefox") ret = blocks.Match("dofirefox") assert.True(t, ret) ret = blocks.Match("firefox") assert.True(t, ret) ret = blocks.Match("fir") assert.True(t, ret) ret = blocks.Match("firg") assert.False(t, ret) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/procfs/������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014325� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/procfs/procfs.go���������������������������������������������������������������������000664 �000000 �000000 �00000006742 13753517240 016161� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package procfs import ( "fmt" "io/ioutil" "os" "path/filepath" "pkg.deepin.io/lib/encoding/kv" "strconv" "strings" ) type Process uint func (p Process) getFile(name string) string { return fmt.Sprintf("/proc/%d/%s", uint(p), name) } func (p Process) Exist() bool { procDir := fmt.Sprintf("/proc/%d", uint(p)) _, err := os.Stat(procDir) return err == nil } func (p Process) Cmdline() ([]string, error) { cmdlineFile := p.getFile("cmdline") bytes, err := ioutil.ReadFile(cmdlineFile) if err != nil { return nil, err } content := string(bytes) parts := strings.Split(content, "\x00") length := len(parts) if length >= 2 && parts[length-1] == "" { return parts[:length-1], nil } return parts, nil } func (p Process) Cwd() (string, error) { cwdFile := p.getFile("cwd") cwd, err := os.Readlink(cwdFile) return cwd, err } func (p Process) Exe() (string, error) { exeFile := p.getFile("exe") exe, err := filepath.EvalSymlinks(exeFile) return exe, err } type EnvVars []string func (p Process) Environ() (EnvVars, error) { envFile := p.getFile("environ") contents, err := ioutil.ReadFile(envFile) if err != nil { return nil, err } return strings.Split(string(contents), "\x00"), nil } func (vars EnvVars) Lookup(key string) (string, bool) { prefix := key + "=" for _, aVar := range vars { if strings.HasPrefix(aVar, prefix) { return aVar[len(prefix):], true } } return "", false } func (vars EnvVars) Get(key string) string { ret, _ := vars.Lookup(key) return ret } type Status []*kv.Pair func (p Process) Status() (Status, error) { statusFile := p.getFile("status") f, err := os.Open(statusFile) if err != nil { return nil, err } defer f.Close() r := kv.NewReader(f) r.Delim = ':' r.TrimSpace = kv.TrimDelimRightSpace | kv.TrimTailingSpace pairs, err := r.ReadAll() if err != nil { return nil, err } return Status(pairs), nil } func (st Status) lookup(key string) (string, error) { for _, pair := range st { if pair.Key == key { return pair.Value, nil } } return "", StatusFieldNotFoundErr{key} } type StatusFieldNotFoundErr struct { Field string } func (err StatusFieldNotFoundErr) Error() string { return fmt.Sprintf("field %s is not found in proc status file", err.Field) } func (st Status) Uids() ([]uint, error) { uids := make([]uint, 0, 4) value, err := st.lookup("Uid") if err != nil { return nil, err } for _, i := range strings.Split(value, "\t") { v, err := strconv.ParseUint(i, 10, 32) if err != nil { return nil, err } uids = append(uids, uint(v)) } return uids, nil } func (st Status) PPid() (uint, error) { value, err := st.lookup("PPid") if err != nil { return 0, err } v, err := strconv.ParseUint(value, 10, 32) if err != nil { return 0, err } return uint(v), nil } ������������������������������go-lib-5.6.0.9/procfs/procfs_test.go����������������������������������������������������������������000664 �000000 �000000 �00000006672 13753517240 017222� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package procfs import ( "os" "testing" . "github.com/smartystreets/goconvey/convey" ) func TestGetFile(t *testing.T) { Convey("getFile", t, func(c C) { p := Process(1) c.So(p.getFile("cwd"), ShouldEqual, "/proc/1/cwd") }) } func TestExist(t *testing.T) { Convey("Exist", t, func(c C) { p := Process(os.Getpid()) c.So(p.Exist(), ShouldBeTrue) }) } func TestCmdline(t *testing.T) { Convey("Cmdline", t, func(c C) { p := Process(os.Getpid()) cmdline, err := p.Cmdline() c.So(err, ShouldBeNil) t.Log("cmdline:", cmdline) c.So(len(cmdline) > 0, ShouldBeTrue) }) } func TestCwd(t *testing.T) { Convey("Cwd", t, func(c C) { p := Process(os.Getpid()) cwd, err := p.Cwd() c.So(err, ShouldBeNil) t.Log("cwd:", cwd) osWd, err1 := os.Getwd() c.So(err1, ShouldBeNil) c.So(cwd, ShouldEqual, osWd) }) } func TestExe(t *testing.T) { Convey("Exe", t, func(c C) { p := Process(os.Getpid()) exe, err := p.Exe() c.So(err, ShouldBeNil) t.Log("exe:", exe) c.So(len(exe) > 0, ShouldBeTrue) }) } func TestEnvVars(t *testing.T) { vars := EnvVars{ "PWD=/a/b/c", } Convey("EnvVars.Lookup", t, func(c C) { pwd, ok := vars.Lookup("PWD") c.So(pwd, ShouldEqual, "/a/b/c") c.So(ok, ShouldBeTrue) abc, ok := vars.Lookup("abc") c.So(abc, ShouldEqual, "") c.So(ok, ShouldBeFalse) }) Convey("EnvVars.Get", t, func(c C) { pwd := vars.Get("PWD") c.So(pwd, ShouldEqual, "/a/b/c") abc := vars.Get("abc") c.So(abc, ShouldEqual, "") }) } func TestEnvion(t *testing.T) { Convey("Envion", t, func(c C) { p := Process(os.Getpid()) environ, err := p.Environ() c.So(err, ShouldBeNil) c.So(len(environ) > 0, ShouldBeTrue) for _, aVar := range environ { t.Log(string(aVar)) } path, ok := environ.Lookup("PATH") c.So(ok, ShouldBeTrue) c.So(path != "", ShouldBeTrue) home, ok := environ.Lookup("HOME") c.So(ok, ShouldBeTrue) c.So(home != "", ShouldBeTrue) xxx, ok := environ.Lookup("XXXXXXXXXXXXXXX") c.So(ok, ShouldBeFalse) c.So(xxx, ShouldEqual, "") }) } func TestStatus(t *testing.T) { Convey("Status", t, func(c C) { p := Process(os.Getpid()) status, err := p.Status() c.So(err, ShouldBeNil) c.So(status, ShouldNotBeEmpty) // test lookup val, err := status.lookup("XXX") c.So(val, ShouldBeBlank) c.So(err, ShouldResemble, StatusFieldNotFoundErr{"XXX"}) c.So(err.Error(), ShouldEqual, "field XXX is not found in proc status file") // test Uids uids, err := status.Uids() c.So(err, ShouldBeNil) t.Log("uids:", uids) c.So(uids[0], ShouldEqual, uint(os.Getuid())) c.So(uids[1], ShouldEqual, uint(os.Geteuid())) // test PPid ppid, err := status.PPid() c.So(err, ShouldBeNil) t.Log("ppid:", ppid) c.So(ppid, ShouldBeGreaterThan, 0) }) } ����������������������������������������������������������������������go-lib-5.6.0.9/profile/�����������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014471� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/profile/profile.go�������������������������������������������������������������������000664 �000000 �000000 �00000010014 13753517240 016454� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ // profiling of your Go application. package profile import ( "io" "os" "os/signal" "path/filepath" "runtime/pprof" "sync" "pkg.deepin.io/lib/initializer/v2" ) type _Profile struct { writer io.Writer //nolint file string } func (prof *_Profile) File() string { return prof.file } type _CPUProfile struct { _Profile } func newCPUProfile(file string) *_CPUProfile { return &_CPUProfile{_Profile{file: file}} } func (prof *_CPUProfile) Start(writer io.Writer) { _ = pprof.StartCPUProfile(writer) } func (prof *_CPUProfile) Stop() { pprof.StopCPUProfile() } type _MemProfile struct { _Profile } func newMemPrifle(file string) *_MemProfile { return &_MemProfile{_Profile{file: file}} } func (prof *_MemProfile) Start(writer io.Writer) { prof.writer = writer } func (prof *_MemProfile) Stop() { _ = pprof.Lookup("heap").WriteTo(prof.writer, 0) } type _BlockProfile struct { _Profile } func newBlockProfile(file string) *_BlockProfile { return &_BlockProfile{_Profile{file: file}} } func (prof *_BlockProfile) Start(writer io.Writer) { prof.writer = writer } func (prof *_BlockProfile) Stop() { _ = pprof.Lookup("block").WriteTo(prof.writer, 0) } // Config controls the operation of the profile package. type Config struct { // CPUProfile is the name of cpu profile which controls if cpu profiling will be enabled. // It defaults to false. CPUProfile string // MemProfile is the name of memory profile which controls if cpu profiling will be enabled. // It defaults to false. MemProfile string // MemProfile is the name of memory profile which controls if cpu profiling will be enabled. // It defaults to false. BlockProfile string // NoShutdownHook controls whether the profiling package should // hook SIGINT to write profiles cleanly. // Programs with more sophisticated signal handling should set // this to true and ensure the Stop() function returned from Start() // is called during shutdown. NoShutdownHook bool closers []func() closeOnce sync.Once } func (cfg *Config) enableProfile(prof interface { File() string Start(io.Writer) Stop() }) error { file := prof.File() // if name is empty, do not enable profile. if file == "" { return nil } var err error err = os.MkdirAll(filepath.Dir(file), 0777) if err != nil { return err } f, err := os.Create(file) if err != nil { cfg.stop() return err } prof.Start(f) cfg.closers = append(cfg.closers, func() { prof.Stop() _ = f.Close() }) return nil } // Start starts a new profiling session configured using *Config. // The caller should call the Stop method to cleanly stop profiling. func (cfg *Config) Start() error { if err := initializer.Do(func() error { return cfg.enableProfile(newCPUProfile(cfg.CPUProfile)) }).Do(func() error { return cfg.enableProfile(newMemPrifle(cfg.MemProfile)) }).Do(func() error { return cfg.enableProfile(newBlockProfile(cfg.BlockProfile)) }).GetError(); err != nil { return err } if !cfg.NoShutdownHook { go func() { c := make(chan os.Signal, 1) signal.Notify(c, os.Interrupt) <-c cfg.stop() os.Exit(0) }() } return nil } func (cfg *Config) stop() { cfg.closeOnce.Do(func() { for _, c := range cfg.closers { c() } }) } // Stop stops all profile. func (cfg *Config) Stop() { if !cfg.NoShutdownHook { return } cfg.stop() } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/profile/profile_test.go��������������������������������������������������������������000664 �000000 �000000 �00000002047 13753517240 017522� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package profile func ExampleConfig_Start() { p := &Config{CPUProfile: "test"} if err := p.Start(); err != nil { // error handle return } } func ExampleConfig_Stop() { p := &Config{CPUProfile: "cpu.prof", NoShutdownHook: true} if err := p.Start(); err != nil { // error handle return } p.Stop() } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/profile/time.go����������������������������������������������������������������������000664 �000000 �000000 �00000002734 13753517240 015764� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2015 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package profile import ( "time" ) // Timer recoreds time cost. type Timer struct { startTime time.Time moduleStartTime time.Time endTime time.Time } // NewTimer creates a new timer and start it. func NewTimer() *Timer { t := &Timer{} t.startTime = time.Now() t.endTime = t.startTime return t } // Elapsed returns the time duration from the time of start or last elapsed. func (t *Timer) Elapsed() time.Duration { endTime := time.Now() sub := endTime.Sub(t.moduleStartTime) t.moduleStartTime = endTime return sub } // TotalCost will stop the timer and return the total cost time. func (t *Timer) TotalCost() time.Duration { if t.startTime == t.endTime { t.endTime = time.Now() } return t.endTime.Sub(t.startTime) } ������������������������������������go-lib-5.6.0.9/proxy/�������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014212� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/proxy/README.md����������������������������������������������������������������������000664 �000000 �000000 �00000001544 13753517240 015475� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������网络代理相关库, 监听并将 gsettings(com.deepin.wrap.gnome.system.proxy) 的值同步给当前进程的环境变量, 用到的环境变量包括: ``` http_proxy="http://user:pass@127.0.0.1:8080/" https_proxy="https://127.0.0.1:8080/" ftp_proxy="ftp://127.0.0.1:8080/" all_proxy="http://127.0.0.1:8080/" SOCKS_SERVER=socks5://127.0.0.1:8000/ no_proxy="localhost,127.0.0.0/8,::1" ``` 因为 Linux 没有统一的接口处理系统代理, Deepin 在兼容 GNOME 系统代理的 基础上同时会设置环境变量, 以求适配更多的网络应用, 由于环境变量是进程内 设置的, 所以抽象出这个库用于给 Deepin 相关程序(startdde/launcher/dock) 动态更新系统代理环境变量, 使用方法很简单: ```go import ( "pkg.deepin.io/gir/glib-2.0" "pkg.deepin.io/lib/proxy" ) func main() { SetupProxy() glib.StartLoop() } ``` ������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/proxy/dev_test.go��������������������������������������������������������������������000664 �000000 �000000 �00000002153 13753517240 016357� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������//+build dev /* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package proxy import ( "pkg.deepin.io/gir/glib-2.0" C "gopkg.in/check.v1" "pkg.deepin.io/lib/log" "testing" ) func Test(t *testing.T) { C.TestingT(t) } type testWrapper struct{} func init() { C.Suite(&testWrapper{}) } func (*testWrapper) TestMain(c *C.C) { logger.SetLogLevel(log.LevelDebug) SetupProxy() logger.Info("start loop...") glib.StartLoop() } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/proxy/proxy.go�����������������������������������������������������������������������000664 �000000 �000000 �00000013066 13753517240 015730� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package proxy import ( "fmt" "os" "pkg.deepin.io/gir/gio-2.0" "pkg.deepin.io/lib/gsettings" "pkg.deepin.io/lib/log" "pkg.deepin.io/lib/utils" "strconv" "strings" ) // Synchronize proxy gsettings to environment variables. // // Examples of proxy environment variables: // http_proxy="http://user:pass@127.0.0.1:8080/" // https_proxy="https://127.0.0.1:8080/" // ftp_proxy="ftp://127.0.0.1:8080/" // all_proxy="http://127.0.0.1:8080/" // SOCKS_SERVER=socks5://127.0.0.1:8000/ // no_proxy="localhost,127.0.0.0/8,::1" const ( // general proxy environment variables, works for wget/curl/aria2c envAutoProxy = "auto_proxy" envHttpProxy = "http_proxy" envHttpsProxy = "https_proxy" envFtpProxy = "ftp_proxy" envAllProxy = "all_proxy" envNoProxy = "no_proxy" // special proxy environment variable for chrome envSocksProxy = "SOCKS_SERVER" gsettingsIdProxy = "com.deepin.wrap.gnome.system.proxy" proxyTypeHttp = "http" proxyTypeHttps = "https" proxyTypeFtp = "ftp" proxyTypeSocks = "socks5" gkeyProxyMode = "mode" proxyModeNone = "none" proxyModeManual = "manual" proxyModeAuto = "auto" gkeyProxyAuto = "autoconfig-url" gkeyProxyIgnoreHosts = "ignore-hosts" gkeyProxyHost = "host" gkeyProxyPort = "port" gchildProxyHttp = "http" gchildProxyHttps = "https" gchildProxyFtp = "ftp" gchildProxySocks = "socks" ) var ( logger = log.NewLogger("go-lib/proxy") proxySettings *gio.Settings proxyChildSettingsHttp *gio.Settings proxyChildSettingsHttps *gio.Settings proxyChildSettingsFtp *gio.Settings proxyChildSettingsSocks *gio.Settings ) // SetupProxy setup system proxy, need followed with glib.StartLoop(). func SetupProxy() { proxySettings = gio.NewSettings(gsettingsIdProxy) proxyChildSettingsHttp = proxySettings.GetChild(gchildProxyHttp) proxyChildSettingsHttps = proxySettings.GetChild(gchildProxyHttps) proxyChildSettingsFtp = proxySettings.GetChild(gchildProxyFtp) proxyChildSettingsSocks = proxySettings.GetChild(gchildProxySocks) updateProxyEnvs() listenProxyGsettings() } func listenProxyGsettings() { changedHandler := func(key string) { updateProxyEnvs() } const systemProxy = "system.proxy" gsettings.ConnectChanged(systemProxy, "*", changedHandler) gsettings.ConnectChanged(systemProxy+"."+gchildProxyHttp, "*", changedHandler) gsettings.ConnectChanged(systemProxy+"."+gchildProxyHttps, "*", changedHandler) gsettings.ConnectChanged(systemProxy+"."+gchildProxyFtp, "*", changedHandler) gsettings.ConnectChanged(systemProxy+"."+gchildProxySocks, "*", changedHandler) } func showEnvs() { showEnv(envHttpProxy) showEnv(envHttpsProxy) showEnv(envFtpProxy) showEnv(envSocksProxy) showEnv(envAllProxy) showEnv(envAutoProxy) showEnv(envNoProxy) } func showEnv(envName string) { if utils.IsEnvExists(envName) { logger.Debug(envName, os.Getenv(envName)) } else { logger.Debug(envName, "<not exists>") } } func updateProxyEnvs() { logger.Debug("update proxy environment variables...") os.Unsetenv(envHttpProxy) os.Unsetenv(envHttpsProxy) os.Unsetenv(envFtpProxy) os.Unsetenv(envSocksProxy) os.Unsetenv(envAutoProxy) os.Unsetenv(envAllProxy) os.Unsetenv(envNoProxy) proxyMode := proxySettings.GetString(gkeyProxyMode) switch proxyMode { case proxyModeNone: case proxyModeAuto: doSetEnv(envAutoProxy, proxySettings.GetString(gkeyProxyAuto)) case proxyModeManual: doSetEnv(envHttpProxy, getProxyValue(proxyTypeHttp)) doSetEnv(envHttpsProxy, getProxyValue(proxyTypeHttps)) doSetEnv(envFtpProxy, getProxyValue(proxyTypeFtp)) doSetEnv(envSocksProxy, getProxyValue(proxyTypeSocks)) arrayIgnoreHosts := proxySettings.GetStrv(gkeyProxyIgnoreHosts) ignoreHosts := strings.Join(arrayIgnoreHosts, ",") doSetEnv(envNoProxy, ignoreHosts) // fallback socks proxy value to http to be compatible with Qt>=4.6 if utils.IsEnvExists(envSocksProxy) && !utils.IsEnvExists(envHttpProxy) { doSetEnv(envHttpProxy, os.Getenv(envSocksProxy)) } } showEnvs() } func doSetEnv(env, value string) { if len(value) > 0 { os.Setenv(env, value) } } func getProxyValue(proxyType string) (proxyValue string) { childSettings, err := getProxyChildSettings(proxyType) if err != nil { return } host := childSettings.GetString(gkeyProxyHost) if len(host) == 0 { return } port := strconv.Itoa(int(childSettings.GetInt(gkeyProxyPort))) proxyValue = fmt.Sprintf("%s://%s:%s", proxyType, host, port) return } func getProxyChildSettings(proxyType string) (childSettings *gio.Settings, err error) { switch proxyType { case proxyTypeHttp: childSettings = proxyChildSettingsHttp case proxyTypeHttps: childSettings = proxyChildSettingsHttps case proxyTypeFtp: childSettings = proxyChildSettingsFtp case proxyTypeSocks: childSettings = proxyChildSettingsSocks default: err = fmt.Errorf("not a valid proxy type: %s", proxyType) logger.Error(err) } return } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/�������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014161� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/card.go������������������������������������������������������������������������000664 �000000 �000000 �00000007133 13753517240 015425� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" import "fmt" import "unsafe" const ( DirectionSink int = iota + 1 DirectionSource ) type CardPortInfo struct { PortInfo Direction int Profiles ProfileInfos2 } type CardPortInfos []CardPortInfo //typedef struct pa_card_info { // uint32_t index; /**< Index of this card */ // const char *name; /**< Name of this card */ // uint32_t owner_module; /**< Index of the owning module, or PA_INVALID_INDEX. */ // const char *driver; /**< Driver name */ // uint32_t n_profiles; /**< Number of entries in profile array */ // pa_card_profile_info* profiles; /**< \deprecated Superseded by profiles2 */ // pa_card_profile_info* active_profile; /**< \deprecated Superseded by active_profile2 */ // pa_proplist *proplist; /**< Property list */ // uint32_t n_ports; /**< Number of entries in port array */ // pa_card_port_info **ports; /**< Array of pointers to ports, or NULL. Array is terminated by an entry set to NULL. */ // pa_card_profile_info2** profiles2; /**< Array of pointers to available profiles, or NULL. Array is terminated by an entry set to NULL. \since 5.0 */ // pa_card_profile_info2* active_profile2; /**< Pointer to active profile in the array, or NULL. \since 5.0 */ //} pa_card_info; type Card struct { Index uint32 Name string OwnerModule uint32 Driver string PropList map[string]string Profiles ProfileInfos2 ActiveProfile ProfileInfo2 Ports CardPortInfos } func toCardInfo(info *C.pa_card_info) (c *Card) { c = &Card{} c.Index = uint32(info.index) c.Name = C.GoString(info.name) c.OwnerModule = uint32(info.owner_module) c.Driver = C.GoString(info.driver) c.PropList = toProplist(info.proplist) c.Profiles = toProfiles(uint32(info.n_profiles), info.profiles2) c.ActiveProfile = toProfile(info.active_profile2) c.Ports = toCardPorts(uint32(info.n_ports), info.ports) return } func (card *Card) SetProfile(name string) { c := GetContext() c.safeDo(func() { cname := C.CString(fmt.Sprint(card.Index)) pname := C.CString(name) op := C.pa_context_set_card_profile_by_name(c.ctx, cname, pname, C.get_success_cb(), nil) C.free(unsafe.Pointer(cname)) C.free(unsafe.Pointer(pname)) C.pa_operation_unref(op) }) } func (infos CardPortInfos) TrySelectProfile(portName string) (string, error) { for _, info := range infos { if info.Name != portName { continue } return info.Profiles.SelectProfile(), nil } return "", fmt.Errorf("Invalid card port name: %s", portName) } func (infos CardPortInfos) Get(name string, direction int) (CardPortInfo, error) { for _, info := range infos { if info.Name == name && info.Direction == direction { return info, nil } } return CardPortInfo{}, fmt.Errorf("Invalid card port name: %s", name) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/dde-pulse.c��������������������������������������������������������������������000664 �000000 �000000 �00000016337 13753517240 016221� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <pulse/pulseaudio.h> #include "dde-pulse.h" #include <string.h> #include <stdio.h> #include "_cgo_export.h" //convert int int connect_timeout = 0; static inline void __empty_success_cb(pa_context *c, int success, void *userdata) { if (success) { return; } int en = pa_context_errno(c); fprintf(stderr, "go-lib/pulse operation failed: %s. %p %p\n", pa_strerror(en), c, userdata); } pa_context_success_cb_t get_success_cb() { return __empty_success_cb; } void set_connect_timeout() { connect_timeout = 1; } static void __empty_index_cb(pa_context *c, uint32_t idx, void *userdata) { return; } pa_context_index_cb_t get_index_cb() { return __empty_index_cb; } #define DEFINE(ID, TYPE, PA_FUNC_SUFFIX) \ void receive_##TYPE##_cb(pa_context *c, const pa_##TYPE##_info *info, int eol, void *userdata) \ { \ if (eol < 0) { \ int en = pa_context_errno(c); \ fprintf(stderr, "receive_%s_cb failed: %s\n", \ #TYPE, \ pa_strerror(en)); \ } \ go_receive_some_info((int64_t)userdata, ID, (void*)info, eol); \ } \ void _get_##TYPE##_info(pa_threaded_mainloop* loop, pa_context *c, int64_t cookie, uint32_t index) \ { \ pa_operation_unref(pa_context_get_##TYPE##_info##PA_FUNC_SUFFIX(c, index, receive_##TYPE##_cb, (void*)cookie)); \ } \ void _get_##TYPE##_info_list(pa_threaded_mainloop* loop, pa_context* ctx, int64_t cookie) \ { \ pa_operation_unref(pa_context_get_##TYPE##_info_list(ctx, receive_##TYPE##_cb, (void*)cookie)); \ } DEFINE(PA_SUBSCRIPTION_EVENT_SINK, sink, _by_index); DEFINE(PA_SUBSCRIPTION_EVENT_SOURCE, source, _by_index); DEFINE(PA_SUBSCRIPTION_EVENT_SINK_INPUT, sink_input, ); DEFINE(PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT, source_output, ); DEFINE(PA_SUBSCRIPTION_EVENT_CARD, card, _by_index); DEFINE(PA_SUBSCRIPTION_EVENT_CLIENT, client, ); DEFINE(PA_SUBSCRIPTION_EVENT_MODULE, module, ); DEFINE(PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE, sample, _by_index); void receive_server_info_cb(pa_context *c, const pa_server_info *info, void *userdata) { if (info == NULL) { return; } go_receive_some_info((int64_t)userdata, PA_SUBSCRIPTION_EVENT_SERVER, (void*)info, 0); } void _get_server_info(pa_threaded_mainloop* loop, pa_context *c, int64_t cookie) { pa_operation_unref(pa_context_get_server_info(c, receive_server_info_cb, (void*)cookie)); } void dpa_context_subscribe_cb(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *userdata) { int facility = t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK; int event_type = t & PA_SUBSCRIPTION_EVENT_TYPE_MASK; go_handle_changed(facility, event_type, idx); } static void dpa_context_state_cb(pa_context* ctx, void* userdata) { int state = pa_context_get_state (ctx); go_handle_state_changed(state); } void setup_monitor(pa_threaded_mainloop* m, pa_context *ctx) { pa_threaded_mainloop_lock(m); pa_context_set_state_callback(ctx, dpa_context_state_cb, NULL); pa_context_set_subscribe_callback(ctx, dpa_context_subscribe_cb, NULL); pa_context_subscribe(ctx, PA_SUBSCRIPTION_MASK_SERVER | PA_SUBSCRIPTION_MASK_CARD | PA_SUBSCRIPTION_MASK_SINK | PA_SUBSCRIPTION_MASK_SOURCE | PA_SUBSCRIPTION_MASK_SINK_INPUT | PA_SUBSCRIPTION_MASK_SOURCE_OUTPUT | PA_SUBSCRIPTION_MASK_SAMPLE_CACHE, NULL, NULL); pa_threaded_mainloop_unlock(m); } static void _wait_context_state_change(pa_context* ctx, void* userdata) { pa_threaded_mainloop* loop = userdata; pa_threaded_mainloop_signal(loop, 0); } pa_context* new_pa_context(pa_threaded_mainloop* m) { pa_threaded_mainloop_lock(m); pa_threaded_mainloop_start(m); pa_mainloop_api* mlapi = pa_threaded_mainloop_get_api(m); pa_context* ctx = pa_context_new(mlapi, "go-pulseaudio"); pa_threaded_mainloop_unlock(m); connect_timeout = 0; pa_threaded_mainloop_lock(m); pa_context_set_state_callback(ctx, _wait_context_state_change, m); pa_context_connect(ctx, NULL, PA_CONTEXT_NOFAIL, NULL); int state = pa_context_get_state(ctx); while (state != PA_CONTEXT_READY) { // Exit condition one. if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) { pa_threaded_mainloop_unlock(m); fprintf(stderr, "Failed Connect to pulseaudio server\n"); return NULL; } // It must be the last line of while loop. // wait for connect state changed. pa_threaded_mainloop_wait(m); // Exit condition two. if (connect_timeout) { pa_threaded_mainloop_unlock(m); fprintf(stderr, "Failed Connect to pulseaudio server timeout\n"); return NULL; } state = pa_context_get_state(ctx); } pa_threaded_mainloop_unlock(m); setup_monitor(m, ctx); return ctx; } // #define PA_INVALID_INDEX ((uint32_t) -1) // // If idx is PA_INVALID_INDEX, all sinks will be suspended. void _suspend_sink_by_id(pa_threaded_mainloop *loop, pa_context* ctx, uint32_t idx, int suspend) { pa_operation* o = pa_context_suspend_sink_by_index(ctx, idx, suspend, get_success_cb(), NULL); if (!o) { fprintf(stderr, "Failed suspend sink %u\n", idx); return; } pa_operation_unref(o); } // If idx is PA_INVALID_INDEX, all sources will be suspended. void _suspend_source_by_id(pa_threaded_mainloop *loop, pa_context* ctx, uint32_t idx, int suspend) { pa_operation* o = pa_context_suspend_source_by_index(ctx, idx, suspend, get_success_cb(), NULL); if (!o) { fprintf(stderr, "Failed suspend sink %u\n", idx); return; } pa_operation_unref(o); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/dde-pulse.h��������������������������������������������������������������������000664 �000000 �000000 �00000003720 13753517240 016216� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef DDE_PULSE_H #define DDE_PULSE_H /* ANY function touch a _pa_context_ must hold the pa_threaded_mainloop lock !!!!!! And may object created by pa_context, like pa_stream_new also need hold the lock. */ #include <pulse/pulseaudio.h> #define DECLARE(TYPE) \ void _get_##TYPE##_info(pa_threaded_mainloop*, pa_context*, int64_t, uint32_t); \ void _get_##TYPE##_info_list(pa_threaded_mainloop*, pa_context*, int64_t); DECLARE(sink); DECLARE(sink_input); DECLARE(source); DECLARE(source_output); DECLARE(client); DECLARE(card); DECLARE(module); DECLARE(sample); void _get_server_info(pa_threaded_mainloop*, pa_context *c, int64_t cookie); pa_context* new_pa_context(pa_threaded_mainloop* ml); // Fixed gccgo(1.4) compile failed, becase of 'success_cb' duplicate definition pa_context_success_cb_t get_success_cb(); void set_connect_timeout(); pa_context_index_cb_t get_index_cb(); pa_stream* createMonitorStreamForSource(pa_threaded_mainloop* loop, pa_context* ctx, uint32_t source_idx, uint32_t stream_idx, int suspend); void _suspend_sink_by_id(pa_threaded_mainloop* loop, pa_context* ctx, uint32_t idx, int suspend); void _suspend_source_by_id(pa_threaded_mainloop* loop, pa_context* ctx, uint32_t idx, int suspend); #endif ������������������������������������������������go-lib-5.6.0.9/pulse/info_test.go�������������������������������������������������������������������000664 �000000 �000000 �00000000763 13753517240 016510� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package pulse import ( "os" "testing" "pkg.deepin.io/lib/xdg/basedir" ) // Please manually enable test CFLAGS in ./pulse.go func TestQueryInfo(t *testing.T) { homeDir := basedir.GetUserHomeDir() _, err := os.Stat(homeDir) if os.IsNotExist(err) { t.Skip("home dir is not exist") } _ = GetContext() ctx := GetContextForced() if ctx == nil { t.Skip("Can't connect to pulseaudio.") return } _, err = ctx.GetServer() if err != nil { t.Fatal("Can't query server info", err) } } �������������go-lib-5.6.0.9/pulse/mainloop_callbacks.go����������������������������������������������������������000664 �000000 �000000 �00000007477 13753517240 020344� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package pulse //#include "dde-pulse.h" import "C" import ( "fmt" "runtime" "unsafe" ) // ONLY C file and below function can use C.pa_threaded_mainloop_lock/unlock type safeDoCtx struct { fn func() loop *C.pa_threaded_mainloop } var pendingSafeDo = make(chan safeDoCtx) func startHandleSafeDo() { // Move all safeDo fn to here to avoid creating too many OS Thread. // Because GOMAXPROC only apply to go-runtime. for c := range pendingSafeDo { if c.fn != nil { runtime.LockOSThread() C.pa_threaded_mainloop_lock(c.loop) c.fn() C.pa_threaded_mainloop_unlock(c.loop) runtime.UnlockOSThread() } } } func init() { // TODO: encapsulate the logic to Context and adding Start/Stop logic. go startHandleSafeDo() } func freeContext(ctx *Context) { runtime.LockOSThread() C.pa_threaded_mainloop_lock(ctx.loop) // The pa_context_unref must be protected. // This operation will cancel all pending operations which will touch mainloop object. C.pa_context_unref(ctx.ctx) C.pa_threaded_mainloop_unlock(ctx.loop) // There no need to call pa_threaded_mainloop_stop. C.pa_threaded_mainloop_free(ctx.loop) runtime.UnlockOSThread() ctx.loop = nil ctx.ctx = nil } // safeDo invoke an function with lock func (c *Context) safeDo(fn func()) { pendingSafeDo <- safeDoCtx{fn, c.loop} } func (c *Context) AddEventChan(ch chan<- *Event) { c.mu.Lock() c.eventChanList = append(c.eventChanList, ch) c.mu.Unlock() } func (c *Context) RemoveEventChan(ch chan<- *Event) { c.mu.Lock() var newList []chan<- *Event for _, ch0 := range c.eventChanList { if ch0 != ch { newList = append(newList, ch0) } } c.eventChanList = newList c.mu.Unlock() } func (c *Context) AddStateChan(ch chan<- int) { c.mu.Lock() c.stateChanList = append(c.stateChanList, ch) c.mu.Unlock() } func (c *Context) RemoveStateChan(ch chan<- int) { c.mu.Lock() var newList []chan<- int for _, ch0 := range c.stateChanList { if ch0 != ch { newList = append(newList, ch0) } } c.stateChanList = newList c.mu.Unlock() } // ALL of below functions are invoked from pulse's mainloop thread. // So // 1. Don't hold go-runtime lock in current thread. // 2. Don't hold pa_threaded_mainloop in current thread. // // NOTE: // In pa_threaded_mainloop, _prepare_ and _dispatch_ is running // under lock. Only phrase _poll_ is release the lock. So callback // must not try to hold lock. //export go_handle_changed func go_handle_changed(facility int, event_type int, idx uint32) { event := &Event{ Facility: facility, Type: event_type, Index: idx, } ctx := GetContext() ctx.mu.Lock() for _, eventChan := range ctx.eventChanList { select { case eventChan <- event: default: } } ctx.mu.Unlock() } //export go_handle_state_changed func go_handle_state_changed(state int) { ctx := GetContext() ctx.mu.Lock() for _, stateChan := range ctx.stateChanList { select { case stateChan <- state: default: } } ctx.mu.Unlock() } //export go_update_volume_meter func go_update_volume_meter(source_index uint32, sink_index uint32, v float64) { sourceMeterLock.RLock() cb, ok := sourceMeterCBs[source_index] sourceMeterLock.RUnlock() if ok && cb != nil { cb(v) } } //export go_receive_some_info func go_receive_some_info(cookie int64, infoType int, info unsafe.Pointer, eol int) { ck := fetchCookie(cookie) if ck == nil { if eol == 0 { // Sometimes pulseaudio will send eol=1 to pa_context_get_*_by_index/name. fmt.Println("Warning: recieve_some_info with nil cookie", cookie, infoType, info) } return } switch { case eol == 1: ck.EndOfList() case eol == 0: // 1. the Feed will be blocked until the ck creator received. // 2. the creator of ck may be invoked under PendingCallback // so this must not be moved to PendingCallback. paInfo := NewPaInfo(info, infoType) ck.Feed(paInfo) case eol < 0: ck.Failed() } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/meter.c������������������������������������������������������������������������000664 �000000 �000000 �00000006047 13753517240 015450� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "dde-pulse.h" #include <string.h> #include <stdio.h> #include "_cgo_export.h" static void suspended_callback(pa_stream *s, void *userdata) { /*MainWindow *w = static_cast<MainWindow*>(userdata);*/ /*if (pa_stream_is_suspended(s))*/ /*w->updateVolumeMeter(pa_stream_get_device_index(s), PA_INVALID_INDEX, -1);*/ } static void read_callback(pa_stream *s, size_t length, void *userdata) { const void *data; double v; if (pa_stream_peek(s, &data, &length) < 0) { fprintf(stderr, "Failed to read data from stream"); return; } if (!data) { pa_stream_drop(s); return; } assert(length > 0); assert(length % sizeof(float) == 0); v = ((const float*) data)[length / sizeof(float) -1]; pa_stream_drop(s); if (v < 0) v = 0; if (v > 1) v = 1; go_update_volume_meter(pa_stream_get_device_index(s), pa_stream_get_monitor_stream(s), v); } pa_stream* createMonitorStreamForSource(pa_threaded_mainloop* loop, pa_context* ctx, uint32_t source_idx, uint32_t stream_idx, int suspend) { stream_idx = -1; pa_stream *s; char t[16]; pa_buffer_attr attr; pa_sample_spec ss; pa_stream_flags_t flags; ss.channels = 1; ss.format = PA_SAMPLE_FLOAT32; ss.rate = 25; memset(&attr, 0, sizeof(attr)); attr.fragsize = sizeof(float); attr.maxlength = (uint32_t) -1; snprintf(t, sizeof(t), "%u", source_idx); pa_threaded_mainloop_lock(loop); if (!(s = pa_stream_new(ctx, "Peak detect", &ss, NULL))) { pa_threaded_mainloop_unlock(loop); fprintf(stderr, "Failed to create monitoring stream"); return NULL; } if (stream_idx != (uint32_t) -1) pa_stream_set_monitor_stream(s, stream_idx); pa_stream_set_read_callback(s, read_callback, NULL); pa_stream_set_suspended_callback(s, suspended_callback, NULL); flags = (pa_stream_flags_t) (PA_STREAM_DONT_MOVE | PA_STREAM_PEAK_DETECT | PA_STREAM_ADJUST_LATENCY | (suspend ? PA_STREAM_DONT_INHIBIT_AUTO_SUSPEND : PA_STREAM_NOFLAGS)); if (pa_stream_connect_record(s, t, &attr, flags) < 0) { fprintf(stderr, "Failed to connect monitoring stream"); pa_stream_unref(s); pa_threaded_mainloop_unlock(loop); return NULL; } pa_threaded_mainloop_unlock(loop); return s; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/meter.go�����������������������������������������������������������������������000664 �000000 �000000 �00000003064 13753517240 015627� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" import "sync" var sourceMeterCBs = make(map[uint32]func(float64)) var sourceMeterLock sync.RWMutex type SourceMeter struct { core *C.pa_stream sourceIndex uint32 ctx *Context } func NewSourceMeter(c *Context, idx uint32) *SourceMeter { core := C.createMonitorStreamForSource(c.loop, c.ctx, C.uint32_t(idx), 0, 0) return &SourceMeter{ core: core, sourceIndex: idx, ctx: c, } } func (s *SourceMeter) Destroy() { sourceMeterLock.Lock() delete(sourceMeterCBs, s.sourceIndex) sourceMeterLock.Unlock() s.ctx.safeDo(func() { C.pa_stream_disconnect(s.core) C.pa_stream_unref(s.core) }) } func (s *SourceMeter) ConnectChanged(cb func(v float64)) { sourceMeterLock.Lock() sourceMeterCBs[s.sourceIndex] = cb sourceMeterLock.Unlock() } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/misc.go������������������������������������������������������������������������000664 �000000 �000000 �00000010535 13753517240 015447� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" import "unsafe" const ( VolumeMax = C.PA_VOLUME_MAX * 1.0 / C.PA_VOLUME_NORM VolumeUIMax = 99957.0 / C.PA_VOLUME_NORM // C.pa_sw_volume_from_dB(11.0) ) const ( AvailableTypeUnknow int = iota AvailableTypeNo AvailableTypeYes ) func toProplist(c *C.pa_proplist) map[string]string { var ret = make(map[string]string) var state unsafe.Pointer for key := C.pa_proplist_iterate(c, &state); key != nil; { ret[C.GoString(key)] = C.GoString(C.pa_proplist_gets(c, key)) key = C.pa_proplist_iterate(c, &state) } return ret } type ProfileInfo2 struct { Name string Description string Priority uint32 NSinks uint32 NSources uint32 Available int } type ProfileInfos2 []ProfileInfo2 type PortInfo struct { Name string Description string Priority uint32 Available int // 0: Unknow, 1: No, 2: Yes } type PortInfos []PortInfo func (infos PortInfos) Get(name string) *PortInfo { for _, info := range infos { if info.Name == name { return &info } } return nil } func (infos ProfileInfos2) Exists(name string) bool { for _, info := range infos { if info.Name == name { return true } } return false } func (infos ProfileInfos2) SelectProfile() string { if len(infos) == 0 { return "" } profile := infos.selectByAvailable(AvailableTypeYes) if len(profile.Name) != 0 { return profile.Name } profile = infos.selectByAvailable(AvailableTypeUnknow) if len(profile.Name) != 0 { return profile.Name } profile = infos.selectByAvailable(AvailableTypeNo) return profile.Name } func (infos ProfileInfos2) Len() int { return len(infos) } func (infos ProfileInfos2) Less(i, j int) bool { return infos[i].Priority > infos[j].Priority } func (infos ProfileInfos2) Swap(i, j int) { infos[i], infos[j] = infos[j], infos[i] } func (infos ProfileInfos2) selectByAvailable(available int) ProfileInfo2 { var profile ProfileInfo2 for _, info := range infos { if info.Available != available { continue } if profile.Priority < info.Priority { profile = info } } return profile } func toBool(v C.int) bool { if int(v) == 0 { return false } else { return true } } type Volume struct { paVolume C.pa_volume_t } func (v Volume) ToPercent() float64 { return float64(v.paVolume) / C.PA_VOLUME_NORM } func (v Volume) ToLiner() float64 { return float64(C.pa_sw_volume_to_linear(C.pa_volume_t(v.paVolume))) } func (v Volume) TodB() float64 { return float64(C.pa_sw_volume_to_dB(C.pa_volume_t(v.paVolume))) } type CVolume struct { core C.pa_cvolume } func (cv CVolume) Avg() float64 { return float64(C.pa_cvolume_max(&cv.core)) / C.PA_VOLUME_NORM } func (cv CVolume) Balance(cmap ChannelMap) float64 { return float64(C.pa_cvolume_get_balance(&cv.core, &cmap.core)) } func (cv CVolume) Fade(cmap ChannelMap) float64 { return float64(C.pa_cvolume_get_fade(&cv.core, &cmap.core)) } func (cv CVolume) SetAvg(v float64) CVolume { C.pa_cvolume_scale(&cv.core, C.pa_volume_t((C.double(v) * C.PA_VOLUME_NORM))) return cv } func (cv CVolume) SetBalance(cm ChannelMap, balance float64) CVolume { C.pa_cvolume_set_balance(&cv.core, &cm.core, C.float(balance)) return cv } func (cv CVolume) SetFade(cm ChannelMap, fade float64) CVolume { C.pa_cvolume_set_fade(&cv.core, &cm.core, C.float(fade)) return cv } type ChannelPosition int32 type ChannelMap struct { core C.pa_channel_map } func (cm ChannelMap) CanBalance() bool { if C.pa_channel_map_can_balance(&cm.core) == 0 { return false } else { return true } } func (cm ChannelMap) CanFade() bool { if C.pa_channel_map_can_fade(&cm.core) == 0 { return false } else { return true } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/proplist.go��������������������������������������������������������������������000664 �000000 �000000 �00000012137 13753517240 016370� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" const ( PA_PROP_MEDIA_NAME = "media.name" PA_PROP_MEDIA_TITLE = "media.title" PA_PROP_MEDIA_ARTIST = "media.artist" PA_PROP_MEDIA_COPYRIGHT = "media.copyright" PA_PROP_MEDIA_SOFTWARE = "media.software" PA_PROP_MEDIA_LANGUAGE = "media.language" PA_PROP_MEDIA_FILENAME = "media.filename" PA_PROP_MEDIA_ICON_NAME = "media.icon_name" PA_PROP_MEDIA_ROLE = "media.role" PA_PROP_FILTER_WANT = "filter.want" PA_PROP_FILTER_APPLY = "filter.apply" PA_PROP_FILTER_SUPPRESS = "filter.suppress" PA_PROP_EVENT_ID = "event.id" PA_PROP_EVENT_DESCRIPTION = "event.description" PA_PROP_EVENT_MOUSE_X = "event.mouse.x" PA_PROP_EVENT_MOUSE_Y = "event.mouse.y" PA_PROP_EVENT_MOUSE_HPOS = "event.mouse.hpos" PA_PROP_EVENT_MOUSE_VPOS = "event.mouse.vpos" PA_PROP_EVENT_MOUSE_BUTTON = "event.mouse.button" PA_PROP_WINDOW_NAME = "window.name" PA_PROP_WINDOW_ID = "window.id" PA_PROP_WINDOW_ICON_NAME = "window.icon_name" PA_PROP_WINDOW_X = "window.x" PA_PROP_WINDOW_Y = "window.y" PA_PROP_WINDOW_WIDTH = "window.width" PA_PROP_WINDOW_HEIGHT = "window.height" PA_PROP_WINDOW_HPOS = "window.hpos" PA_PROP_WINDOW_VPOS = "window.vpos" PA_PROP_WINDOW_DESKTOP = "window.desktop" PA_PROP_WINDOW_X11_DISPLAY = "window.x11.display" PA_PROP_WINDOW_X11_SCREEN = "window.x11.screen" PA_PROP_WINDOW_X11_MONITOR = "window.x11.monitor" PA_PROP_WINDOW_X11_XID = "window.x11.xid" PA_PROP_APPLICATION_NAME = "application.name" PA_PROP_APPLICATION_ID = "application.id" PA_PROP_APPLICATION_VERSION = "application.version" PA_PROP_APPLICATION_ICON_NAME = "application.icon_name" PA_PROP_APPLICATION_LANGUAGE = "application.language" PA_PROP_APPLICATION_PROCESS_ID = "application.process.id" PA_PROP_APPLICATION_PROCESS_BINARY = "application.process.binary" PA_PROP_APPLICATION_PROCESS_USER = "application.process.user" PA_PROP_APPLICATION_PROCESS_HOST = "application.process.host" PA_PROP_APPLICATION_PROCESS_MACHINE_ID = "application.process.machine_id" PA_PROP_APPLICATION_PROCESS_SESSION_ID = "application.process.session_id" PA_PROP_DEVICE_STRING = "device.string" PA_PROP_DEVICE_API = "device.api" PA_PROP_DEVICE_DESCRIPTION = "device.description" PA_PROP_DEVICE_BUS_PATH = "device.bus_path" PA_PROP_DEVICE_SERIAL = "device.serial" PA_PROP_DEVICE_VENDOR_ID = "device.vendor.id" PA_PROP_DEVICE_VENDOR_NAME = "device.vendor.name" PA_PROP_DEVICE_PRODUCT_ID = "device.product.id" PA_PROP_DEVICE_PRODUCT_NAME = "device.product.name" PA_PROP_DEVICE_CLASS = "device.class" PA_PROP_DEVICE_FORM_FACTOR = "device.form_factor" PA_PROP_DEVICE_BUS = "device.bus" PA_PROP_DEVICE_ICON_NAME = "device.icon_name" PA_PROP_DEVICE_ACCESS_MODE = "device.access_mode" PA_PROP_DEVICE_MASTER_DEVICE = "device.master_device" PA_PROP_DEVICE_BUFFERING_BUFFER_SIZE = "device.buffering.buffer_size" PA_PROP_DEVICE_BUFFERING_FRAGMENT_SIZE = "device.buffering.fragment_size" PA_PROP_DEVICE_PROFILE_NAME = "device.profile.name" PA_PROP_DEVICE_INTENDED_ROLES = "device.intended_roles" PA_PROP_DEVICE_PROFILE_DESCRIPTION = "device.profile.description" PA_PROP_MODULE_AUTHOR = "module.author" PA_PROP_MODULE_DESCRIPTION = "module.description" PA_PROP_MODULE_USAGE = "module.usage" PA_PROP_MODULE_VERSION = "module.version" PA_PROP_FORMAT_SAMPLE_FORMAT = "format.sample_format" PA_PROP_FORMAT_RATE = "format.rate" PA_PROP_FORMAT_CHANNELS = "format.channels" PA_PROP_FORMAT_CHANNEL_MAP = "format.channel_map" ) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/pulse.go�����������������������������������������������������������������������000664 �000000 �000000 �00000030015 13753517240 015637� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" #cgo pkg-config: libpulse glib-2.0 //enable below flags in test environment //#cgo CFLAGS: -fsanitize=thread //#cgo LDFLAGS: -ltsan */ import "C" import ( "fmt" "sync" "time" "unsafe" ) type Callback func(eventType int, idx uint32) const ( EventTypeNew = C.PA_SUBSCRIPTION_EVENT_NEW EventTypeChange = C.PA_SUBSCRIPTION_EVENT_CHANGE EventTypeRemove = C.PA_SUBSCRIPTION_EVENT_REMOVE ) const ( FacilityServer = C.PA_SUBSCRIPTION_EVENT_SERVER FacilitySink = C.PA_SUBSCRIPTION_EVENT_SINK FacilitySource = C.PA_SUBSCRIPTION_EVENT_SOURCE FacilitySinkInput = C.PA_SUBSCRIPTION_EVENT_SINK_INPUT FacilitySourceOutput = C.PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT FacilityCard = C.PA_SUBSCRIPTION_EVENT_CARD FacilityClient = C.PA_SUBSCRIPTION_EVENT_CLIENT FacilityModule = C.PA_SUBSCRIPTION_EVENT_MODULE FacilitySampleCache = C.PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE ) const ( ContextStateUnconnected = C.PA_CONTEXT_UNCONNECTED ContextStateConnecting = C.PA_CONTEXT_CONNECTING ContextStateAuthorizing = C.PA_CONTEXT_AUTHORIZING ContextStateSettingName = C.PA_CONTEXT_SETTING_NAME ContextStateReady = C.PA_CONTEXT_READY ContextStateFailed = C.PA_CONTEXT_FAILED ContextStateTerminated = C.PA_CONTEXT_TERMINATED ) type Event struct { Facility int Type int Index uint32 } type Context struct { eventChanList []chan<- *Event stateChanList []chan<- int mu sync.Mutex ctx *C.pa_context loop *C.pa_threaded_mainloop } func (c *Context) GetCardList() (r []*Card) { ck := newCookie() c.safeDo(func() { C._get_card_info_list(c.loop, c.ctx, C.int64_t(ck.id)) }) for _, info := range ck.ReplyList() { card := info.ToCard() if card == nil { continue } r = append(r, card) } return } func (c *Context) GetCard(index uint32) (*Card, error) { ck := newCookie() c.safeDo(func() { C._get_card_info(c.loop, c.ctx, C.int64_t(ck.id), C.uint32_t(index)) }) info := ck.Reply() if info == nil { return nil, fmt.Errorf("Can't obtain this instance for: %v", index) } card := info.ToCard() if card == nil { return nil, fmt.Errorf("'%d' not a valid card index", index) } return card, nil } func (c *Context) GetSinkList() (r []*Sink) { ck := newCookie() c.safeDo(func() { C._get_sink_info_list(c.loop, c.ctx, C.int64_t(ck.id)) }) for _, info := range ck.ReplyList() { sink := info.ToSink() if sink == nil { continue } r = append(r, sink) } return } func (c *Context) GetSink(index uint32) (*Sink, error) { ck := newCookie() c.safeDo(func() { C._get_sink_info(c.loop, c.ctx, C.int64_t(ck.id), C.uint32_t(index)) }) info := ck.Reply() if info == nil { return nil, fmt.Errorf("Can't obtain this instance for: %v", index) } sink := info.ToSink() if sink == nil { return nil, fmt.Errorf("'%d' not a valid sink index", index) } return sink, nil } func (c *Context) GetSinkInputList() (r []*SinkInput) { ck := newCookie() c.safeDo(func() { C._get_sink_input_info_list(c.loop, c.ctx, C.int64_t(ck.id)) }) for _, info := range ck.ReplyList() { si := info.ToSinkInput() if si == nil { continue } r = append(r, si) } return } func (c *Context) GetSinkInput(index uint32) (*SinkInput, error) { ck := newCookie() c.safeDo(func() { C._get_sink_input_info(c.loop, c.ctx, C.int64_t(ck.id), C.uint32_t(index)) }) info := ck.Reply() if info == nil { return nil, fmt.Errorf("Can't obtain this instance for: %v", index) } si := info.ToSinkInput() if si == nil { return nil, fmt.Errorf("'%d' not a valid sinkinput index", index) } return si, nil } func (c *Context) GetSourceList() (r []*Source) { ck := newCookie() c.safeDo(func() { C._get_source_info_list(c.loop, c.ctx, C.int64_t(ck.id)) }) for _, info := range ck.ReplyList() { source := info.ToSource() if source == nil { continue } r = append(r, source) } return } func (c *Context) GetSource(index uint32) (*Source, error) { ck := newCookie() c.safeDo(func() { C._get_source_info(c.loop, c.ctx, C.int64_t(ck.id), C.uint32_t(index)) }) info := ck.Reply() if info == nil { return nil, fmt.Errorf("Can't obtain this instance for: %v", index) } source := info.ToSource() if source == nil { return nil, fmt.Errorf("'%d' not a valid source index", index) } return source, nil } func (c *Context) GetServer() (*Server, error) { ck := newCookie() c.safeDo(func() { C._get_server_info(c.loop, c.ctx, C.int64_t(ck.id)) }) info := ck.Reply() if info == nil { return nil, fmt.Errorf("Can't obtain the server instance.") } s := info.ToServer() if s == nil { return nil, fmt.Errorf("Not found valid server") } return s, nil } func (c *Context) GetSourceOutputList() (r []*SourceOutput) { ck := newCookie() c.safeDo(func() { C._get_source_output_info_list(c.loop, c.ctx, C.int64_t(ck.id)) }) for _, info := range ck.ReplyList() { so := info.ToSourceOutput() if so == nil { continue } r = append(r, so) } return } func (c *Context) GetSourceOutput(index uint32) (*SourceOutput, error) { ck := newCookie() c.safeDo(func() { C._get_source_output_info(c.loop, c.ctx, C.int64_t(ck.id), C.uint32_t(index)) }) info := ck.Reply() if info == nil { return nil, fmt.Errorf("Can't obtain the this instance for: %v", index) } so := info.ToSourceOutput() if so == nil { return nil, fmt.Errorf("'%d' not a valid sourceoutput index", index) } return so, nil } func (c *Context) GetDefaultSource() string { s, _ := c.GetServer() if s != nil { return s.DefaultSourceName } return "" } func (c *Context) GetDefaultSink() string { s, _ := c.GetServer() if s != nil { return s.DefaultSinkName } return "" } func (c *Context) SetDefaultSink(name string) { c.safeDo(func() { cname := C.CString(name) op := C.pa_context_set_default_sink(c.ctx, cname, C.get_success_cb(), nil) C.pa_operation_unref(op) C.free(unsafe.Pointer(cname)) }) } func (c *Context) SetDefaultSource(name string) { c.safeDo(func() { cname := C.CString(name) op := C.pa_context_set_default_source(c.ctx, cname, C.get_success_cb(), nil) C.pa_operation_unref(op) C.free(unsafe.Pointer(cname)) }) } // MoveSinkInputsByName move sink-inputs to the special sink name func (c *Context) MoveSinkInputsByName(sinkInputs []uint32, sinkName string) { c.safeDo(func() { cname := C.CString(sinkName) for _, idx := range sinkInputs { op := C.pa_context_move_sink_input_by_name(c.ctx, C.uint32_t(idx), cname, C.get_success_cb(), nil) C.pa_operation_unref(op) } C.free(unsafe.Pointer(cname)) }) } // MoveSinkInputsByIndex move sink-inputs to the special sink index func (c *Context) MoveSinkInputsByIndex(sinkInputs []uint32, sinkIdx uint32) { c.safeDo(func() { for _, idx := range sinkInputs { op := C.pa_context_move_sink_input_by_index(c.ctx, C.uint32_t(idx), C.uint32_t(sinkIdx), C.get_success_cb(), nil) C.pa_operation_unref(op) } }) } // MoveSourceOutputsByName move source-outputs to the special source name func (c *Context) MoveSourceOutputsByName(sourceOutputs []uint32, sourceName string) { c.safeDo(func() { cname := C.CString(sourceName) for _, idx := range sourceOutputs { op := C.pa_context_move_source_output_by_name( c.ctx, C.uint32_t(idx), cname, C.get_success_cb(), nil, ) C.pa_operation_unref(op) } C.free(unsafe.Pointer(cname)) }) } // MoveSourceOutputsByIndex move source-outputs to the special source index func (c *Context) MoveSourceOutputsByIndex(sourceOutputs []uint32, sourceIdx uint32) { c.safeDo(func() { for _, idx := range sourceOutputs { op := C.pa_context_move_source_output_by_index( c.ctx, C.uint32_t(idx), C.uint32_t(sourceIdx), C.get_success_cb(), nil, ) C.pa_operation_unref(op) } }) } var ( __context *Context __ctxLocker sync.Mutex ) func GetContextForced() *Context { __ctxLocker.Lock() ctx := __context if ctx != nil { freeContext(ctx) __context = nil } __ctxLocker.Unlock() return GetContext() } var PulseInitTimeout = 15 func GetContext() *Context { __ctxLocker.Lock() defer __ctxLocker.Unlock() if __context == nil { loop := C.pa_threaded_mainloop_new() timer := time.AfterFunc(time.Second*time.Duration(PulseInitTimeout), func() { C.set_connect_timeout() C.pa_threaded_mainloop_signal(loop, 0) }) defer timer.Stop() ctx := C.new_pa_context(loop) if ctx == nil { //TODO: Free loop fmt.Println("Failed to init pulseaudio") return nil } __context = &Context{ ctx: ctx, loop: loop, } } return __context } func (c *Context) SuspendSinkById(idx uint32, suspend int) { c.safeDo(func() { C._suspend_sink_by_id(c.loop, c.ctx, C.uint32_t(idx), C.int(suspend)) }) } func (c *Context) SuspendSourceById(idx uint32, suspend int) { c.safeDo(func() { C._suspend_source_by_id(c.loop, c.ctx, C.uint32_t(idx), C.int(suspend)) }) } func (c *Context) SetSinkPortByIndex(sinkIndex uint32, portName string) { c.safeDo(func() { cPortName := C.CString(portName) op := C.pa_context_set_sink_port_by_index(c.ctx, C.uint32_t(sinkIndex), cPortName, C.get_success_cb(), nil) C.free(unsafe.Pointer(cPortName)) C.pa_operation_unref(op) }) } func (c *Context) SetSinkMuteByIndex(sinkIndex uint32, mute bool) { muteInt := 0 if mute { muteInt = 1 } c.safeDo(func() { op := C.pa_context_set_sink_mute_by_index(c.ctx, C.uint32_t(sinkIndex), C.int(muteInt), C.get_success_cb(), nil) C.pa_operation_unref(op) }) } func (c *Context) SetSinkVolumeByIndex(sinkIndex uint32, v CVolume) { c.safeDo(func() { op := C.pa_context_set_sink_volume_by_index(c.ctx, C.uint32_t(sinkIndex), &v.core, C.get_success_cb(), nil) C.pa_operation_unref(op) }) } func (c *Context) SetSourcePortByIndex(sourceIndex uint32, portName string) { c.safeDo(func() { cPortName := C.CString(portName) op := C.pa_context_set_source_port_by_index(c.ctx, C.uint32_t(sourceIndex), cPortName, C.get_success_cb(), nil) C.free(unsafe.Pointer(cPortName)) C.pa_operation_unref(op) }) } func (c *Context) SetSourceVolumeByIndex(sourceIndex uint32, v CVolume) { c.safeDo(func() { op := C.pa_context_set_source_volume_by_index(c.ctx, C.uint32_t(sourceIndex), &v.core, C.get_success_cb(), nil) C.pa_operation_unref(op) }) } func (c *Context) SetSourceMuteByIndex(sourceIndex uint32, mute bool) { muteInt := 0 if mute { muteInt = 1 } c.safeDo(func() { op := C.pa_context_set_source_mute_by_index(c.ctx, C.uint32_t(sourceIndex), C.int(muteInt), C.get_success_cb(), nil) C.pa_operation_unref(op) }) } func (c *Context) SetSinkInputVolume(sinkInputIndex uint32, v CVolume) { c.safeDo(func() { op := C.pa_context_set_sink_input_volume(c.ctx, C.uint32_t(sinkInputIndex), &v.core, C.get_success_cb(), nil) C.pa_operation_unref(op) }) } func (c *Context) SetSinkInputMute(sinkInputIndex uint32, mute bool) { muteInt := 0 if mute { muteInt = 1 } c.safeDo(func() { op := C.pa_context_set_sink_input_mute(c.ctx, C.uint32_t(sinkInputIndex), C.int(muteInt), C.get_success_cb(), nil) C.pa_operation_unref(op) }) } func (c *Context) LoadModule(name, argument string) { c.safeDo(func() { cName := C.CString(name) defer C.free(unsafe.Pointer(cName)) var cArgument *C.char if argument != "" { cArgument = C.CString(argument) defer C.free(unsafe.Pointer(cArgument)) } op := C.pa_context_load_module(c.ctx, cName, cArgument, C.get_index_cb(), nil) C.pa_operation_unref(op) }) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/server.go����������������������������������������������������������������������000664 �000000 �000000 �00000002743 13753517240 016024� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" type Server struct { UserName string HostName string ServerVersion string ServerName string //sample_spec DefaultSinkName string DefaultSourceName string Cookie uint32 ChannelMap ChannelMap } func toServerInfo(info *C.pa_server_info) *Server { s := &Server{} s.UserName = C.GoString(info.user_name) s.HostName = C.GoString(info.host_name) s.ServerVersion = C.GoString(info.server_version) s.ServerName = C.GoString(info.server_name) //sample_spec s.DefaultSinkName = C.GoString(info.default_sink_name) s.DefaultSourceName = C.GoString(info.default_source_name) s.Cookie = uint32(info.cookie) s.ChannelMap = ChannelMap{info.channel_map} return s } �����������������������������go-lib-5.6.0.9/pulse/simple/������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015452� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/simple/simple.go���������������������������������������������������������������000664 �000000 �000000 �00000006146 13753517240 017301� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package simple /* #cgo pkg-config: libpulse-simple #include <pulse/simple.h> #include <pulse/error.h> #include <stdlib.h> */ import "C" import ( "fmt" "unsafe" ) type Conn struct { Ptr unsafe.Pointer } func wrapConn(ptr *C.pa_simple) Conn { return Conn{Ptr: unsafe.Pointer(ptr)} } func (v Conn) native() *C.pa_simple { return (*C.pa_simple)(v.Ptr) } type StreamDirection uint const ( StreamDirectionPlayback = C.PA_STREAM_PLAYBACK ) type SampleFormat uint const ( SampleFormatU8 = C.PA_SAMPLE_U8 SampleFormatS16NE = C.PA_SAMPLE_S16NE SampleFormatS16LE = C.PA_SAMPLE_S16LE SampleFormatS16BE = C.PA_SAMPLE_S16BE SampleFormatFloat32LE = C.PA_SAMPLE_FLOAT32LE SampleFormatFloat32BE = C.PA_SAMPLE_FLOAT32BE SampleFormatS32LE = C.PA_SAMPLE_S32LE SampleFormatS32BE = C.PA_SAMPLE_S32BE ) type SampleSpec struct { Format SampleFormat Rate uint32 Channels uint8 } func (ss *SampleSpec) native() *C.pa_sample_spec { if ss == nil { return nil } var ss0 C.pa_sample_spec ss0.format = C.pa_sample_format_t(ss.Format) ss0.rate = C.uint32_t(ss.Rate) ss0.channels = C.uint8_t(ss.Channels) return &ss0 } // server: server name, empty for default // name: A descriptive name for this client, application name // dir: Open this stream for recording or playback? // dev: sink or source name, empty for default // streamName: A descriptive name for this stream (application name, song title, ...) // sampleSpec: The sample type to use func NewConn(server, name string, dir StreamDirection, dev, streamName string, sampleSpec *SampleSpec) (Conn, error) { var server0 *C.char if server != "" { server0 = C.CString(server) // or null defer C.free(unsafe.Pointer(server0)) } name0 := C.CString(name) var dev0 *C.char if dev != "" { dev0 = C.CString(dev) defer C.free(unsafe.Pointer(dev0)) } streamName0 := C.CString(streamName) var errCode C.int ret := C.pa_simple_new(server0, name0, C.pa_stream_direction_t(dir), dev0, streamName0, sampleSpec.native(), nil, nil, &errCode) // clean C.free(unsafe.Pointer(name0)) C.free(unsafe.Pointer(streamName0)) if ret == nil { return Conn{}, newError("pa_simple_new", errCode) } return wrapConn(ret), nil } func (c Conn) Write(data unsafe.Pointer, bytes uint) (int, error) { var errCode C.int ret := C.pa_simple_write(c.native(), data, C.size_t(bytes), &errCode) return int(ret), newError("pa_simple_write", errCode) } func (c Conn) Drain() (int, error) { var errCode C.int ret := C.pa_simple_drain(c.native(), &errCode) return int(ret), newError("pa_simple_drain", errCode) } // Close and free func (c Conn) Free() { C.pa_simple_free(c.native()) } func (c Conn) Flush() (int, error) { var errCode C.int ret := C.pa_simple_flush(c.native(), &errCode) return int(ret), newError("pa_simple_flush", errCode) } type Error struct { Code int Fn string } func newError(fn string, errCode C.int) error { if errCode != 0 /*PA_OK*/ { return Error{ Code: int(errCode), Fn: fn, } } return nil } func (err Error) Error() string { errMsg := C.GoString(C.pa_strerror(C.int(err.Code))) return fmt.Sprintf("%s: %s", err.Fn, errMsg) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/sink.go������������������������������������������������������������������������000664 �000000 �000000 �00000004170 13753517240 015456� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" type Sink struct { Index uint32 Name string Description string //sample_spec ChannelMap ChannelMap OwnerModule uint32 Volume CVolume Mute bool MonitorSource uint32 MonitorSourceName string //latency pa_usec_t Driver string Flags int PropList map[string]string //configured_latency pa_usec_t BaseVolume Volume //state pa_sink_state_t NVolumeSteps uint32 Card uint32 Ports []PortInfo ActivePort PortInfo //n_formats //formats } func toSinkInfo(info *C.pa_sink_info) *Sink { s := &Sink{} s.Index = uint32(info.index) s.Name = C.GoString(info.name) s.Description = C.GoString(info.description) //sample_spec s.ChannelMap = ChannelMap{info.channel_map} s.OwnerModule = uint32(info.owner_module) s.Volume = CVolume{info.volume} s.Mute = toBool(info.mute) s.MonitorSource = uint32(info.monitor_source) s.MonitorSourceName = C.GoString(info.monitor_source_name) //latency s.Flags = int(info.flags) s.Driver = C.GoString(info.driver) s.PropList = toProplist(info.proplist) //configured_latency s.BaseVolume = Volume{info.base_volume} //state s.NVolumeSteps = uint32(info.n_volume_steps) s.Card = uint32(info.card) s.Ports = toPorts(uint32(info.n_ports), info.ports) s.ActivePort = toPort(info.active_port) //n_formats //formats return s } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/sink_input.go������������������������������������������������������������������000664 �000000 �000000 �00000003475 13753517240 016704� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" type SinkInput struct { Index uint32 Name string OwnerModule uint32 Client uint32 Sink uint32 //sample_spec ChannelMap ChannelMap Volume CVolume //buffer usec //sink usec ResampleMethod string Driver string Mute bool PropList map[string]string Corked int HasVolume bool VolumeWritable bool //format } func toSinkInputInfo(info *C.pa_sink_input_info) *SinkInput { s := &SinkInput{} s.Index = uint32(info.index) s.Name = C.GoString(info.name) s.OwnerModule = uint32(info.owner_module) s.Client = uint32(info.client) s.Sink = uint32(info.sink) //sample_spec s.ChannelMap = ChannelMap{info.channel_map} s.Volume = CVolume{info.volume} //buffer usec //sink usec s.ResampleMethod = C.GoString(info.resample_method) s.Driver = C.GoString(info.driver) s.Mute = toBool(info.mute) s.PropList = toProplist(info.proplist) s.Corked = int(info.corked) s.HasVolume = toBool(info.has_volume) s.VolumeWritable = toBool(info.volume_writable) //format return s } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/source.go����������������������������������������������������������������������000664 �000000 �000000 �00000004157 13753517240 016017� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" type Source struct { Index uint32 Name string Description string //sample_spec ChannelMap ChannelMap OwnerModule uint32 Volume CVolume Mute bool MonitorOfSink uint32 MonitorOfSinkName string //latency pa_usec_t Driver string Flags int Proplist map[string]string BaseVolume Volume //state NVolumeSteps uint32 Card uint32 Ports []PortInfo ActivePort PortInfo //n_formats //formats } func toSourceInfo(info *C.pa_source_info) *Source { s := &Source{} s.Index = uint32(info.index) s.Name = C.GoString(info.name) s.Description = C.GoString(info.description) s.ChannelMap = ChannelMap{info.channel_map} //sample_spec s.OwnerModule = uint32(info.owner_module) s.Volume = CVolume{info.volume} s.Mute = toBool(info.mute) s.MonitorOfSink = uint32(info.monitor_of_sink) s.MonitorOfSinkName = C.GoString(info.monitor_of_sink_name) //latency pa_usec_t s.Driver = C.GoString(info.driver) //flags pa_source_flags_t s.Flags = int(info.flags) s.Proplist = toProplist(info.proplist) s.BaseVolume = Volume{info.base_volume} //state s.NVolumeSteps = uint32(info.n_volume_steps) s.Card = uint32(info.card) s.Ports = toSourcePorts(uint32(info.n_ports), info.ports) s.ActivePort = toSourcePort(info.active_port) //n_formats //formats return s } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/source_output.go���������������������������������������������������������������000664 �000000 �000000 �00000001627 13753517240 017436� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" */ import "C" type SourceOutput struct{} func toSourceOutputInfo(info *C.pa_source_output_info) *SourceOutput { return nil } ���������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/sync.go������������������������������������������������������������������������000664 �000000 �000000 �00000005266 13753517240 015475� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse import "unsafe" import "sync" /* #include "dde-pulse.h" #cgo pkg-config: libpulse */ import "C" type paInfo struct { data interface{} Type int } func NewPaInfo(data unsafe.Pointer, Type int) *paInfo { if data == nil { return nil } info := &paInfo{Type: Type} switch Type { case C.PA_SUBSCRIPTION_EVENT_SINK: info.data = toSinkInfo((*C.pa_sink_info)(data)) case C.PA_SUBSCRIPTION_EVENT_SINK_INPUT: info.data = toSinkInputInfo((*C.pa_sink_input_info)(data)) case C.PA_SUBSCRIPTION_EVENT_SOURCE: info.data = toSourceInfo((*C.pa_source_info)(data)) case C.PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: info.data = toSourceOutputInfo((*C.pa_source_output_info)(data)) case C.PA_SUBSCRIPTION_EVENT_SERVER: info.data = toServerInfo((*C.pa_server_info)(data)) case C.PA_SUBSCRIPTION_EVENT_CARD: info.data = toCardInfo((*C.pa_card_info)(data)) default: // current didn't support this type return nil } return info } type cookie struct { id int64 data chan *paInfo } func (c *cookie) Reply() *paInfo { defer deleteCookie(c.id) return <-c.data } func (c *cookie) ReplyList() []*paInfo { defer deleteCookie(c.id) var infos []*paInfo for info := range c.data { infos = append(infos, info) } return infos } func (c *cookie) Feed(paInfo *paInfo) { if paInfo == nil { return } c.data <- paInfo } func (c *cookie) EndOfList() { close(c.data) deleteCookie(c.id) } func (c *cookie) Failed() { close(c.data) deleteCookie(c.id) } var newCookie, fetchCookie, deleteCookie = func() (func() *cookie, func(int64) *cookie, func(int64)) { cookies := make(map[int64]*cookie) id := int64(0) var locker sync.Mutex return func() *cookie { locker.Lock() id++ c := &cookie{int64(id), make(chan *paInfo)} cookies[c.id] = c locker.Unlock() return c }, func(i int64) *cookie { locker.Lock() c := cookies[i] locker.Unlock() return c }, func(i int64) { locker.Lock() delete(cookies, i) locker.Unlock() } }() ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/thread_test.go�����������������������������������������������������������������000664 �000000 �000000 �00000002106 13753517240 017015� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse import ( "math/rand" "testing" ) func BenchmarkTheadSafe(b *testing.B) { ctx := GetContext() sinks := ctx.GetSinkList() for _, s := range sinks { old := s.Volume for i := 0; i < b.N; i++ { v := s.Volume.SetAvg(rand.Float64()) ctx.SetSinkVolumeByIndex(s.Index, v) } ctx.SetSinkVolumeByIndex(s.Index, old) } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/pulse/wrap.go������������������������������������������������������������������������000664 �000000 �000000 �00000007363 13753517240 015472� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package pulse /* #include "dde-pulse.h" #cgo pkg-config: libpulse */ import "C" import "unsafe" func (info *paInfo) ToServer() *Server { switch r := info.data.(type) { case *Server: return r } return nil } func (info *paInfo) ToCard() *Card { switch r := info.data.(type) { case *Card: return r } return nil } func (info *paInfo) ToSink() *Sink { switch r := info.data.(type) { case *Sink: return r } return nil } func (info *paInfo) ToSinkInput() *SinkInput { switch r := info.data.(type) { case *SinkInput: return r } return nil } func (info *paInfo) ToSource() *Source { switch r := info.data.(type) { case *Source: return r } return nil } func (info *paInfo) ToSourceOutput() *SourceOutput { switch r := info.data.(type) { case *SourceOutput: return r } return nil } func toProfiles(n uint32, c **C.pa_card_profile_info2) (r ProfileInfos2) { if n > 0 { pp := (*[1 << 10](*C.pa_card_profile_info2))(unsafe.Pointer(c))[:n:n] for _, p := range pp { r = append(r, toProfile(p)) } } return } func toProfile(c *C.pa_card_profile_info2) ProfileInfo2 { if nil == c { return ProfileInfo2{} } return ProfileInfo2{ Name: C.GoString(c.name), Description: C.GoString(c.description), Priority: uint32(c.priority), NSinks: uint32(c.n_sinks), NSources: uint32(c.n_sources), Available: int(c.available), } } func toPorts(n uint32, c **C.pa_sink_port_info) (r []PortInfo) { if n > 0 { pp := (*[1 << 10](*C.pa_sink_port_info))(unsafe.Pointer(c))[:n:n] for _, p := range pp { r = append(r, toPort(p)) } } return } func toPort(c *C.pa_sink_port_info) PortInfo { if c == nil { return PortInfo{} } return PortInfo{ Name: C.GoString(c.name), Description: C.GoString(c.description), Priority: uint32(c.priority), Available: int(c.available), } } func toCardPorts(n uint32, c **C.pa_card_port_info) (r CardPortInfos) { if n > 0 { pp := (*[1 << 10](*C.pa_card_port_info))(unsafe.Pointer(c))[:n:n] for _, p := range pp { r = append(r, toCardPort(p)) } } return } func toCardPort(c *C.pa_card_port_info) CardPortInfo { if c == nil { return CardPortInfo{} } return CardPortInfo{ PortInfo: PortInfo{ Name: C.GoString(c.name), Description: C.GoString(c.description), Priority: uint32(c.priority), Available: int(c.available), }, Direction: int(c.direction), Profiles: toProfiles(uint32(c.n_profiles), c.profiles2), } } func toSourcePorts(n uint32, c **C.pa_source_port_info) (r []PortInfo) { if n > 0 { pp := (*[1 << 10](*C.pa_source_port_info))(unsafe.Pointer(c))[:n:n] for _, p := range pp { r = append(r, toSourcePort(p)) } } return } func toSourcePort(c *C.pa_source_port_info) PortInfo { if c == nil { return PortInfo{} } return PortInfo{ Name: C.GoString(c.name), Description: C.GoString(c.description), Priority: uint32(c.priority), Available: int(c.available), } } type SampleFormat int32 type SampleSpec struct { Format SampleFormat Rate uint32 Channels uint8 } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/shell/�������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014140� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/shell/shell.go�����������������������������������������������������������������������000664 �000000 �000000 �00000001137 13753517240 015600� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package shell import ( "bytes" "strings" ) const specialChars = "`~!#$&*()|\\;'\"<>? " func isSpecialChar(c byte) bool { return strings.IndexByte(specialChars, c) >= 0 } // Encode returns a sh string literal representing s func Encode(s string) string { var buf bytes.Buffer for i := 0; i < len(s); i++ { c := s[i] if isSpecialChar(c) { buf.WriteByte('\\') buf.WriteByte(c) } else if c == '\t' { buf.WriteString(`'\t'`) } else if c == '\r' { buf.WriteString(`'\r'`) } else if c == '\n' { buf.WriteString(`'\n'`) } else { buf.WriteByte(c) } } return buf.String() } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/shell/shell_test.go������������������������������������������������������������������000664 �000000 �000000 �00000001006 13753517240 016632� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package shell import ( "os/exec" "testing" ) func TestEncode(t *testing.T) { _, err := exec.LookPath("sh") if err != nil { t.Skip("not found sh") } for _, s := range []string{ "hello world", "hello$world", "hello\t\r\nworld", "中文 english", "`~!#$&*()|\\;'\"<>? ", } { r := Encode(s) t.Log(r) cmd := exec.Command("sh", "-c", "echo -n "+r) output, err := cmd.Output() if err != nil { t.Fatal(err) } if s != string(output) { t.Errorf("%q != %q", s, string(output)) } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound/�������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014161� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound/player.c�����������������������������������������������������������������������000664 �000000 �000000 �00000006430 13753517240 015624� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include <glib.h> #include <locale.h> #include <stdio.h> #include <string.h> #include "player.h" #define DEFAULT_DRIVER "pulse" static ca_context* connect_canberra_context(char* device, char* driver); static uint32_t id = 0; int canberra_play_system_sound(char *theme, char *event_id, char *device, char* driver) { int curid = ++id; setlocale(LC_ALL, ""); ca_context *ca = connect_canberra_context(device, driver); if (ca == NULL) { return -1; } int playret = ca_context_play(ca, curid, CA_PROP_CANBERRA_XDG_THEME_NAME, theme, CA_PROP_EVENT_ID, event_id, NULL); if (playret != CA_SUCCESS) { g_warning("play: id=%d %s\n", curid, ca_strerror(playret)); ca_context_destroy(ca); return playret; } // wait for end int playing; do { g_usleep(500 * 1000); // sleep 0.5s int ret = ca_context_playing(ca, curid, &playing); if (ret != CA_SUCCESS) { g_warning("ca_context_playing id=%d %s\n", curid, ca_strerror(ret)); } } while (playing > 0); ca_context_destroy(ca); return playret; } int canberra_play_sound_file(char *file, char *device, char* driver) { int curid = ++id; setlocale(LC_ALL, ""); ca_context *ca = connect_canberra_context(device, driver); if (ca == NULL) { return -1; } int playret = ca_context_play(ca, curid, CA_PROP_MEDIA_FILENAME, file, NULL); if (playret != CA_SUCCESS) { g_warning("play_sound_file filename:%s id=%d %s\n", file, curid, ca_strerror(playret)); ca_context_destroy(ca); return playret; } // wait for end int playing; do { g_usleep(500 * 1000); // sleep 0.5s int ret = ca_context_playing(ca, curid, &playing); if (ret != CA_SUCCESS) { g_warning("ca_context_playing id=%d %s\n", curid, ca_strerror(ret)); } } while (playing > 0); ca_context_destroy(ca); return playret; } static ca_context* connect_canberra_context(char* device, char* driver) { ca_context* ca = NULL; if (ca_context_create(&ca) != 0) { g_warning("Create canberra context failed"); return NULL; } // set backend driver if (strlen(driver) > 0) { if (ca_context_set_driver(ca, driver) != 0 ) { g_warning("Set '%s' as backend driver failed", driver); ca_context_destroy(ca); return NULL; } } if (strlen(device) > 0) { if (ca_context_change_device(ca, device) != 0) { g_warning("Set '%s' as backend device failed", device); ca_context_destroy(ca); return NULL; } } if (ca_context_open(ca) != 0) { g_warning("Connect the context to sound system failed"); ca_context_destroy(ca); return NULL; } return ca; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound/player.go����������������������������������������������������������������������000664 �000000 �000000 �00000006152 13753517240 016010� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package sound // #cgo pkg-config: glib-2.0 libcanberra // #include <stdlib.h> // #include "player.h" import "C" import ( "fmt" "os/exec" "unsafe" ) const ( PlayerLibcanberra = "libcanberra" PlayerMPV = "mpv" PlayerPaplay = "paplay" ) // PlayThemeSound: play sound theme event // @theme : the special sound theme // @event : the special theme event id // @device: the special backend card, default: the current sound card // @driver: the special backend driver, as: 'pulse','alsa','null' ... // default: 'pulse' // @player: the special sound play method, as: 'libcanberra','mpv','paplay' // if empty or other value, just as 'libcanberra' // // return: the error message func PlayThemeSound(theme, event, device, driver, player string) error { switch player { case PlayerPaplay, PlayerMPV: file, err := findThemeFile(theme, event) if err != nil { return err } _, err = exec.Command(player, []string{file}...).Output() return err } cTheme := C.CString(theme) defer C.free(unsafe.Pointer(cTheme)) cEvent := C.CString(event) defer C.free(unsafe.Pointer(cEvent)) cDevice := C.CString(device) defer C.free(unsafe.Pointer(cDevice)) cDriver := C.CString(driver) defer C.free(unsafe.Pointer(cDriver)) ret := C.canberra_play_system_sound(cTheme, cEvent, cDevice, cDriver) if ret != 0 { msg := C.GoString(C.ca_strerror(ret)) return fmt.Errorf("Play failed: %s", msg) } return nil } // PlaySoundFile: play sound file // @file : the file which needed to play // @device: the special backend card, default: the current sound card // @driver: the special backend driver, as: 'pulse','alsa','null' ... // default: 'pulse' // @player: the special sound play method, as: 'libcanberra','mpv','paplay' // if empty or other value, just as 'libcanberra' // // return: the error message func PlaySoundFile(file, device, driver, player string) error { switch player { case PlayerPaplay, PlayerMPV: _, err := exec.Command(player, []string{file}...).Output() return err } cFile := C.CString(file) defer C.free(unsafe.Pointer(cFile)) cDevice := C.CString(device) defer C.free(unsafe.Pointer(cDevice)) cDriver := C.CString(driver) defer C.free(unsafe.Pointer(cDriver)) ret := C.canberra_play_sound_file(cFile, cDevice, cDriver) if ret != 0 { msg := C.GoString(C.ca_strerror(ret)) return fmt.Errorf("Play failed: %s", msg) } return nil } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound/player.h�����������������������������������������������������������������������000664 �000000 �000000 �00000001737 13753517240 015636� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef __PLAYER_H__ #define __PLAYER_H__ #include <canberra.h> int canberra_play_system_sound(char *theme, char *event_id, char *device, char* driver); int canberra_play_sound_file(char *file, char *device, char* driver); #endif ���������������������������������go-lib-5.6.0.9/sound/utils.go�����������������������������������������������������������������������000664 �000000 �000000 �00000002670 13753517240 015655� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package sound import ( "fmt" "os" "path" "pkg.deepin.io/lib/utils" ) var ( errInvalidEvent = fmt.Errorf("invalid theme event") ) func findThemeFile(theme, event string) (string, error) { var home = os.Getenv("HOME") var themeDirs = []string{ path.Join(home, ".local/share/sounds"), "/usr/local/share/sounds", "/usr/share/sounds", } for _, dir := range themeDirs { // TODO: fix non ogg/oga event // TODO: handle sound theme 'index.theme' file := path.Join(dir, theme, "stereo", event+".ogg") if utils.IsFileExist(file) { return file, nil } file = path.Join(dir, theme, "stereo", event+".oga") if utils.IsFileExist(file) { return file, nil } } return "", errInvalidEvent } ������������������������������������������������������������������������go-lib-5.6.0.9/sound_effect/������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015475� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound_effect/alsa_backend.go���������������������������������������������������������000664 �000000 �000000 �00000004206 13753517240 020415� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package sound_effect import ( "unsafe" "pkg.deepin.io/lib/asound" ) type ALSAPlayBackend struct { pcm asound.PCM frameSize int } func newALSAPlayBackend(device string, sampleSpec *SampleSpec) (pb PlayBackend, err error) { if device == "" { device = "default" } pcm, err := asound.OpenPCM(device, asound.PCMStreamPlayback, 0) if err != nil { return } defer func() { if err != nil { //println("call pcm.Close()") pcm.Close() } }() params, err := asound.NewPCMHwParams() if err != nil { return nil, err } defer params.Free() // fill it in with default values pcm.HwParamsAny(params) channels := sampleSpec.channels format := sampleSpec.pcmFormat err = pcm.HwParamsSetAccess(params, asound.PCMAccessRWInterleaved) if err != nil { return } err = pcm.HwParamsSetFormat(params, format) if err != nil { return } err = pcm.HwParamsSetChannels(params, uint(channels)) if err != nil { return } sampleRate := uint(sampleSpec.rate) _, err = pcm.HwParamsSetRateNear(params, &sampleRate) if err != nil { return } bufferTime, _, err := params.GetBufferTimeMax() if err != nil { return } if bufferTime > 500000 { bufferTime = 500000 } periodTime := uint(0) if bufferTime > 0 { periodTime = bufferTime / 4 } // set period time if periodTime > 0 { _, err = pcm.HwParamsSetPeriodTimeNear(params, &periodTime) if err != nil { return } } // set buffer time if bufferTime > 0 { _, err = pcm.HwParamsSetBufferTimeNear(params, &bufferTime) if err != nil { return } } err = pcm.HwParams(params) if err != nil { return } err = pcm.Prepare() if err != nil { return } frameSize := channels * sampleSpec.pcmFormat.Size(1) return &ALSAPlayBackend{ pcm: pcm, frameSize: frameSize, }, nil } func (pb *ALSAPlayBackend) Write(data []byte) error { frames := len(data) / pb.frameSize _, err := pb.pcm.Writei(unsafe.Pointer(&data[0]), asound.PCMUFrames(frames)) if err == asound.ErrUnderrun { return pb.pcm.Prepare() } return err } func (pb *ALSAPlayBackend) Drain() error { return pb.pcm.Drain() } func (pb *ALSAPlayBackend) Close() error { return pb.pcm.Close() } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound_effect/ogg.go������������������������������������������������������������������000664 �000000 �000000 �00000002506 13753517240 016603� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package sound_effect import ( "io" "time" "pkg.deepin.io/lib/asound" paSimple "pkg.deepin.io/lib/pulse/simple" "pkg.deepin.io/lib/stb_vorbis" ) func newOggDecoder(file string) (Decoder, error) { decoder, err := stb_vorbis.OpenFile(file) if err != nil { return nil, err } info := decoder.GetInfo() channels := info.Channels sampleRate := info.SampleRate sampleSpec := &SampleSpec{ channels: channels, rate: int(sampleRate), paFormat: paSimple.SampleFormatS16LE, pcmFormat: asound.PCMFormatS16LE, } bufSize := int(sampleRate) / 8 * channels * 2 return &OggDecoder{ core: decoder, sampleSpec: sampleSpec, bufSize: bufSize, }, nil } type OggDecoder struct { core stb_vorbis.Decoder sampleSpec *SampleSpec bufSize int } func (d *OggDecoder) GetDuration() time.Duration { // TODO return 0 } func (d *OggDecoder) Decode() ([]byte, error) { channels := d.sampleSpec.channels buf := make([]byte, d.bufSize) samples := d.core.GetSamplesShortInterleaved(channels, buf) if samples <= 0 { err := d.core.GetError() if err != nil { return nil, err } return nil, io.EOF } bytes := uint(2 * samples * channels) return buf[:bytes], nil } func (d *OggDecoder) GetSampleSpec() *SampleSpec { return d.sampleSpec } func (d *OggDecoder) Close() error { d.core.Close() return nil } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound_effect/player.go���������������������������������������������������������������000664 �000000 �000000 �00000012511 13753517240 017320� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package sound_effect import ( "errors" "fmt" "io" "os" "path/filepath" "sync" "time" "pkg.deepin.io/lib/asound" paSimple "pkg.deepin.io/lib/pulse/simple" "pkg.deepin.io/lib/sound_effect/theme" ) type Player struct { finder *theme.Finder cache map[string]*CacheItem cacheMu sync.Mutex UseCache bool backendType PlayBackendType } type CacheItem struct { modTime time.Time event string sampleSpec *SampleSpec data [][]byte } type Decoder interface { GetSampleSpec() *SampleSpec Decode() ([]byte, error) Close() error GetDuration() time.Duration } type SampleSpec struct { channels int rate int paFormat paSimple.SampleFormat pcmFormat asound.PCMFormat } func (ss *SampleSpec) GetPaSampleSpec() *paSimple.SampleSpec { return &paSimple.SampleSpec{ Channels: uint8(ss.channels), Rate: uint32(ss.rate), Format: ss.paFormat, } } func NewPlayer(useCache bool, backendType PlayBackendType) *Player { player := &Player{ finder: theme.NewFinder(), UseCache: useCache, backendType: backendType, } if useCache { player.cache = make(map[string]*CacheItem) } return player } func (player *Player) Finder() *theme.Finder { return player.finder } func (player *Player) GetDuration(theme, event string) (time.Duration, error) { filename := player.finder.Find(theme, "stereo", event) if filename == "" { return 0, errors.New("not found file") } return player.getDuration(filename) } func (player *Player) Play(theme, event, device string) error { filename := player.finder.Find(theme, "stereo", event) if filename == "" { return errors.New("not found file") } return player.play(filename, event, device) } func cacheItemOk(cacheItem *CacheItem, fileInfo os.FileInfo) bool { return cacheItem.modTime == fileInfo.ModTime() } func getDecoder(file string, fileInfo os.FileInfo) (Decoder, error) { ext := filepath.Ext(file) switch ext { case ".ogg", ".oga": return newOggDecoder(file) case ".wav": return newWavDecoder(file, fileInfo) default: return nil, fmt.Errorf("unsupported ext %q", ext) } } type PlayBackendType uint const ( PlayBackendPulseAudio = iota PlayBackendALSA ) type PlayBackend interface { Write(data []byte) error Drain() error Close() error } func getPlayBackend(type0 PlayBackendType, event, device string, sampleSpec *SampleSpec) (PlayBackend, error) { switch type0 { case PlayBackendPulseAudio: return newPulseAudioPlayBackend(event, device, sampleSpec) case PlayBackendALSA: return newALSAPlayBackend(device, sampleSpec) default: return nil, fmt.Errorf("unknown play backend type %d", type0) } } func (Player *Player) getDuration(file string) (time.Duration, error) { fileInfo, err := os.Stat(file) if err != nil { return 0, err } decoder, err := getDecoder(file, fileInfo) if err != nil { return 0, err } defer decoder.Close() return decoder.GetDuration(), nil } func (player *Player) play(file, event, device string) error { fileInfo, err := os.Stat(file) if err != nil { return err } var doCache = player.UseCache if fileInfo.Size() > 30*1024 { doCache = false } if doCache { player.cacheMu.Lock() cacheItem, ok := player.cache[file] player.cacheMu.Unlock() if ok { cacheOk := cacheItemOk(cacheItem, fileInfo) if cacheOk { return player.playCacheItem(cacheItem, device) } else { player.cacheMu.Lock() delete(player.cache, file) player.cacheMu.Unlock() } } } decoder, err := getDecoder(file, fileInfo) if err != nil { return err } defer decoder.Close() sampleSpec := decoder.GetSampleSpec() backend, err := getPlayBackend(player.backendType, event, device, sampleSpec) if err != nil { return err } defer backend.Close() var cacheData [][]byte for { data, err := decoder.Decode() if len(data) > 0 { if doCache { cacheData = append(cacheData, data) } err := backend.Write(data) if err != nil { return err } } if err == io.EOF { break } else if err != nil { return err } } if doCache { cacheItem := &CacheItem{ event: event, modTime: fileInfo.ModTime(), sampleSpec: sampleSpec, data: cacheData, } player.cacheMu.Lock() player.cache[file] = cacheItem player.cacheMu.Unlock() } return backend.Drain() } func (player *Player) playCacheItem(cacheItem *CacheItem, device string) error { backend, err := getPlayBackend(player.backendType, cacheItem.event, device, cacheItem.sampleSpec) if err != nil { return err } defer backend.Close() for _, data := range cacheItem.data { err := backend.Write(data) if err != nil { return err } } return backend.Drain() } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound_effect/pulse_backend.go��������������������������������������������������������000664 �000000 �000000 �00000001442 13753517240 020624� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package sound_effect import ( "unsafe" paSimple "pkg.deepin.io/lib/pulse/simple" ) type PulseAudioPlayBackend struct { conn paSimple.Conn } func newPulseAudioPlayBackend(event, device string, sampleSpec *SampleSpec) (PlayBackend, error) { paConn, err := paSimple.NewConn("", "com.deepin.SoundEffect", paSimple.StreamDirectionPlayback, device, event, sampleSpec.GetPaSampleSpec()) if err != nil { return nil, err } return &PulseAudioPlayBackend{ conn: paConn, }, nil } func (pb *PulseAudioPlayBackend) Write(data []byte) error { _, err := pb.conn.Write(unsafe.Pointer(&data[0]), uint(len(data))) return err } func (pb *PulseAudioPlayBackend) Drain() error { _, err := pb.conn.Drain() return err } func (pb *PulseAudioPlayBackend) Close() error { pb.conn.Free() return nil } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound_effect/theme/������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 016577� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound_effect/theme/theme.go����������������������������������������������������������000664 �000000 �000000 �00000011141 13753517240 020226� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package theme import ( "errors" "io/ioutil" "os" "path/filepath" "pkg.deepin.io/lib/keyfile" "pkg.deepin.io/lib/strv" "pkg.deepin.io/lib/xdg/basedir" "strings" "sync" ) type Theme struct { InternalName string Path string Inherits []string Directories []string SubDirs []SubDir //Name string //Comment string //Hidden bool //Example string } type SubDir struct { Name string OutputProfile string //Context string } type Finder struct { dataDirs []string loadedThemes map[string]*Theme mu sync.Mutex } func NewFinder() *Finder { const soundsDir = "sounds" dataDirs := strv.Strv{filepath.Join(basedir.GetUserDataDir(), soundsDir)} for _, dir := range basedir.GetSystemDataDirs() { dataDirs, _ = dataDirs.Add(filepath.Join(dir, soundsDir)) } return &Finder{ dataDirs: dataDirs, } } func (finder *Finder) GetTheme(name string) (*Theme, error) { finder.mu.Lock() defer finder.mu.Unlock() if theme, ok := finder.loadedThemes[name]; ok { return theme, nil } for _, dataDir := range finder.dataDirs { fileInfos, err := ioutil.ReadDir(dataDir) if err != nil { continue } for _, fileInfo := range fileInfos { if !fileInfo.IsDir() { continue } if fileInfo.Name() != name { continue } // ex. /usr/share/sounds/ freedesktop index.theme theme, err := LoadTheme(filepath.Join(dataDir, fileInfo.Name(), "index.theme")) if err != nil { continue } // save theme in cache if finder.loadedThemes == nil { finder.loadedThemes = make(map[string]*Theme) } finder.loadedThemes[theme.InternalName] = theme return theme, nil } } return nil, errors.New("not found theme " + name) } func LoadTheme(filename string) (*Theme, error) { kf := keyfile.NewKeyFile() kf.ListSeparator = ',' err := kf.LoadFromFile(filename) if err != nil { return nil, err } const mainSection = "Sound Theme" _, err = kf.GetSection(mainSection) if err != nil { return nil, err } inherits, _ := kf.GetStringList(mainSection, "Inherits") directories, _ := kf.GetStringList(mainSection, "Directories") var subDirs []SubDir for _, section := range directories { outputProfile, _ := kf.GetString(section, "OutputProfile") if outputProfile != "" { subDirs = append(subDirs, SubDir{ OutputProfile: outputProfile, Name: section, }) } } path := filepath.Dir(filename) t := &Theme{ Path: path, InternalName: filepath.Base(path), Inherits: inherits, Directories: directories, SubDirs: subDirs, } return t, nil } func isNameOk(name string) bool { if strings.ContainsRune(name, '/') || name == "" || name == "." || name == ".." { return false } return true } func (finder *Finder) Find(reqTheme, reqOutputProfile, reqName string) string { if !(isNameOk(reqTheme) && isNameOk(reqName)) { return "" } filename := finder.find(reqTheme, reqOutputProfile, reqName) if filename != "" { return filename } const fallbackTheme = "freedesktop" if reqTheme != fallbackTheme { // fallback filename = finder.find(fallbackTheme, reqOutputProfile, reqName) if filename != "" { return filename } } return "" } func (finder *Finder) find(reqTheme, reqOutputProfile, reqName string) string { theme, err := finder.GetTheme(reqTheme) if err != nil { return "" } filename := finder.lookup(theme, reqOutputProfile, reqName) if filename != "" { return filename } // recursively find from parents for _, parent := range theme.Inherits { parentTheme, err := finder.GetTheme(parent) if err != nil { continue } filename = finder.find(parentTheme.InternalName, reqOutputProfile, reqName) if filename != "" { return filename } } return "" } func (finder *Finder) lookup(theme *Theme, reqOutputProfile, reqName string) string { profiles := strv.Strv{reqOutputProfile} profiles, _ = profiles.Add("stereo") for _, profile := range profiles { for _, subDir := range theme.SubDirs { if subDir.OutputProfile == profile { for _, directory := range finder.dataDirs { for _, name := range getNames(reqName, nil) { for _, ext := range []string{"oga", "ogg", "wav"} { filename := filepath.Join(directory, theme.InternalName, subDir.Name, name+"."+ext) statInfo, err := os.Stat(filename) if err != nil { continue } if statInfo.IsDir() { continue } return filename } } } } } } return "" } func getNames(name string, acc []string) []string { idx := strings.LastIndex(name, "-") if idx < 0 { return append(acc, name) } else { return getNames(name[:idx], append(acc, name)) } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/sound_effect/wav.go������������������������������������������������������������������000664 �000000 �000000 �00000004424 13753517240 016625� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package sound_effect import ( "errors" "os" "time" "github.com/cryptix/wav" "pkg.deepin.io/lib/asound" paSimple "pkg.deepin.io/lib/pulse/simple" ) type WavDecoder struct { reader *wav.Reader f *os.File sampleSpec *SampleSpec bufSize int bytesPerFrame int duration time.Duration } func newWavDecoder(filename string, fileInfo os.FileInfo) (Decoder, error) { f, err := os.Open(filename) if err != nil { return nil, err } wavReader, err := wav.NewReader(f, fileInfo.Size()) if err != nil { return nil, err } wavFile := wavReader.GetFile() paFormat, pcmFormat, err := getWavFormat(wavFile) if err != nil { return nil, err } sampleSpec := &SampleSpec{ paFormat: paFormat, pcmFormat: pcmFormat, rate: int(wavFile.SampleRate), channels: int(wavFile.Channels), } bytesPerFrame := int(wavFile.Channels) * int(wavFile.SignificantBits/8) bufSize := int(wavFile.SampleRate/8) * bytesPerFrame // NOTE: do not use wavFile.Duration duration := time.Duration( float64(wavReader.GetSampleCount()/uint32(wavFile.Channels)) / float64(wavFile.SampleRate) * float64(time.Second), ) return &WavDecoder{ f: f, reader: wavReader, sampleSpec: sampleSpec, bufSize: bufSize, bytesPerFrame: bytesPerFrame, duration: duration, }, nil } func getWavFormat(wavFile wav.File) (paSimple.SampleFormat, asound.PCMFormat, error) { switch wavFile.SignificantBits { case 8: return paSimple.SampleFormatU8, asound.PCMFormatU8, nil case 16: return paSimple.SampleFormatS16LE, asound.PCMFormatS16LE, nil case 32: return paSimple.SampleFormatS32LE, asound.PCMFormatS32LE, nil default: return 0, 0, errors.New("unsupported format") } } func (d *WavDecoder) GetSampleSpec() *SampleSpec { return d.sampleSpec } func (d *WavDecoder) Decode() ([]byte, error) { buf := make([]byte, d.bufSize) n, err := d.read(buf) return buf[:n], err } func (d *WavDecoder) GetDuration() time.Duration { return d.duration } func (d *WavDecoder) read(buf []byte) (int, error) { var n int for n < len(buf) { sample, err := d.reader.ReadRawSample() if err != nil { return n - (n % d.bytesPerFrame), err } n += copy(buf[n:], sample) } return n, nil } func (d *WavDecoder) Close() error { return d.f.Close() } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/stb_vorbis/��������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015205� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/stb_vorbis/stb_vorbis.c��������������������������������������������������������������000664 �000000 �000000 �00000520657 13753517240 017544� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Ogg Vorbis audio decoder - v1.11 - public domain // http://nothings.org/stb_vorbis/ // // Original version written by Sean Barrett in 2007. // // Originally sponsored by RAD Game Tools. Seeking sponsored // by Phillip Bennefall, Marc Andersen, Aaron Baker, Elias Software, // Aras Pranckevicius, and Sean Barrett. // // LICENSE // // See end of file for license information. // // Limitations: // // - floor 0 not supported (used in old ogg vorbis files pre-2004) // - lossless sample-truncation at beginning ignored // - cannot concatenate multiple vorbis streams // - sample positions are 32-bit, limiting seekable 192Khz // files to around 6 hours (Ogg supports 64-bit) // // Feature contributors: // Dougall Johnson (sample-exact seeking) // // Bugfix/warning contributors: // Terje Mathisen Niklas Frykholm Andy Hill // Casey Muratori John Bolton Gargaj // Laurent Gomila Marc LeBlanc Ronny Chevalier // Bernhard Wodo Evan Balster alxprd@github // Tom Beaumont Ingo Leitgeb Nicolas Guillemot // Phillip Bennefall Rohit Thiago Goulart // manxorist@github saga musix github:infatum // // Partial history: // 1.11 - 2017/07/23 - fix MinGW compilation // 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory // 1.09 - 2016/04/04 - back out 'truncation of last frame' fix from previous version // 1.08 - 2016/04/02 - warnings; setup memory leaks; truncation of last frame // 1.07 - 2015/01/16 - fixes for crashes on invalid files; warning fixes; const // 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson) // some crash fixes when out of memory or with corrupt files // fix some inappropriately signed shifts // 1.05 - 2015/04/19 - don't define __forceinline if it's redundant // 1.04 - 2014/08/27 - fix missing const-correct case in API // 1.03 - 2014/08/07 - warning fixes // 1.02 - 2014/07/09 - declare qsort comparison as explicitly _cdecl in Windows // 1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float (interleaved was correct) // 1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in >2-channel; // (API change) report sample rate for decode-full-file funcs // // See end of file for full version history. ////////////////////////////////////////////////////////////////////////////// // // HEADER BEGINS HERE // #include "stb_vorbis.h" // // HEADER ENDS HERE // ////////////////////////////////////////////////////////////////////////////// #ifndef STB_VORBIS_HEADER_ONLY // global configuration settings (e.g. set these in the project/makefile), // or just set them in this file at the top (although ideally the first few // should be visible when the header file is compiled too, although it's not // crucial) // STB_VORBIS_NO_PUSHDATA_API // does not compile the code for the various stb_vorbis_*_pushdata() // functions // #define STB_VORBIS_NO_PUSHDATA_API // STB_VORBIS_NO_PULLDATA_API // does not compile the code for the non-pushdata APIs // #define STB_VORBIS_NO_PULLDATA_API // STB_VORBIS_NO_STDIO // does not compile the code for the APIs that use FILE *s internally // or externally (implied by STB_VORBIS_NO_PULLDATA_API) // #define STB_VORBIS_NO_STDIO // STB_VORBIS_NO_INTEGER_CONVERSION // does not compile the code for converting audio sample data from // float to integer (implied by STB_VORBIS_NO_PULLDATA_API) // #define STB_VORBIS_NO_INTEGER_CONVERSION // STB_VORBIS_NO_FAST_SCALED_FLOAT // does not use a fast float-to-int trick to accelerate float-to-int on // most platforms which requires endianness be defined correctly. //#define STB_VORBIS_NO_FAST_SCALED_FLOAT // STB_VORBIS_MAX_CHANNELS [number] // globally define this to the maximum number of channels you need. // The spec does not put a restriction on channels except that // the count is stored in a byte, so 255 is the hard limit. // Reducing this saves about 16 bytes per value, so using 16 saves // (255-16)*16 or around 4KB. Plus anything other memory usage // I forgot to account for. Can probably go as low as 8 (7.1 audio), // 6 (5.1 audio), or 2 (stereo only). #ifndef STB_VORBIS_MAX_CHANNELS #define STB_VORBIS_MAX_CHANNELS 16 // enough for anyone? #endif // STB_VORBIS_PUSHDATA_CRC_COUNT [number] // after a flush_pushdata(), stb_vorbis begins scanning for the // next valid page, without backtracking. when it finds something // that looks like a page, it streams through it and verifies its // CRC32. Should that validation fail, it keeps scanning. But it's // possible that _while_ streaming through to check the CRC32 of // one candidate page, it sees another candidate page. This #define // determines how many "overlapping" candidate pages it can search // at once. Note that "real" pages are typically ~4KB to ~8KB, whereas // garbage pages could be as big as 64KB, but probably average ~16KB. // So don't hose ourselves by scanning an apparent 64KB page and // missing a ton of real ones in the interim; so minimum of 2 #ifndef STB_VORBIS_PUSHDATA_CRC_COUNT #define STB_VORBIS_PUSHDATA_CRC_COUNT 4 #endif // STB_VORBIS_FAST_HUFFMAN_LENGTH [number] // sets the log size of the huffman-acceleration table. Maximum // supported value is 24. with larger numbers, more decodings are O(1), // but the table size is larger so worse cache missing, so you'll have // to probe (and try multiple ogg vorbis files) to find the sweet spot. #ifndef STB_VORBIS_FAST_HUFFMAN_LENGTH #define STB_VORBIS_FAST_HUFFMAN_LENGTH 10 #endif // STB_VORBIS_FAST_BINARY_LENGTH [number] // sets the log size of the binary-search acceleration table. this // is used in similar fashion to the fast-huffman size to set initial // parameters for the binary search // STB_VORBIS_FAST_HUFFMAN_INT // The fast huffman tables are much more efficient if they can be // stored as 16-bit results instead of 32-bit results. This restricts // the codebooks to having only 65535 possible outcomes, though. // (At least, accelerated by the huffman table.) #ifndef STB_VORBIS_FAST_HUFFMAN_INT #define STB_VORBIS_FAST_HUFFMAN_SHORT #endif // STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH // If the 'fast huffman' search doesn't succeed, then stb_vorbis falls // back on binary searching for the correct one. This requires storing // extra tables with the huffman codes in sorted order. Defining this // symbol trades off space for speed by forcing a linear search in the // non-fast case, except for "sparse" codebooks. // #define STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH // STB_VORBIS_DIVIDES_IN_RESIDUE // stb_vorbis precomputes the result of the scalar residue decoding // that would otherwise require a divide per chunk. you can trade off // space for time by defining this symbol. // #define STB_VORBIS_DIVIDES_IN_RESIDUE // STB_VORBIS_DIVIDES_IN_CODEBOOK // vorbis VQ codebooks can be encoded two ways: with every case explicitly // stored, or with all elements being chosen from a small range of values, // and all values possible in all elements. By default, stb_vorbis expands // this latter kind out to look like the former kind for ease of decoding, // because otherwise an integer divide-per-vector-element is required to // unpack the index. If you define STB_VORBIS_DIVIDES_IN_CODEBOOK, you can // trade off storage for speed. //#define STB_VORBIS_DIVIDES_IN_CODEBOOK #ifdef STB_VORBIS_CODEBOOK_SHORTS #error "STB_VORBIS_CODEBOOK_SHORTS is no longer supported as it produced incorrect results for some input formats" #endif // STB_VORBIS_DIVIDE_TABLE // this replaces small integer divides in the floor decode loop with // table lookups. made less than 1% difference, so disabled by default. // STB_VORBIS_NO_INLINE_DECODE // disables the inlining of the scalar codebook fast-huffman decode. // might save a little codespace; useful for debugging // #define STB_VORBIS_NO_INLINE_DECODE // STB_VORBIS_NO_DEFER_FLOOR // Normally we only decode the floor without synthesizing the actual // full curve. We can instead synthesize the curve immediately. This // requires more memory and is very likely slower, so I don't think // you'd ever want to do it except for debugging. // #define STB_VORBIS_NO_DEFER_FLOOR ////////////////////////////////////////////////////////////////////////////// #ifdef STB_VORBIS_NO_PULLDATA_API #define STB_VORBIS_NO_INTEGER_CONVERSION #define STB_VORBIS_NO_STDIO #endif #if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO) #define STB_VORBIS_NO_STDIO 1 #endif #ifndef STB_VORBIS_NO_INTEGER_CONVERSION #ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT // only need endianness for fast-float-to-int, which we don't // use for pushdata #ifndef STB_VORBIS_BIG_ENDIAN #define STB_VORBIS_ENDIAN 0 #else #define STB_VORBIS_ENDIAN 1 #endif #endif #endif #ifndef STB_VORBIS_NO_STDIO #include <stdio.h> #endif #ifndef STB_VORBIS_NO_CRT #include <stdlib.h> #include <string.h> #include <assert.h> #include <math.h> // find definition of alloca if it's not in stdlib.h: #if defined(_MSC_VER) || defined(__MINGW32__) #include <malloc.h> #endif #if defined(__linux__) || defined(__linux) || defined(__EMSCRIPTEN__) #include <alloca.h> #endif #else // STB_VORBIS_NO_CRT #define NULL 0 #define malloc(s) 0 #define free(s) ((void) 0) #define realloc(s) 0 #endif // STB_VORBIS_NO_CRT #include <limits.h> #ifdef __MINGW32__ // eff you mingw: // "fixed": // http://sourceforge.net/p/mingw-w64/mailman/message/32882927/ // "no that broke the build, reverted, who cares about C": // http://sourceforge.net/p/mingw-w64/mailman/message/32890381/ #ifdef __forceinline #undef __forceinline #endif #define __forceinline #define alloca __builtin_alloca #elif !defined(_MSC_VER) #if __GNUC__ #define __forceinline inline #else #define __forceinline #endif #endif #if STB_VORBIS_MAX_CHANNELS > 256 #error "Value of STB_VORBIS_MAX_CHANNELS outside of allowed range" #endif #if STB_VORBIS_FAST_HUFFMAN_LENGTH > 24 #error "Value of STB_VORBIS_FAST_HUFFMAN_LENGTH outside of allowed range" #endif #if 0 #include <crtdbg.h> #define CHECK(f) _CrtIsValidHeapPointer(f->channel_buffers[1]) #else #define CHECK(f) ((void) 0) #endif #define MAX_BLOCKSIZE_LOG 13 // from specification #define MAX_BLOCKSIZE (1 << MAX_BLOCKSIZE_LOG) typedef unsigned char uint8; typedef signed char int8; typedef unsigned short uint16; typedef signed short int16; typedef unsigned int uint32; typedef signed int int32; #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif typedef float codetype; // @NOTE // // Some arrays below are tagged "//varies", which means it's actually // a variable-sized piece of data, but rather than malloc I assume it's // small enough it's better to just allocate it all together with the // main thing // // Most of the variables are specified with the smallest size I could pack // them into. It might give better performance to make them all full-sized // integers. It should be safe to freely rearrange the structures or change // the sizes larger--nothing relies on silently truncating etc., nor the // order of variables. #define FAST_HUFFMAN_TABLE_SIZE (1 << STB_VORBIS_FAST_HUFFMAN_LENGTH) #define FAST_HUFFMAN_TABLE_MASK (FAST_HUFFMAN_TABLE_SIZE - 1) typedef struct { int dimensions, entries; uint8 *codeword_lengths; float minimum_value; float delta_value; uint8 value_bits; uint8 lookup_type; uint8 sequence_p; uint8 sparse; uint32 lookup_values; codetype *multiplicands; uint32 *codewords; #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT int16 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; #else int32 fast_huffman[FAST_HUFFMAN_TABLE_SIZE]; #endif uint32 *sorted_codewords; int *sorted_values; int sorted_entries; } Codebook; typedef struct { uint8 order; uint16 rate; uint16 bark_map_size; uint8 amplitude_bits; uint8 amplitude_offset; uint8 number_of_books; uint8 book_list[16]; // varies } Floor0; typedef struct { uint8 partitions; uint8 partition_class_list[32]; // varies uint8 class_dimensions[16]; // varies uint8 class_subclasses[16]; // varies uint8 class_masterbooks[16]; // varies int16 subclass_books[16][8]; // varies uint16 Xlist[31*8+2]; // varies uint8 sorted_order[31*8+2]; uint8 neighbors[31*8+2][2]; uint8 floor1_multiplier; uint8 rangebits; int values; } Floor1; typedef union { Floor0 floor0; Floor1 floor1; } Floor; typedef struct { uint32 begin, end; uint32 part_size; uint8 classifications; uint8 classbook; uint8 **classdata; int16 (*residue_books)[8]; } Residue; typedef struct { uint8 magnitude; uint8 angle; uint8 mux; } MappingChannel; typedef struct { uint16 coupling_steps; MappingChannel *chan; uint8 submaps; uint8 submap_floor[15]; // varies uint8 submap_residue[15]; // varies } Mapping; typedef struct { uint8 blockflag; uint8 mapping; uint16 windowtype; uint16 transformtype; } Mode; typedef struct { uint32 goal_crc; // expected crc if match int bytes_left; // bytes left in packet uint32 crc_so_far; // running crc int bytes_done; // bytes processed in _current_ chunk uint32 sample_loc; // granule pos encoded in page } CRCscan; typedef struct { uint32 page_start, page_end; uint32 last_decoded_sample; } ProbedPage; struct stb_vorbis { // user-accessible info unsigned int sample_rate; int channels; unsigned int setup_memory_required; unsigned int temp_memory_required; unsigned int setup_temp_memory_required; // input config #ifndef STB_VORBIS_NO_STDIO FILE *f; uint32 f_start; int close_on_free; #endif uint8 *stream; uint8 *stream_start; uint8 *stream_end; uint32 stream_len; uint8 push_mode; uint32 first_audio_page_offset; ProbedPage p_first, p_last; // memory management stb_vorbis_alloc alloc; int setup_offset; int temp_offset; // run-time results int eof; enum STBVorbisError error; // user-useful data // header info int blocksize[2]; int blocksize_0, blocksize_1; int codebook_count; Codebook *codebooks; int floor_count; uint16 floor_types[64]; // varies Floor *floor_config; int residue_count; uint16 residue_types[64]; // varies Residue *residue_config; int mapping_count; Mapping *mapping; int mode_count; Mode mode_config[64]; // varies uint32 total_samples; // decode buffer float *channel_buffers[STB_VORBIS_MAX_CHANNELS]; float *outputs [STB_VORBIS_MAX_CHANNELS]; float *previous_window[STB_VORBIS_MAX_CHANNELS]; int previous_length; #ifndef STB_VORBIS_NO_DEFER_FLOOR int16 *finalY[STB_VORBIS_MAX_CHANNELS]; #else float *floor_buffers[STB_VORBIS_MAX_CHANNELS]; #endif uint32 current_loc; // sample location of next frame to decode int current_loc_valid; // per-blocksize precomputed data // twiddle factors float *A[2],*B[2],*C[2]; float *window[2]; uint16 *bit_reverse[2]; // current page/packet/segment streaming info uint32 serial; // stream serial number for verification int last_page; int segment_count; uint8 segments[255]; uint8 page_flag; uint8 bytes_in_seg; uint8 first_decode; int next_seg; int last_seg; // flag that we're on the last segment int last_seg_which; // what was the segment number of the last seg? uint32 acc; int valid_bits; int packet_bytes; int end_seg_with_known_loc; uint32 known_loc_for_packet; int discard_samples_deferred; uint32 samples_output; // push mode scanning int page_crc_tests; // only in push_mode: number of tests active; -1 if not searching #ifndef STB_VORBIS_NO_PUSHDATA_API CRCscan scan[STB_VORBIS_PUSHDATA_CRC_COUNT]; #endif // sample-access int channel_buffer_start; int channel_buffer_end; }; #if defined(STB_VORBIS_NO_PUSHDATA_API) #define IS_PUSH_MODE(f) FALSE #elif defined(STB_VORBIS_NO_PULLDATA_API) #define IS_PUSH_MODE(f) TRUE #else #define IS_PUSH_MODE(f) ((f)->push_mode) #endif typedef struct stb_vorbis vorb; static int error(vorb *f, enum STBVorbisError e) { f->error = e; if (!f->eof && e != VORBIS_need_more_data) { f->error=e; // breakpoint for debugging } return 0; } // these functions are used for allocating temporary memory // while decoding. if you can afford the stack space, use // alloca(); otherwise, provide a temp buffer and it will // allocate out of those. #define array_size_required(count,size) (count*(sizeof(void *)+(size))) #define temp_alloc(f,size) (f->alloc.alloc_buffer ? setup_temp_malloc(f,size) : alloca(size)) #ifdef dealloca #define temp_free(f,p) (f->alloc.alloc_buffer ? 0 : dealloca(size)) #else #define temp_free(f,p) 0 #endif #define temp_alloc_save(f) ((f)->temp_offset) #define temp_alloc_restore(f,p) ((f)->temp_offset = (p)) #define temp_block_array(f,count,size) make_block_array(temp_alloc(f,array_size_required(count,size)), count, size) // given a sufficiently large block of memory, make an array of pointers to subblocks of it static void *make_block_array(void *mem, int count, int size) { int i; void ** p = (void **) mem; char *q = (char *) (p + count); for (i=0; i < count; ++i) { p[i] = q; q += size; } return p; } static void *setup_malloc(vorb *f, int sz) { sz = (sz+3) & ~3; f->setup_memory_required += sz; if (f->alloc.alloc_buffer) { void *p = (char *) f->alloc.alloc_buffer + f->setup_offset; if (f->setup_offset + sz > f->temp_offset) return NULL; f->setup_offset += sz; return p; } return sz ? malloc(sz) : NULL; } static void setup_free(vorb *f, void *p) { if (f->alloc.alloc_buffer) return; // do nothing; setup mem is a stack free(p); } static void *setup_temp_malloc(vorb *f, int sz) { sz = (sz+3) & ~3; if (f->alloc.alloc_buffer) { if (f->temp_offset - sz < f->setup_offset) return NULL; f->temp_offset -= sz; return (char *) f->alloc.alloc_buffer + f->temp_offset; } return malloc(sz); } static void setup_temp_free(vorb *f, void *p, int sz) { if (f->alloc.alloc_buffer) { f->temp_offset += (sz+3)&~3; return; } free(p); } #define CRC32_POLY 0x04c11db7 // from spec static uint32 crc_table[256]; static void crc32_init(void) { int i,j; uint32 s; for(i=0; i < 256; i++) { for (s=(uint32) i << 24, j=0; j < 8; ++j) s = (s << 1) ^ (s >= (1U<<31) ? CRC32_POLY : 0); crc_table[i] = s; } } static __forceinline uint32 crc32_update(uint32 crc, uint8 byte) { return (crc << 8) ^ crc_table[byte ^ (crc >> 24)]; } // used in setup, and for huffman that doesn't go fast path static unsigned int bit_reverse(unsigned int n) { n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1); n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2); n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4); n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8); return (n >> 16) | (n << 16); } static float square(float x) { return x*x; } // this is a weird definition of log2() for which log2(1) = 1, log2(2) = 2, log2(4) = 3 // as required by the specification. fast(?) implementation from stb.h // @OPTIMIZE: called multiple times per-packet with "constants"; move to setup static int ilog(int32 n) { static signed char log2_4[16] = { 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4 }; if (n < 0) return 0; // signed n returns 0 // 2 compares if n < 16, 3 compares otherwise (4 if signed or n > 1<<29) if (n < (1 << 14)) if (n < (1 << 4)) return 0 + log2_4[n ]; else if (n < (1 << 9)) return 5 + log2_4[n >> 5]; else return 10 + log2_4[n >> 10]; else if (n < (1 << 24)) if (n < (1 << 19)) return 15 + log2_4[n >> 15]; else return 20 + log2_4[n >> 20]; else if (n < (1 << 29)) return 25 + log2_4[n >> 25]; else return 30 + log2_4[n >> 30]; } #ifndef M_PI #define M_PI 3.14159265358979323846264f // from CRC #endif // code length assigned to a value with no huffman encoding #define NO_CODE 255 /////////////////////// LEAF SETUP FUNCTIONS ////////////////////////// // // these functions are only called at setup, and only a few times // per file static float float32_unpack(uint32 x) { // from the specification uint32 mantissa = x & 0x1fffff; uint32 sign = x & 0x80000000; uint32 exp = (x & 0x7fe00000) >> 21; double res = sign ? -(double)mantissa : (double)mantissa; return (float) ldexp((float)res, exp-788); } // zlib & jpeg huffman tables assume that the output symbols // can either be arbitrarily arranged, or have monotonically // increasing frequencies--they rely on the lengths being sorted; // this makes for a very simple generation algorithm. // vorbis allows a huffman table with non-sorted lengths. This // requires a more sophisticated construction, since symbols in // order do not map to huffman codes "in order". static void add_entry(Codebook *c, uint32 huff_code, int symbol, int count, int len, uint32 *values) { if (!c->sparse) { c->codewords [symbol] = huff_code; } else { c->codewords [count] = huff_code; c->codeword_lengths[count] = len; values [count] = symbol; } } static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) { int i,k,m=0; uint32 available[32]; memset(available, 0, sizeof(available)); // find the first entry for (k=0; k < n; ++k) if (len[k] < NO_CODE) break; if (k == n) { assert(c->sorted_entries == 0); return TRUE; } // add to the list add_entry(c, 0, k, m++, len[k], values); // add all available leaves for (i=1; i <= len[k]; ++i) available[i] = 1U << (32-i); // note that the above code treats the first case specially, // but it's really the same as the following code, so they // could probably be combined (except the initial code is 0, // and I use 0 in available[] to mean 'empty') for (i=k+1; i < n; ++i) { uint32 res; int z = len[i], y; if (z == NO_CODE) continue; // find lowest available leaf (should always be earliest, // which is what the specification calls for) // note that this property, and the fact we can never have // more than one free leaf at a given level, isn't totally // trivial to prove, but it seems true and the assert never // fires, so! while (z > 0 && !available[z]) --z; if (z == 0) { return FALSE; } res = available[z]; assert(z >= 0 && z < 32); available[z] = 0; add_entry(c, bit_reverse(res), i, m++, len[i], values); // propogate availability up the tree if (z != len[i]) { assert(len[i] >= 0 && len[i] < 32); for (y=len[i]; y > z; --y) { assert(available[y] == 0); available[y] = res + (1 << (32-y)); } } } return TRUE; } // accelerated huffman table allows fast O(1) match of all symbols // of length <= STB_VORBIS_FAST_HUFFMAN_LENGTH static void compute_accelerated_huffman(Codebook *c) { int i, len; for (i=0; i < FAST_HUFFMAN_TABLE_SIZE; ++i) c->fast_huffman[i] = -1; len = c->sparse ? c->sorted_entries : c->entries; #ifdef STB_VORBIS_FAST_HUFFMAN_SHORT if (len > 32767) len = 32767; // largest possible value we can encode! #endif for (i=0; i < len; ++i) { if (c->codeword_lengths[i] <= STB_VORBIS_FAST_HUFFMAN_LENGTH) { uint32 z = c->sparse ? bit_reverse(c->sorted_codewords[i]) : c->codewords[i]; // set table entries for all bit combinations in the higher bits while (z < FAST_HUFFMAN_TABLE_SIZE) { c->fast_huffman[z] = i; z += 1 << c->codeword_lengths[i]; } } } } #ifdef _MSC_VER #define STBV_CDECL __cdecl #else #define STBV_CDECL #endif static int STBV_CDECL uint32_compare(const void *p, const void *q) { uint32 x = * (uint32 *) p; uint32 y = * (uint32 *) q; return x < y ? -1 : x > y; } static int include_in_sort(Codebook *c, uint8 len) { if (c->sparse) { assert(len != NO_CODE); return TRUE; } if (len == NO_CODE) return FALSE; if (len > STB_VORBIS_FAST_HUFFMAN_LENGTH) return TRUE; return FALSE; } // if the fast table above doesn't work, we want to binary // search them... need to reverse the bits static void compute_sorted_huffman(Codebook *c, uint8 *lengths, uint32 *values) { int i, len; // build a list of all the entries // OPTIMIZATION: don't include the short ones, since they'll be caught by FAST_HUFFMAN. // this is kind of a frivolous optimization--I don't see any performance improvement, // but it's like 4 extra lines of code, so. if (!c->sparse) { int k = 0; for (i=0; i < c->entries; ++i) if (include_in_sort(c, lengths[i])) c->sorted_codewords[k++] = bit_reverse(c->codewords[i]); assert(k == c->sorted_entries); } else { for (i=0; i < c->sorted_entries; ++i) c->sorted_codewords[i] = bit_reverse(c->codewords[i]); } qsort(c->sorted_codewords, c->sorted_entries, sizeof(c->sorted_codewords[0]), uint32_compare); c->sorted_codewords[c->sorted_entries] = 0xffffffff; len = c->sparse ? c->sorted_entries : c->entries; // now we need to indicate how they correspond; we could either // #1: sort a different data structure that says who they correspond to // #2: for each sorted entry, search the original list to find who corresponds // #3: for each original entry, find the sorted entry // #1 requires extra storage, #2 is slow, #3 can use binary search! for (i=0; i < len; ++i) { int huff_len = c->sparse ? lengths[values[i]] : lengths[i]; if (include_in_sort(c,huff_len)) { uint32 code = bit_reverse(c->codewords[i]); int x=0, n=c->sorted_entries; while (n > 1) { // invariant: sc[x] <= code < sc[x+n] int m = x + (n >> 1); if (c->sorted_codewords[m] <= code) { x = m; n -= (n>>1); } else { n >>= 1; } } assert(c->sorted_codewords[x] == code); if (c->sparse) { c->sorted_values[x] = values[i]; c->codeword_lengths[x] = huff_len; } else { c->sorted_values[x] = i; } } } } // only run while parsing the header (3 times) static int vorbis_validate(uint8 *data) { static uint8 vorbis[6] = { 'v', 'o', 'r', 'b', 'i', 's' }; return memcmp(data, vorbis, 6) == 0; } // called from setup only, once per code book // (formula implied by specification) static int lookup1_values(int entries, int dim) { int r = (int) floor(exp((float) log((float) entries) / dim)); if ((int) floor(pow((float) r+1, dim)) <= entries) // (int) cast for MinGW warning; ++r; // floor() to avoid _ftol() when non-CRT assert(pow((float) r+1, dim) > entries); assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above return r; } // called twice per file static void compute_twiddle_factors(int n, float *A, float *B, float *C) { int n4 = n >> 2, n8 = n >> 3; int k,k2; for (k=k2=0; k < n4; ++k,k2+=2) { A[k2 ] = (float) cos(4*k*M_PI/n); A[k2+1] = (float) -sin(4*k*M_PI/n); B[k2 ] = (float) cos((k2+1)*M_PI/n/2) * 0.5f; B[k2+1] = (float) sin((k2+1)*M_PI/n/2) * 0.5f; } for (k=k2=0; k < n8; ++k,k2+=2) { C[k2 ] = (float) cos(2*(k2+1)*M_PI/n); C[k2+1] = (float) -sin(2*(k2+1)*M_PI/n); } } static void compute_window(int n, float *window) { int n2 = n >> 1, i; for (i=0; i < n2; ++i) window[i] = (float) sin(0.5 * M_PI * square((float) sin((i - 0 + 0.5) / n2 * 0.5 * M_PI))); } static void compute_bitreverse(int n, uint16 *rev) { int ld = ilog(n) - 1; // ilog is off-by-one from normal definitions int i, n8 = n >> 3; for (i=0; i < n8; ++i) rev[i] = (bit_reverse(i) >> (32-ld+3)) << 2; } static int init_blocksize(vorb *f, int b, int n) { int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3; f->A[b] = (float *) setup_malloc(f, sizeof(float) * n2); f->B[b] = (float *) setup_malloc(f, sizeof(float) * n2); f->C[b] = (float *) setup_malloc(f, sizeof(float) * n4); if (!f->A[b] || !f->B[b] || !f->C[b]) return error(f, VORBIS_outofmem); compute_twiddle_factors(n, f->A[b], f->B[b], f->C[b]); f->window[b] = (float *) setup_malloc(f, sizeof(float) * n2); if (!f->window[b]) return error(f, VORBIS_outofmem); compute_window(n, f->window[b]); f->bit_reverse[b] = (uint16 *) setup_malloc(f, sizeof(uint16) * n8); if (!f->bit_reverse[b]) return error(f, VORBIS_outofmem); compute_bitreverse(n, f->bit_reverse[b]); return TRUE; } static void neighbors(uint16 *x, int n, int *plow, int *phigh) { int low = -1; int high = 65536; int i; for (i=0; i < n; ++i) { if (x[i] > low && x[i] < x[n]) { *plow = i; low = x[i]; } if (x[i] < high && x[i] > x[n]) { *phigh = i; high = x[i]; } } } // this has been repurposed so y is now the original index instead of y typedef struct { uint16 x,id; } stbv__floor_ordering; static int STBV_CDECL point_compare(const void *p, const void *q) { stbv__floor_ordering *a = (stbv__floor_ordering *) p; stbv__floor_ordering *b = (stbv__floor_ordering *) q; return a->x < b->x ? -1 : a->x > b->x; } // /////////////////////// END LEAF SETUP FUNCTIONS ////////////////////////// #if defined(STB_VORBIS_NO_STDIO) #define USE_MEMORY(z) TRUE #else #define USE_MEMORY(z) ((z)->stream) #endif static uint8 get8(vorb *z) { if (USE_MEMORY(z)) { if (z->stream >= z->stream_end) { z->eof = TRUE; return 0; } return *z->stream++; } #ifndef STB_VORBIS_NO_STDIO { int c = fgetc(z->f); if (c == EOF) { z->eof = TRUE; return 0; } return c; } #endif } static uint32 get32(vorb *f) { uint32 x; x = get8(f); x += get8(f) << 8; x += get8(f) << 16; x += (uint32) get8(f) << 24; return x; } static int getn(vorb *z, uint8 *data, int n) { if (USE_MEMORY(z)) { if (z->stream+n > z->stream_end) { z->eof = 1; return 0; } memcpy(data, z->stream, n); z->stream += n; return 1; } #ifndef STB_VORBIS_NO_STDIO if (fread(data, n, 1, z->f) == 1) return 1; else { z->eof = 1; return 0; } #endif } static void skip(vorb *z, int n) { if (USE_MEMORY(z)) { z->stream += n; if (z->stream >= z->stream_end) z->eof = 1; return; } #ifndef STB_VORBIS_NO_STDIO { long x = ftell(z->f); fseek(z->f, x+n, SEEK_SET); } #endif } static int set_file_offset(stb_vorbis *f, unsigned int loc) { #ifndef STB_VORBIS_NO_PUSHDATA_API if (f->push_mode) return 0; #endif f->eof = 0; if (USE_MEMORY(f)) { if (f->stream_start + loc >= f->stream_end || f->stream_start + loc < f->stream_start) { f->stream = f->stream_end; f->eof = 1; return 0; } else { f->stream = f->stream_start + loc; return 1; } } #ifndef STB_VORBIS_NO_STDIO if (loc + f->f_start < loc || loc >= 0x80000000) { loc = 0x7fffffff; f->eof = 1; } else { loc += f->f_start; } if (!fseek(f->f, loc, SEEK_SET)) return 1; f->eof = 1; fseek(f->f, f->f_start, SEEK_END); return 0; #endif } static uint8 ogg_page_header[4] = { 0x4f, 0x67, 0x67, 0x53 }; static int capture_pattern(vorb *f) { if (0x4f != get8(f)) return FALSE; if (0x67 != get8(f)) return FALSE; if (0x67 != get8(f)) return FALSE; if (0x53 != get8(f)) return FALSE; return TRUE; } #define PAGEFLAG_continued_packet 1 #define PAGEFLAG_first_page 2 #define PAGEFLAG_last_page 4 static int start_page_no_capturepattern(vorb *f) { uint32 loc0,loc1,n; // stream structure version if (0 != get8(f)) return error(f, VORBIS_invalid_stream_structure_version); // header flag f->page_flag = get8(f); // absolute granule position loc0 = get32(f); loc1 = get32(f); // @TODO: validate loc0,loc1 as valid positions? // stream serial number -- vorbis doesn't interleave, so discard get32(f); //if (f->serial != get32(f)) return error(f, VORBIS_incorrect_stream_serial_number); // page sequence number n = get32(f); f->last_page = n; // CRC32 get32(f); // page_segments f->segment_count = get8(f); if (!getn(f, f->segments, f->segment_count)) return error(f, VORBIS_unexpected_eof); // assume we _don't_ know any the sample position of any segments f->end_seg_with_known_loc = -2; if (loc0 != ~0U || loc1 != ~0U) { int i; // determine which packet is the last one that will complete for (i=f->segment_count-1; i >= 0; --i) if (f->segments[i] < 255) break; // 'i' is now the index of the _last_ segment of a packet that ends if (i >= 0) { f->end_seg_with_known_loc = i; f->known_loc_for_packet = loc0; } } if (f->first_decode) { int i,len; ProbedPage p; len = 0; for (i=0; i < f->segment_count; ++i) len += f->segments[i]; len += 27 + f->segment_count; p.page_start = f->first_audio_page_offset; p.page_end = p.page_start + len; p.last_decoded_sample = loc0; f->p_first = p; } f->next_seg = 0; return TRUE; } static int start_page(vorb *f) { if (!capture_pattern(f)) return error(f, VORBIS_missing_capture_pattern); return start_page_no_capturepattern(f); } static int start_packet(vorb *f) { while (f->next_seg == -1) { if (!start_page(f)) return FALSE; if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_continued_packet_flag_invalid); } f->last_seg = FALSE; f->valid_bits = 0; f->packet_bytes = 0; f->bytes_in_seg = 0; // f->next_seg is now valid return TRUE; } static int maybe_start_packet(vorb *f) { if (f->next_seg == -1) { int x = get8(f); if (f->eof) return FALSE; // EOF at page boundary is not an error! if (0x4f != x ) return error(f, VORBIS_missing_capture_pattern); if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); if (0x67 != get8(f)) return error(f, VORBIS_missing_capture_pattern); if (0x53 != get8(f)) return error(f, VORBIS_missing_capture_pattern); if (!start_page_no_capturepattern(f)) return FALSE; if (f->page_flag & PAGEFLAG_continued_packet) { // set up enough state that we can read this packet if we want, // e.g. during recovery f->last_seg = FALSE; f->bytes_in_seg = 0; return error(f, VORBIS_continued_packet_flag_invalid); } } return start_packet(f); } static int next_segment(vorb *f) { int len; if (f->last_seg) return 0; if (f->next_seg == -1) { f->last_seg_which = f->segment_count-1; // in case start_page fails if (!start_page(f)) { f->last_seg = 1; return 0; } if (!(f->page_flag & PAGEFLAG_continued_packet)) return error(f, VORBIS_continued_packet_flag_invalid); } len = f->segments[f->next_seg++]; if (len < 255) { f->last_seg = TRUE; f->last_seg_which = f->next_seg-1; } if (f->next_seg >= f->segment_count) f->next_seg = -1; assert(f->bytes_in_seg == 0); f->bytes_in_seg = len; return len; } #define EOP (-1) #define INVALID_BITS (-1) static int get8_packet_raw(vorb *f) { if (!f->bytes_in_seg) { // CLANG! if (f->last_seg) return EOP; else if (!next_segment(f)) return EOP; } assert(f->bytes_in_seg > 0); --f->bytes_in_seg; ++f->packet_bytes; return get8(f); } static int get8_packet(vorb *f) { int x = get8_packet_raw(f); f->valid_bits = 0; return x; } static void flush_packet(vorb *f) { while (get8_packet_raw(f) != EOP); } // @OPTIMIZE: this is the secondary bit decoder, so it's probably not as important // as the huffman decoder? static uint32 get_bits(vorb *f, int n) { uint32 z; if (f->valid_bits < 0) return 0; if (f->valid_bits < n) { if (n > 24) { // the accumulator technique below would not work correctly in this case z = get_bits(f, 24); z += get_bits(f, n-24) << 24; return z; } if (f->valid_bits == 0) f->acc = 0; while (f->valid_bits < n) { int z = get8_packet_raw(f); if (z == EOP) { f->valid_bits = INVALID_BITS; return 0; } f->acc += z << f->valid_bits; f->valid_bits += 8; } } if (f->valid_bits < 0) return 0; if (n < 32) { z = f->acc & ((1U << n)-1); f->acc >>= n; } f->valid_bits -= n; return z; } // @OPTIMIZE: primary accumulator for huffman // expand the buffer to as many bits as possible without reading off end of packet // it might be nice to allow f->valid_bits and f->acc to be stored in registers, // e.g. cache them locally and decode locally static __forceinline void prep_huffman(vorb *f) { if (f->valid_bits <= 24) { if (f->valid_bits == 0) f->acc = 0; do { int z; if (f->last_seg && !f->bytes_in_seg) return; z = get8_packet_raw(f); if (z == EOP) return; f->acc += (unsigned) z << f->valid_bits; f->valid_bits += 8; } while (f->valid_bits <= 24); } } enum { VORBIS_packet_id = 1, VORBIS_packet_comment = 3, VORBIS_packet_setup = 5 }; static int codebook_decode_scalar_raw(vorb *f, Codebook *c) { int i; prep_huffman(f); if (c->codewords == NULL && c->sorted_codewords == NULL) return -1; // cases to use binary search: sorted_codewords && !c->codewords // sorted_codewords && c->entries > 8 if (c->entries > 8 ? c->sorted_codewords!=NULL : !c->codewords) { // binary search uint32 code = bit_reverse(f->acc); int x=0, n=c->sorted_entries, len; while (n > 1) { // invariant: sc[x] <= code < sc[x+n] int m = x + (n >> 1); if (c->sorted_codewords[m] <= code) { x = m; n -= (n>>1); } else { n >>= 1; } } // x is now the sorted index if (!c->sparse) x = c->sorted_values[x]; // x is now sorted index if sparse, or symbol otherwise len = c->codeword_lengths[x]; if (f->valid_bits >= len) { f->acc >>= len; f->valid_bits -= len; return x; } f->valid_bits = 0; return -1; } // if small, linear search assert(!c->sparse); for (i=0; i < c->entries; ++i) { if (c->codeword_lengths[i] == NO_CODE) continue; if (c->codewords[i] == (f->acc & ((1 << c->codeword_lengths[i])-1))) { if (f->valid_bits >= c->codeword_lengths[i]) { f->acc >>= c->codeword_lengths[i]; f->valid_bits -= c->codeword_lengths[i]; return i; } f->valid_bits = 0; return -1; } } error(f, VORBIS_invalid_stream); f->valid_bits = 0; return -1; } #ifndef STB_VORBIS_NO_INLINE_DECODE #define DECODE_RAW(var, f,c) \ if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) \ prep_huffman(f); \ var = f->acc & FAST_HUFFMAN_TABLE_MASK; \ var = c->fast_huffman[var]; \ if (var >= 0) { \ int n = c->codeword_lengths[var]; \ f->acc >>= n; \ f->valid_bits -= n; \ if (f->valid_bits < 0) { f->valid_bits = 0; var = -1; } \ } else { \ var = codebook_decode_scalar_raw(f,c); \ } #else static int codebook_decode_scalar(vorb *f, Codebook *c) { int i; if (f->valid_bits < STB_VORBIS_FAST_HUFFMAN_LENGTH) prep_huffman(f); // fast huffman table lookup i = f->acc & FAST_HUFFMAN_TABLE_MASK; i = c->fast_huffman[i]; if (i >= 0) { f->acc >>= c->codeword_lengths[i]; f->valid_bits -= c->codeword_lengths[i]; if (f->valid_bits < 0) { f->valid_bits = 0; return -1; } return i; } return codebook_decode_scalar_raw(f,c); } #define DECODE_RAW(var,f,c) var = codebook_decode_scalar(f,c); #endif #define DECODE(var,f,c) \ DECODE_RAW(var,f,c) \ if (c->sparse) var = c->sorted_values[var]; #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK #define DECODE_VQ(var,f,c) DECODE_RAW(var,f,c) #else #define DECODE_VQ(var,f,c) DECODE(var,f,c) #endif // CODEBOOK_ELEMENT_FAST is an optimization for the CODEBOOK_FLOATS case // where we avoid one addition #define CODEBOOK_ELEMENT(c,off) (c->multiplicands[off]) #define CODEBOOK_ELEMENT_FAST(c,off) (c->multiplicands[off]) #define CODEBOOK_ELEMENT_BASE(c) (0) static int codebook_decode_start(vorb *f, Codebook *c) { int z = -1; // type 0 is only legal in a scalar context if (c->lookup_type == 0) error(f, VORBIS_invalid_stream); else { DECODE_VQ(z,f,c); if (c->sparse) assert(z < c->sorted_entries); if (z < 0) { // check for EOP if (!f->bytes_in_seg) if (f->last_seg) return z; error(f, VORBIS_invalid_stream); } } return z; } static int codebook_decode(vorb *f, Codebook *c, float *output, int len) { int i,z = codebook_decode_start(f,c); if (z < 0) return FALSE; if (len > c->dimensions) len = c->dimensions; #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK if (c->lookup_type == 1) { float last = CODEBOOK_ELEMENT_BASE(c); int div = 1; for (i=0; i < len; ++i) { int off = (z / div) % c->lookup_values; float val = CODEBOOK_ELEMENT_FAST(c,off) + last; output[i] += val; if (c->sequence_p) last = val + c->minimum_value; div *= c->lookup_values; } return TRUE; } #endif z *= c->dimensions; if (c->sequence_p) { float last = CODEBOOK_ELEMENT_BASE(c); for (i=0; i < len; ++i) { float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; output[i] += val; last = val + c->minimum_value; } } else { float last = CODEBOOK_ELEMENT_BASE(c); for (i=0; i < len; ++i) { output[i] += CODEBOOK_ELEMENT_FAST(c,z+i) + last; } } return TRUE; } static int codebook_decode_step(vorb *f, Codebook *c, float *output, int len, int step) { int i,z = codebook_decode_start(f,c); float last = CODEBOOK_ELEMENT_BASE(c); if (z < 0) return FALSE; if (len > c->dimensions) len = c->dimensions; #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK if (c->lookup_type == 1) { int div = 1; for (i=0; i < len; ++i) { int off = (z / div) % c->lookup_values; float val = CODEBOOK_ELEMENT_FAST(c,off) + last; output[i*step] += val; if (c->sequence_p) last = val; div *= c->lookup_values; } return TRUE; } #endif z *= c->dimensions; for (i=0; i < len; ++i) { float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; output[i*step] += val; if (c->sequence_p) last = val; } return TRUE; } static int codebook_decode_deinterleave_repeat(vorb *f, Codebook *c, float **outputs, int ch, int *c_inter_p, int *p_inter_p, int len, int total_decode) { int c_inter = *c_inter_p; int p_inter = *p_inter_p; int i,z, effective = c->dimensions; // type 0 is only legal in a scalar context if (c->lookup_type == 0) return error(f, VORBIS_invalid_stream); while (total_decode > 0) { float last = CODEBOOK_ELEMENT_BASE(c); DECODE_VQ(z,f,c); #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK assert(!c->sparse || z < c->sorted_entries); #endif if (z < 0) { if (!f->bytes_in_seg) if (f->last_seg) return FALSE; return error(f, VORBIS_invalid_stream); } // if this will take us off the end of the buffers, stop short! // we check by computing the length of the virtual interleaved // buffer (len*ch), our current offset within it (p_inter*ch)+(c_inter), // and the length we'll be using (effective) if (c_inter + p_inter*ch + effective > len * ch) { effective = len*ch - (p_inter*ch - c_inter); } #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK if (c->lookup_type == 1) { int div = 1; for (i=0; i < effective; ++i) { int off = (z / div) % c->lookup_values; float val = CODEBOOK_ELEMENT_FAST(c,off) + last; if (outputs[c_inter]) outputs[c_inter][p_inter] += val; if (++c_inter == ch) { c_inter = 0; ++p_inter; } if (c->sequence_p) last = val; div *= c->lookup_values; } } else #endif { z *= c->dimensions; if (c->sequence_p) { for (i=0; i < effective; ++i) { float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; if (outputs[c_inter]) outputs[c_inter][p_inter] += val; if (++c_inter == ch) { c_inter = 0; ++p_inter; } last = val; } } else { for (i=0; i < effective; ++i) { float val = CODEBOOK_ELEMENT_FAST(c,z+i) + last; if (outputs[c_inter]) outputs[c_inter][p_inter] += val; if (++c_inter == ch) { c_inter = 0; ++p_inter; } } } } total_decode -= effective; } *c_inter_p = c_inter; *p_inter_p = p_inter; return TRUE; } static int predict_point(int x, int x0, int x1, int y0, int y1) { int dy = y1 - y0; int adx = x1 - x0; // @OPTIMIZE: force int division to round in the right direction... is this necessary on x86? int err = abs(dy) * (x - x0); int off = err / adx; return dy < 0 ? y0 - off : y0 + off; } // the following table is block-copied from the specification static float inverse_db_table[256] = { 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, 0.82788260f, 0.88168307f, 0.9389798f, 1.0f }; // @OPTIMIZE: if you want to replace this bresenham line-drawing routine, // note that you must produce bit-identical output to decode correctly; // this specific sequence of operations is specified in the spec (it's // drawing integer-quantized frequency-space lines that the encoder // expects to be exactly the same) // ... also, isn't the whole point of Bresenham's algorithm to NOT // have to divide in the setup? sigh. #ifndef STB_VORBIS_NO_DEFER_FLOOR #define LINE_OP(a,b) a *= b #else #define LINE_OP(a,b) a = b #endif #ifdef STB_VORBIS_DIVIDE_TABLE #define DIVTAB_NUMER 32 #define DIVTAB_DENOM 64 int8 integer_divide_table[DIVTAB_NUMER][DIVTAB_DENOM]; // 2KB #endif static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y1, int n) { int dy = y1 - y0; int adx = x1 - x0; int ady = abs(dy); int base; int x=x0,y=y0; int err = 0; int sy; #ifdef STB_VORBIS_DIVIDE_TABLE if (adx < DIVTAB_DENOM && ady < DIVTAB_NUMER) { if (dy < 0) { base = -integer_divide_table[ady][adx]; sy = base-1; } else { base = integer_divide_table[ady][adx]; sy = base+1; } } else { base = dy / adx; if (dy < 0) sy = base - 1; else sy = base+1; } #else base = dy / adx; if (dy < 0) sy = base - 1; else sy = base+1; #endif ady -= abs(base) * adx; if (x1 > n) x1 = n; if (x < x1) { LINE_OP(output[x], inverse_db_table[y]); for (++x; x < x1; ++x) { err += ady; if (err >= adx) { err -= adx; y += sy; } else y += base; LINE_OP(output[x], inverse_db_table[y]); } } } static int residue_decode(vorb *f, Codebook *book, float *target, int offset, int n, int rtype) { int k; if (rtype == 0) { int step = n / book->dimensions; for (k=0; k < step; ++k) if (!codebook_decode_step(f, book, target+offset+k, n-offset-k, step)) return FALSE; } else { for (k=0; k < n; ) { if (!codebook_decode(f, book, target+offset, n-k)) return FALSE; k += book->dimensions; offset += book->dimensions; } } return TRUE; } static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int rn, uint8 *do_not_decode) { int i,j,pass; Residue *r = f->residue_config + rn; int rtype = f->residue_types[rn]; int c = r->classbook; int classwords = f->codebooks[c].dimensions; int n_read = r->end - r->begin; int part_read = n_read / r->part_size; int temp_alloc_point = temp_alloc_save(f); #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE uint8 ***part_classdata = (uint8 ***) temp_block_array(f,f->channels, part_read * sizeof(**part_classdata)); #else int **classifications = (int **) temp_block_array(f,f->channels, part_read * sizeof(**classifications)); #endif CHECK(f); for (i=0; i < ch; ++i) if (!do_not_decode[i]) memset(residue_buffers[i], 0, sizeof(float) * n); if (rtype == 2 && ch != 1) { for (j=0; j < ch; ++j) if (!do_not_decode[j]) break; if (j == ch) goto done; for (pass=0; pass < 8; ++pass) { int pcount = 0, class_set = 0; if (ch == 2) { while (pcount < part_read) { int z = r->begin + pcount*r->part_size; int c_inter = (z & 1), p_inter = z>>1; if (pass == 0) { Codebook *c = f->codebooks+r->classbook; int q; DECODE(q,f,c); if (q == EOP) goto done; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE part_classdata[0][class_set] = r->classdata[q]; #else for (i=classwords-1; i >= 0; --i) { classifications[0][i+pcount] = q % r->classifications; q /= r->classifications; } #endif } for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { int z = r->begin + pcount*r->part_size; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE int c = part_classdata[0][class_set][i]; #else int c = classifications[0][pcount]; #endif int b = r->residue_books[c][pass]; if (b >= 0) { Codebook *book = f->codebooks + b; #ifdef STB_VORBIS_DIVIDES_IN_CODEBOOK if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; #else // saves 1% if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; #endif } else { z += r->part_size; c_inter = z & 1; p_inter = z >> 1; } } #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE ++class_set; #endif } } else if (ch == 1) { while (pcount < part_read) { int z = r->begin + pcount*r->part_size; int c_inter = 0, p_inter = z; if (pass == 0) { Codebook *c = f->codebooks+r->classbook; int q; DECODE(q,f,c); if (q == EOP) goto done; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE part_classdata[0][class_set] = r->classdata[q]; #else for (i=classwords-1; i >= 0; --i) { classifications[0][i+pcount] = q % r->classifications; q /= r->classifications; } #endif } for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { int z = r->begin + pcount*r->part_size; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE int c = part_classdata[0][class_set][i]; #else int c = classifications[0][pcount]; #endif int b = r->residue_books[c][pass]; if (b >= 0) { Codebook *book = f->codebooks + b; if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; } else { z += r->part_size; c_inter = 0; p_inter = z; } } #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE ++class_set; #endif } } else { while (pcount < part_read) { int z = r->begin + pcount*r->part_size; int c_inter = z % ch, p_inter = z/ch; if (pass == 0) { Codebook *c = f->codebooks+r->classbook; int q; DECODE(q,f,c); if (q == EOP) goto done; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE part_classdata[0][class_set] = r->classdata[q]; #else for (i=classwords-1; i >= 0; --i) { classifications[0][i+pcount] = q % r->classifications; q /= r->classifications; } #endif } for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { int z = r->begin + pcount*r->part_size; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE int c = part_classdata[0][class_set][i]; #else int c = classifications[0][pcount]; #endif int b = r->residue_books[c][pass]; if (b >= 0) { Codebook *book = f->codebooks + b; if (!codebook_decode_deinterleave_repeat(f, book, residue_buffers, ch, &c_inter, &p_inter, n, r->part_size)) goto done; } else { z += r->part_size; c_inter = z % ch; p_inter = z / ch; } } #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE ++class_set; #endif } } } goto done; } CHECK(f); for (pass=0; pass < 8; ++pass) { int pcount = 0, class_set=0; while (pcount < part_read) { if (pass == 0) { for (j=0; j < ch; ++j) { if (!do_not_decode[j]) { Codebook *c = f->codebooks+r->classbook; int temp; DECODE(temp,f,c); if (temp == EOP) goto done; #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE part_classdata[j][class_set] = r->classdata[temp]; #else for (i=classwords-1; i >= 0; --i) { classifications[j][i+pcount] = temp % r->classifications; temp /= r->classifications; } #endif } } } for (i=0; i < classwords && pcount < part_read; ++i, ++pcount) { for (j=0; j < ch; ++j) { if (!do_not_decode[j]) { #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE int c = part_classdata[j][class_set][i]; #else int c = classifications[j][pcount]; #endif int b = r->residue_books[c][pass]; if (b >= 0) { float *target = residue_buffers[j]; int offset = r->begin + pcount * r->part_size; int n = r->part_size; Codebook *book = f->codebooks + b; if (!residue_decode(f, book, target, offset, n, rtype)) goto done; } } } } #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE ++class_set; #endif } } done: CHECK(f); #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE temp_free(f,part_classdata); #else temp_free(f,classifications); #endif temp_alloc_restore(f,temp_alloc_point); } #if 0 // slow way for debugging void inverse_mdct_slow(float *buffer, int n) { int i,j; int n2 = n >> 1; float *x = (float *) malloc(sizeof(*x) * n2); memcpy(x, buffer, sizeof(*x) * n2); for (i=0; i < n; ++i) { float acc = 0; for (j=0; j < n2; ++j) // formula from paper: //acc += n/4.0f * x[j] * (float) cos(M_PI / 2 / n * (2 * i + 1 + n/2.0)*(2*j+1)); // formula from wikipedia //acc += 2.0f / n2 * x[j] * (float) cos(M_PI/n2 * (i + 0.5 + n2/2)*(j + 0.5)); // these are equivalent, except the formula from the paper inverts the multiplier! // however, what actually works is NO MULTIPLIER!?! //acc += 64 * 2.0f / n2 * x[j] * (float) cos(M_PI/n2 * (i + 0.5 + n2/2)*(j + 0.5)); acc += x[j] * (float) cos(M_PI / 2 / n * (2 * i + 1 + n/2.0)*(2*j+1)); buffer[i] = acc; } free(x); } #elif 0 // same as above, but just barely able to run in real time on modern machines void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) { float mcos[16384]; int i,j; int n2 = n >> 1, nmask = (n << 2) -1; float *x = (float *) malloc(sizeof(*x) * n2); memcpy(x, buffer, sizeof(*x) * n2); for (i=0; i < 4*n; ++i) mcos[i] = (float) cos(M_PI / 2 * i / n); for (i=0; i < n; ++i) { float acc = 0; for (j=0; j < n2; ++j) acc += x[j] * mcos[(2 * i + 1 + n2)*(2*j+1) & nmask]; buffer[i] = acc; } free(x); } #elif 0 // transform to use a slow dct-iv; this is STILL basically trivial, // but only requires half as many ops void dct_iv_slow(float *buffer, int n) { float mcos[16384]; float x[2048]; int i,j; int n2 = n >> 1, nmask = (n << 3) - 1; memcpy(x, buffer, sizeof(*x) * n); for (i=0; i < 8*n; ++i) mcos[i] = (float) cos(M_PI / 4 * i / n); for (i=0; i < n; ++i) { float acc = 0; for (j=0; j < n; ++j) acc += x[j] * mcos[((2 * i + 1)*(2*j+1)) & nmask]; buffer[i] = acc; } } void inverse_mdct_slow(float *buffer, int n, vorb *f, int blocktype) { int i, n4 = n >> 2, n2 = n >> 1, n3_4 = n - n4; float temp[4096]; memcpy(temp, buffer, n2 * sizeof(float)); dct_iv_slow(temp, n2); // returns -c'-d, a-b' for (i=0; i < n4 ; ++i) buffer[i] = temp[i+n4]; // a-b' for ( ; i < n3_4; ++i) buffer[i] = -temp[n3_4 - i - 1]; // b-a', c+d' for ( ; i < n ; ++i) buffer[i] = -temp[i - n3_4]; // c'+d } #endif #ifndef LIBVORBIS_MDCT #define LIBVORBIS_MDCT 0 #endif #if LIBVORBIS_MDCT // directly call the vorbis MDCT using an interface documented // by Jeff Roberts... useful for performance comparison typedef struct { int n; int log2n; float *trig; int *bitrev; float scale; } mdct_lookup; extern void mdct_init(mdct_lookup *lookup, int n); extern void mdct_clear(mdct_lookup *l); extern void mdct_backward(mdct_lookup *init, float *in, float *out); mdct_lookup M1,M2; void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) { mdct_lookup *M; if (M1.n == n) M = &M1; else if (M2.n == n) M = &M2; else if (M1.n == 0) { mdct_init(&M1, n); M = &M1; } else { if (M2.n) __asm int 3; mdct_init(&M2, n); M = &M2; } mdct_backward(M, buffer, buffer); } #endif // the following were split out into separate functions while optimizing; // they could be pushed back up but eh. __forceinline showed no change; // they're probably already being inlined. static void imdct_step3_iter0_loop(int n, float *e, int i_off, int k_off, float *A) { float *ee0 = e + i_off; float *ee2 = ee0 + k_off; int i; assert((n & 3) == 0); for (i=(n>>2); i > 0; --i) { float k00_20, k01_21; k00_20 = ee0[ 0] - ee2[ 0]; k01_21 = ee0[-1] - ee2[-1]; ee0[ 0] += ee2[ 0];//ee0[ 0] = ee0[ 0] + ee2[ 0]; ee0[-1] += ee2[-1];//ee0[-1] = ee0[-1] + ee2[-1]; ee2[ 0] = k00_20 * A[0] - k01_21 * A[1]; ee2[-1] = k01_21 * A[0] + k00_20 * A[1]; A += 8; k00_20 = ee0[-2] - ee2[-2]; k01_21 = ee0[-3] - ee2[-3]; ee0[-2] += ee2[-2];//ee0[-2] = ee0[-2] + ee2[-2]; ee0[-3] += ee2[-3];//ee0[-3] = ee0[-3] + ee2[-3]; ee2[-2] = k00_20 * A[0] - k01_21 * A[1]; ee2[-3] = k01_21 * A[0] + k00_20 * A[1]; A += 8; k00_20 = ee0[-4] - ee2[-4]; k01_21 = ee0[-5] - ee2[-5]; ee0[-4] += ee2[-4];//ee0[-4] = ee0[-4] + ee2[-4]; ee0[-5] += ee2[-5];//ee0[-5] = ee0[-5] + ee2[-5]; ee2[-4] = k00_20 * A[0] - k01_21 * A[1]; ee2[-5] = k01_21 * A[0] + k00_20 * A[1]; A += 8; k00_20 = ee0[-6] - ee2[-6]; k01_21 = ee0[-7] - ee2[-7]; ee0[-6] += ee2[-6];//ee0[-6] = ee0[-6] + ee2[-6]; ee0[-7] += ee2[-7];//ee0[-7] = ee0[-7] + ee2[-7]; ee2[-6] = k00_20 * A[0] - k01_21 * A[1]; ee2[-7] = k01_21 * A[0] + k00_20 * A[1]; A += 8; ee0 -= 8; ee2 -= 8; } } static void imdct_step3_inner_r_loop(int lim, float *e, int d0, int k_off, float *A, int k1) { int i; float k00_20, k01_21; float *e0 = e + d0; float *e2 = e0 + k_off; for (i=lim >> 2; i > 0; --i) { k00_20 = e0[-0] - e2[-0]; k01_21 = e0[-1] - e2[-1]; e0[-0] += e2[-0];//e0[-0] = e0[-0] + e2[-0]; e0[-1] += e2[-1];//e0[-1] = e0[-1] + e2[-1]; e2[-0] = (k00_20)*A[0] - (k01_21) * A[1]; e2[-1] = (k01_21)*A[0] + (k00_20) * A[1]; A += k1; k00_20 = e0[-2] - e2[-2]; k01_21 = e0[-3] - e2[-3]; e0[-2] += e2[-2];//e0[-2] = e0[-2] + e2[-2]; e0[-3] += e2[-3];//e0[-3] = e0[-3] + e2[-3]; e2[-2] = (k00_20)*A[0] - (k01_21) * A[1]; e2[-3] = (k01_21)*A[0] + (k00_20) * A[1]; A += k1; k00_20 = e0[-4] - e2[-4]; k01_21 = e0[-5] - e2[-5]; e0[-4] += e2[-4];//e0[-4] = e0[-4] + e2[-4]; e0[-5] += e2[-5];//e0[-5] = e0[-5] + e2[-5]; e2[-4] = (k00_20)*A[0] - (k01_21) * A[1]; e2[-5] = (k01_21)*A[0] + (k00_20) * A[1]; A += k1; k00_20 = e0[-6] - e2[-6]; k01_21 = e0[-7] - e2[-7]; e0[-6] += e2[-6];//e0[-6] = e0[-6] + e2[-6]; e0[-7] += e2[-7];//e0[-7] = e0[-7] + e2[-7]; e2[-6] = (k00_20)*A[0] - (k01_21) * A[1]; e2[-7] = (k01_21)*A[0] + (k00_20) * A[1]; e0 -= 8; e2 -= 8; A += k1; } } static void imdct_step3_inner_s_loop(int n, float *e, int i_off, int k_off, float *A, int a_off, int k0) { int i; float A0 = A[0]; float A1 = A[0+1]; float A2 = A[0+a_off]; float A3 = A[0+a_off+1]; float A4 = A[0+a_off*2+0]; float A5 = A[0+a_off*2+1]; float A6 = A[0+a_off*3+0]; float A7 = A[0+a_off*3+1]; float k00,k11; float *ee0 = e +i_off; float *ee2 = ee0+k_off; for (i=n; i > 0; --i) { k00 = ee0[ 0] - ee2[ 0]; k11 = ee0[-1] - ee2[-1]; ee0[ 0] = ee0[ 0] + ee2[ 0]; ee0[-1] = ee0[-1] + ee2[-1]; ee2[ 0] = (k00) * A0 - (k11) * A1; ee2[-1] = (k11) * A0 + (k00) * A1; k00 = ee0[-2] - ee2[-2]; k11 = ee0[-3] - ee2[-3]; ee0[-2] = ee0[-2] + ee2[-2]; ee0[-3] = ee0[-3] + ee2[-3]; ee2[-2] = (k00) * A2 - (k11) * A3; ee2[-3] = (k11) * A2 + (k00) * A3; k00 = ee0[-4] - ee2[-4]; k11 = ee0[-5] - ee2[-5]; ee0[-4] = ee0[-4] + ee2[-4]; ee0[-5] = ee0[-5] + ee2[-5]; ee2[-4] = (k00) * A4 - (k11) * A5; ee2[-5] = (k11) * A4 + (k00) * A5; k00 = ee0[-6] - ee2[-6]; k11 = ee0[-7] - ee2[-7]; ee0[-6] = ee0[-6] + ee2[-6]; ee0[-7] = ee0[-7] + ee2[-7]; ee2[-6] = (k00) * A6 - (k11) * A7; ee2[-7] = (k11) * A6 + (k00) * A7; ee0 -= k0; ee2 -= k0; } } static __forceinline void iter_54(float *z) { float k00,k11,k22,k33; float y0,y1,y2,y3; k00 = z[ 0] - z[-4]; y0 = z[ 0] + z[-4]; y2 = z[-2] + z[-6]; k22 = z[-2] - z[-6]; z[-0] = y0 + y2; // z0 + z4 + z2 + z6 z[-2] = y0 - y2; // z0 + z4 - z2 - z6 // done with y0,y2 k33 = z[-3] - z[-7]; z[-4] = k00 + k33; // z0 - z4 + z3 - z7 z[-6] = k00 - k33; // z0 - z4 - z3 + z7 // done with k33 k11 = z[-1] - z[-5]; y1 = z[-1] + z[-5]; y3 = z[-3] + z[-7]; z[-1] = y1 + y3; // z1 + z5 + z3 + z7 z[-3] = y1 - y3; // z1 + z5 - z3 - z7 z[-5] = k11 - k22; // z1 - z5 + z2 - z6 z[-7] = k11 + k22; // z1 - z5 - z2 + z6 } static void imdct_step3_inner_s_loop_ld654(int n, float *e, int i_off, float *A, int base_n) { int a_off = base_n >> 3; float A2 = A[0+a_off]; float *z = e + i_off; float *base = z - 16 * n; while (z > base) { float k00,k11; k00 = z[-0] - z[-8]; k11 = z[-1] - z[-9]; z[-0] = z[-0] + z[-8]; z[-1] = z[-1] + z[-9]; z[-8] = k00; z[-9] = k11 ; k00 = z[ -2] - z[-10]; k11 = z[ -3] - z[-11]; z[ -2] = z[ -2] + z[-10]; z[ -3] = z[ -3] + z[-11]; z[-10] = (k00+k11) * A2; z[-11] = (k11-k00) * A2; k00 = z[-12] - z[ -4]; // reverse to avoid a unary negation k11 = z[ -5] - z[-13]; z[ -4] = z[ -4] + z[-12]; z[ -5] = z[ -5] + z[-13]; z[-12] = k11; z[-13] = k00; k00 = z[-14] - z[ -6]; // reverse to avoid a unary negation k11 = z[ -7] - z[-15]; z[ -6] = z[ -6] + z[-14]; z[ -7] = z[ -7] + z[-15]; z[-14] = (k00+k11) * A2; z[-15] = (k00-k11) * A2; iter_54(z); iter_54(z-8); z -= 16; } } static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) { int n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l; int ld; // @OPTIMIZE: reduce register pressure by using fewer variables? int save_point = temp_alloc_save(f); float *buf2 = (float *) temp_alloc(f, n2 * sizeof(*buf2)); float *u=NULL,*v=NULL; // twiddle factors float *A = f->A[blocktype]; // IMDCT algorithm from "The use of multirate filter banks for coding of high quality digital audio" // See notes about bugs in that paper in less-optimal implementation 'inverse_mdct_old' after this function. // kernel from paper // merged: // copy and reflect spectral data // step 0 // note that it turns out that the items added together during // this step are, in fact, being added to themselves (as reflected // by step 0). inexplicable inefficiency! this became obvious // once I combined the passes. // so there's a missing 'times 2' here (for adding X to itself). // this propogates through linearly to the end, where the numbers // are 1/2 too small, and need to be compensated for. { float *d,*e, *AA, *e_stop; d = &buf2[n2-2]; AA = A; e = &buffer[0]; e_stop = &buffer[n2]; while (e != e_stop) { d[1] = (e[0] * AA[0] - e[2]*AA[1]); d[0] = (e[0] * AA[1] + e[2]*AA[0]); d -= 2; AA += 2; e += 4; } e = &buffer[n2-3]; while (d >= buf2) { d[1] = (-e[2] * AA[0] - -e[0]*AA[1]); d[0] = (-e[2] * AA[1] + -e[0]*AA[0]); d -= 2; AA += 2; e -= 4; } } // now we use symbolic names for these, so that we can // possibly swap their meaning as we change which operations // are in place u = buffer; v = buf2; // step 2 (paper output is w, now u) // this could be in place, but the data ends up in the wrong // place... _somebody_'s got to swap it, so this is nominated { float *AA = &A[n2-8]; float *d0,*d1, *e0, *e1; e0 = &v[n4]; e1 = &v[0]; d0 = &u[n4]; d1 = &u[0]; while (AA >= A) { float v40_20, v41_21; v41_21 = e0[1] - e1[1]; v40_20 = e0[0] - e1[0]; d0[1] = e0[1] + e1[1]; d0[0] = e0[0] + e1[0]; d1[1] = v41_21*AA[4] - v40_20*AA[5]; d1[0] = v40_20*AA[4] + v41_21*AA[5]; v41_21 = e0[3] - e1[3]; v40_20 = e0[2] - e1[2]; d0[3] = e0[3] + e1[3]; d0[2] = e0[2] + e1[2]; d1[3] = v41_21*AA[0] - v40_20*AA[1]; d1[2] = v40_20*AA[0] + v41_21*AA[1]; AA -= 8; d0 += 4; d1 += 4; e0 += 4; e1 += 4; } } // step 3 ld = ilog(n) - 1; // ilog is off-by-one from normal definitions // optimized step 3: // the original step3 loop can be nested r inside s or s inside r; // it's written originally as s inside r, but this is dumb when r // iterates many times, and s few. So I have two copies of it and // switch between them halfway. // this is iteration 0 of step 3 imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*0, -(n >> 3), A); imdct_step3_iter0_loop(n >> 4, u, n2-1-n4*1, -(n >> 3), A); // this is iteration 1 of step 3 imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*0, -(n >> 4), A, 16); imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*1, -(n >> 4), A, 16); imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*2, -(n >> 4), A, 16); imdct_step3_inner_r_loop(n >> 5, u, n2-1 - n8*3, -(n >> 4), A, 16); l=2; for (; l < (ld-3)>>1; ++l) { int k0 = n >> (l+2), k0_2 = k0>>1; int lim = 1 << (l+1); int i; for (i=0; i < lim; ++i) imdct_step3_inner_r_loop(n >> (l+4), u, n2-1 - k0*i, -k0_2, A, 1 << (l+3)); } for (; l < ld-6; ++l) { int k0 = n >> (l+2), k1 = 1 << (l+3), k0_2 = k0>>1; int rlim = n >> (l+6), r; int lim = 1 << (l+1); int i_off; float *A0 = A; i_off = n2-1; for (r=rlim; r > 0; --r) { imdct_step3_inner_s_loop(lim, u, i_off, -k0_2, A0, k1, k0); A0 += k1*4; i_off -= 8; } } // iterations with count: // ld-6,-5,-4 all interleaved together // the big win comes from getting rid of needless flops // due to the constants on pass 5 & 4 being all 1 and 0; // combining them to be simultaneous to improve cache made little difference imdct_step3_inner_s_loop_ld654(n >> 5, u, n2-1, A, n); // output is u // step 4, 5, and 6 // cannot be in-place because of step 5 { uint16 *bitrev = f->bit_reverse[blocktype]; // weirdly, I'd have thought reading sequentially and writing // erratically would have been better than vice-versa, but in // fact that's not what my testing showed. (That is, with // j = bitreverse(i), do you read i and write j, or read j and write i.) float *d0 = &v[n4-4]; float *d1 = &v[n2-4]; while (d0 >= v) { int k4; k4 = bitrev[0]; d1[3] = u[k4+0]; d1[2] = u[k4+1]; d0[3] = u[k4+2]; d0[2] = u[k4+3]; k4 = bitrev[1]; d1[1] = u[k4+0]; d1[0] = u[k4+1]; d0[1] = u[k4+2]; d0[0] = u[k4+3]; d0 -= 4; d1 -= 4; bitrev += 2; } } // (paper output is u, now v) // data must be in buf2 assert(v == buf2); // step 7 (paper output is v, now v) // this is now in place { float *C = f->C[blocktype]; float *d, *e; d = v; e = v + n2 - 4; while (d < e) { float a02,a11,b0,b1,b2,b3; a02 = d[0] - e[2]; a11 = d[1] + e[3]; b0 = C[1]*a02 + C[0]*a11; b1 = C[1]*a11 - C[0]*a02; b2 = d[0] + e[ 2]; b3 = d[1] - e[ 3]; d[0] = b2 + b0; d[1] = b3 + b1; e[2] = b2 - b0; e[3] = b1 - b3; a02 = d[2] - e[0]; a11 = d[3] + e[1]; b0 = C[3]*a02 + C[2]*a11; b1 = C[3]*a11 - C[2]*a02; b2 = d[2] + e[ 0]; b3 = d[3] - e[ 1]; d[2] = b2 + b0; d[3] = b3 + b1; e[0] = b2 - b0; e[1] = b1 - b3; C += 4; d += 4; e -= 4; } } // data must be in buf2 // step 8+decode (paper output is X, now buffer) // this generates pairs of data a la 8 and pushes them directly through // the decode kernel (pushing rather than pulling) to avoid having // to make another pass later // this cannot POSSIBLY be in place, so we refer to the buffers directly { float *d0,*d1,*d2,*d3; float *B = f->B[blocktype] + n2 - 8; float *e = buf2 + n2 - 8; d0 = &buffer[0]; d1 = &buffer[n2-4]; d2 = &buffer[n2]; d3 = &buffer[n-4]; while (e >= v) { float p0,p1,p2,p3; p3 = e[6]*B[7] - e[7]*B[6]; p2 = -e[6]*B[6] - e[7]*B[7]; d0[0] = p3; d1[3] = - p3; d2[0] = p2; d3[3] = p2; p1 = e[4]*B[5] - e[5]*B[4]; p0 = -e[4]*B[4] - e[5]*B[5]; d0[1] = p1; d1[2] = - p1; d2[1] = p0; d3[2] = p0; p3 = e[2]*B[3] - e[3]*B[2]; p2 = -e[2]*B[2] - e[3]*B[3]; d0[2] = p3; d1[1] = - p3; d2[2] = p2; d3[1] = p2; p1 = e[0]*B[1] - e[1]*B[0]; p0 = -e[0]*B[0] - e[1]*B[1]; d0[3] = p1; d1[0] = - p1; d2[3] = p0; d3[0] = p0; B -= 8; e -= 8; d0 += 4; d2 += 4; d1 -= 4; d3 -= 4; } } temp_free(f,buf2); temp_alloc_restore(f,save_point); } #if 0 // this is the original version of the above code, if you want to optimize it from scratch void inverse_mdct_naive(float *buffer, int n) { float s; float A[1 << 12], B[1 << 12], C[1 << 11]; int i,k,k2,k4, n2 = n >> 1, n4 = n >> 2, n8 = n >> 3, l; int n3_4 = n - n4, ld; // how can they claim this only uses N words?! // oh, because they're only used sparsely, whoops float u[1 << 13], X[1 << 13], v[1 << 13], w[1 << 13]; // set up twiddle factors for (k=k2=0; k < n4; ++k,k2+=2) { A[k2 ] = (float) cos(4*k*M_PI/n); A[k2+1] = (float) -sin(4*k*M_PI/n); B[k2 ] = (float) cos((k2+1)*M_PI/n/2); B[k2+1] = (float) sin((k2+1)*M_PI/n/2); } for (k=k2=0; k < n8; ++k,k2+=2) { C[k2 ] = (float) cos(2*(k2+1)*M_PI/n); C[k2+1] = (float) -sin(2*(k2+1)*M_PI/n); } // IMDCT algorithm from "The use of multirate filter banks for coding of high quality digital audio" // Note there are bugs in that pseudocode, presumably due to them attempting // to rename the arrays nicely rather than representing the way their actual // implementation bounces buffers back and forth. As a result, even in the // "some formulars corrected" version, a direct implementation fails. These // are noted below as "paper bug". // copy and reflect spectral data for (k=0; k < n2; ++k) u[k] = buffer[k]; for ( ; k < n ; ++k) u[k] = -buffer[n - k - 1]; // kernel from paper // step 1 for (k=k2=k4=0; k < n4; k+=1, k2+=2, k4+=4) { v[n-k4-1] = (u[k4] - u[n-k4-1]) * A[k2] - (u[k4+2] - u[n-k4-3])*A[k2+1]; v[n-k4-3] = (u[k4] - u[n-k4-1]) * A[k2+1] + (u[k4+2] - u[n-k4-3])*A[k2]; } // step 2 for (k=k4=0; k < n8; k+=1, k4+=4) { w[n2+3+k4] = v[n2+3+k4] + v[k4+3]; w[n2+1+k4] = v[n2+1+k4] + v[k4+1]; w[k4+3] = (v[n2+3+k4] - v[k4+3])*A[n2-4-k4] - (v[n2+1+k4]-v[k4+1])*A[n2-3-k4]; w[k4+1] = (v[n2+1+k4] - v[k4+1])*A[n2-4-k4] + (v[n2+3+k4]-v[k4+3])*A[n2-3-k4]; } // step 3 ld = ilog(n) - 1; // ilog is off-by-one from normal definitions for (l=0; l < ld-3; ++l) { int k0 = n >> (l+2), k1 = 1 << (l+3); int rlim = n >> (l+4), r4, r; int s2lim = 1 << (l+2), s2; for (r=r4=0; r < rlim; r4+=4,++r) { for (s2=0; s2 < s2lim; s2+=2) { u[n-1-k0*s2-r4] = w[n-1-k0*s2-r4] + w[n-1-k0*(s2+1)-r4]; u[n-3-k0*s2-r4] = w[n-3-k0*s2-r4] + w[n-3-k0*(s2+1)-r4]; u[n-1-k0*(s2+1)-r4] = (w[n-1-k0*s2-r4] - w[n-1-k0*(s2+1)-r4]) * A[r*k1] - (w[n-3-k0*s2-r4] - w[n-3-k0*(s2+1)-r4]) * A[r*k1+1]; u[n-3-k0*(s2+1)-r4] = (w[n-3-k0*s2-r4] - w[n-3-k0*(s2+1)-r4]) * A[r*k1] + (w[n-1-k0*s2-r4] - w[n-1-k0*(s2+1)-r4]) * A[r*k1+1]; } } if (l+1 < ld-3) { // paper bug: ping-ponging of u&w here is omitted memcpy(w, u, sizeof(u)); } } // step 4 for (i=0; i < n8; ++i) { int j = bit_reverse(i) >> (32-ld+3); assert(j < n8); if (i == j) { // paper bug: original code probably swapped in place; if copying, // need to directly copy in this case int i8 = i << 3; v[i8+1] = u[i8+1]; v[i8+3] = u[i8+3]; v[i8+5] = u[i8+5]; v[i8+7] = u[i8+7]; } else if (i < j) { int i8 = i << 3, j8 = j << 3; v[j8+1] = u[i8+1], v[i8+1] = u[j8 + 1]; v[j8+3] = u[i8+3], v[i8+3] = u[j8 + 3]; v[j8+5] = u[i8+5], v[i8+5] = u[j8 + 5]; v[j8+7] = u[i8+7], v[i8+7] = u[j8 + 7]; } } // step 5 for (k=0; k < n2; ++k) { w[k] = v[k*2+1]; } // step 6 for (k=k2=k4=0; k < n8; ++k, k2 += 2, k4 += 4) { u[n-1-k2] = w[k4]; u[n-2-k2] = w[k4+1]; u[n3_4 - 1 - k2] = w[k4+2]; u[n3_4 - 2 - k2] = w[k4+3]; } // step 7 for (k=k2=0; k < n8; ++k, k2 += 2) { v[n2 + k2 ] = ( u[n2 + k2] + u[n-2-k2] + C[k2+1]*(u[n2+k2]-u[n-2-k2]) + C[k2]*(u[n2+k2+1]+u[n-2-k2+1]))/2; v[n-2 - k2] = ( u[n2 + k2] + u[n-2-k2] - C[k2+1]*(u[n2+k2]-u[n-2-k2]) - C[k2]*(u[n2+k2+1]+u[n-2-k2+1]))/2; v[n2+1+ k2] = ( u[n2+1+k2] - u[n-1-k2] + C[k2+1]*(u[n2+1+k2]+u[n-1-k2]) - C[k2]*(u[n2+k2]-u[n-2-k2]))/2; v[n-1 - k2] = (-u[n2+1+k2] + u[n-1-k2] + C[k2+1]*(u[n2+1+k2]+u[n-1-k2]) - C[k2]*(u[n2+k2]-u[n-2-k2]))/2; } // step 8 for (k=k2=0; k < n4; ++k,k2 += 2) { X[k] = v[k2+n2]*B[k2 ] + v[k2+1+n2]*B[k2+1]; X[n2-1-k] = v[k2+n2]*B[k2+1] - v[k2+1+n2]*B[k2 ]; } // decode kernel to output // determined the following value experimentally // (by first figuring out what made inverse_mdct_slow work); then matching that here // (probably vorbis encoder premultiplies by n or n/2, to save it on the decoder?) s = 0.5; // theoretically would be n4 // [[[ note! the s value of 0.5 is compensated for by the B[] in the current code, // so it needs to use the "old" B values to behave correctly, or else // set s to 1.0 ]]] for (i=0; i < n4 ; ++i) buffer[i] = s * X[i+n4]; for ( ; i < n3_4; ++i) buffer[i] = -s * X[n3_4 - i - 1]; for ( ; i < n ; ++i) buffer[i] = -s * X[i - n3_4]; } #endif static float *get_window(vorb *f, int len) { len <<= 1; if (len == f->blocksize_0) return f->window[0]; if (len == f->blocksize_1) return f->window[1]; assert(0); return NULL; } #ifndef STB_VORBIS_NO_DEFER_FLOOR typedef int16 YTYPE; #else typedef int YTYPE; #endif static int do_floor(vorb *f, Mapping *map, int i, int n, float *target, YTYPE *finalY, uint8 *step2_flag) { int n2 = n >> 1; int s = map->chan[i].mux, floor; floor = map->submap_floor[s]; if (f->floor_types[floor] == 0) { return error(f, VORBIS_invalid_stream); } else { Floor1 *g = &f->floor_config[floor].floor1; int j,q; int lx = 0, ly = finalY[0] * g->floor1_multiplier; for (q=1; q < g->values; ++q) { j = g->sorted_order[q]; #ifndef STB_VORBIS_NO_DEFER_FLOOR if (finalY[j] >= 0) #else if (step2_flag[j]) #endif { int hy = finalY[j] * g->floor1_multiplier; int hx = g->Xlist[j]; if (lx != hx) draw_line(target, lx,ly, hx,hy, n2); CHECK(f); lx = hx, ly = hy; } } if (lx < n2) { // optimization of: draw_line(target, lx,ly, n,ly, n2); for (j=lx; j < n2; ++j) LINE_OP(target[j], inverse_db_table[ly]); CHECK(f); } } return TRUE; } // The meaning of "left" and "right" // // For a given frame: // we compute samples from 0..n // window_center is n/2 // we'll window and mix the samples from left_start to left_end with data from the previous frame // all of the samples from left_end to right_start can be output without mixing; however, // this interval is 0-length except when transitioning between short and long frames // all of the samples from right_start to right_end need to be mixed with the next frame, // which we don't have, so those get saved in a buffer // frame N's right_end-right_start, the number of samples to mix with the next frame, // has to be the same as frame N+1's left_end-left_start (which they are by // construction) static int vorbis_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) { Mode *m; int i, n, prev, next, window_center; f->channel_buffer_start = f->channel_buffer_end = 0; retry: if (f->eof) return FALSE; if (!maybe_start_packet(f)) return FALSE; // check packet type if (get_bits(f,1) != 0) { if (IS_PUSH_MODE(f)) return error(f,VORBIS_bad_packet_type); while (EOP != get8_packet(f)); goto retry; } if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); i = get_bits(f, ilog(f->mode_count-1)); if (i == EOP) return FALSE; if (i >= f->mode_count) return FALSE; *mode = i; m = f->mode_config + i; if (m->blockflag) { n = f->blocksize_1; prev = get_bits(f,1); next = get_bits(f,1); } else { prev = next = 0; n = f->blocksize_0; } // WINDOWING window_center = n >> 1; if (m->blockflag && !prev) { *p_left_start = (n - f->blocksize_0) >> 2; *p_left_end = (n + f->blocksize_0) >> 2; } else { *p_left_start = 0; *p_left_end = window_center; } if (m->blockflag && !next) { *p_right_start = (n*3 - f->blocksize_0) >> 2; *p_right_end = (n*3 + f->blocksize_0) >> 2; } else { *p_right_start = window_center; *p_right_end = n; } return TRUE; } static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, int left_end, int right_start, int right_end, int *p_left) { Mapping *map; int i,j,k,n,n2; int zero_channel[256]; int really_zero_channel[256]; // WINDOWING n = f->blocksize[m->blockflag]; map = &f->mapping[m->mapping]; // FLOORS n2 = n >> 1; CHECK(f); for (i=0; i < f->channels; ++i) { int s = map->chan[i].mux, floor; zero_channel[i] = FALSE; floor = map->submap_floor[s]; if (f->floor_types[floor] == 0) { return error(f, VORBIS_invalid_stream); } else { Floor1 *g = &f->floor_config[floor].floor1; if (get_bits(f, 1)) { short *finalY; uint8 step2_flag[256]; static int range_list[4] = { 256, 128, 86, 64 }; int range = range_list[g->floor1_multiplier-1]; int offset = 2; finalY = f->finalY[i]; finalY[0] = get_bits(f, ilog(range)-1); finalY[1] = get_bits(f, ilog(range)-1); for (j=0; j < g->partitions; ++j) { int pclass = g->partition_class_list[j]; int cdim = g->class_dimensions[pclass]; int cbits = g->class_subclasses[pclass]; int csub = (1 << cbits)-1; int cval = 0; if (cbits) { Codebook *c = f->codebooks + g->class_masterbooks[pclass]; DECODE(cval,f,c); } for (k=0; k < cdim; ++k) { int book = g->subclass_books[pclass][cval & csub]; cval = cval >> cbits; if (book >= 0) { int temp; Codebook *c = f->codebooks + book; DECODE(temp,f,c); finalY[offset++] = temp; } else finalY[offset++] = 0; } } if (f->valid_bits == INVALID_BITS) goto error; // behavior according to spec step2_flag[0] = step2_flag[1] = 1; for (j=2; j < g->values; ++j) { int low, high, pred, highroom, lowroom, room, val; low = g->neighbors[j][0]; high = g->neighbors[j][1]; //neighbors(g->Xlist, j, &low, &high); pred = predict_point(g->Xlist[j], g->Xlist[low], g->Xlist[high], finalY[low], finalY[high]); val = finalY[j]; highroom = range - pred; lowroom = pred; if (highroom < lowroom) room = highroom * 2; else room = lowroom * 2; if (val) { step2_flag[low] = step2_flag[high] = 1; step2_flag[j] = 1; if (val >= room) if (highroom > lowroom) finalY[j] = val - lowroom + pred; else finalY[j] = pred - val + highroom - 1; else if (val & 1) finalY[j] = pred - ((val+1)>>1); else finalY[j] = pred + (val>>1); } else { step2_flag[j] = 0; finalY[j] = pred; } } #ifdef STB_VORBIS_NO_DEFER_FLOOR do_floor(f, map, i, n, f->floor_buffers[i], finalY, step2_flag); #else // defer final floor computation until _after_ residue for (j=0; j < g->values; ++j) { if (!step2_flag[j]) finalY[j] = -1; } #endif } else { error: zero_channel[i] = TRUE; } // So we just defer everything else to later // at this point we've decoded the floor into buffer } } CHECK(f); // at this point we've decoded all floors if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); // re-enable coupled channels if necessary memcpy(really_zero_channel, zero_channel, sizeof(really_zero_channel[0]) * f->channels); for (i=0; i < map->coupling_steps; ++i) if (!zero_channel[map->chan[i].magnitude] || !zero_channel[map->chan[i].angle]) { zero_channel[map->chan[i].magnitude] = zero_channel[map->chan[i].angle] = FALSE; } CHECK(f); // RESIDUE DECODE for (i=0; i < map->submaps; ++i) { float *residue_buffers[STB_VORBIS_MAX_CHANNELS]; int r; uint8 do_not_decode[256]; int ch = 0; for (j=0; j < f->channels; ++j) { if (map->chan[j].mux == i) { if (zero_channel[j]) { do_not_decode[ch] = TRUE; residue_buffers[ch] = NULL; } else { do_not_decode[ch] = FALSE; residue_buffers[ch] = f->channel_buffers[j]; } ++ch; } } r = map->submap_residue[i]; decode_residue(f, residue_buffers, ch, n2, r, do_not_decode); } if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); CHECK(f); // INVERSE COUPLING for (i = map->coupling_steps-1; i >= 0; --i) { int n2 = n >> 1; float *m = f->channel_buffers[map->chan[i].magnitude]; float *a = f->channel_buffers[map->chan[i].angle ]; for (j=0; j < n2; ++j) { float a2,m2; if (m[j] > 0) if (a[j] > 0) m2 = m[j], a2 = m[j] - a[j]; else a2 = m[j], m2 = m[j] + a[j]; else if (a[j] > 0) m2 = m[j], a2 = m[j] + a[j]; else a2 = m[j], m2 = m[j] - a[j]; m[j] = m2; a[j] = a2; } } CHECK(f); // finish decoding the floors #ifndef STB_VORBIS_NO_DEFER_FLOOR for (i=0; i < f->channels; ++i) { if (really_zero_channel[i]) { memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2); } else { do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], NULL); } } #else for (i=0; i < f->channels; ++i) { if (really_zero_channel[i]) { memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2); } else { for (j=0; j < n2; ++j) f->channel_buffers[i][j] *= f->floor_buffers[i][j]; } } #endif // INVERSE MDCT CHECK(f); for (i=0; i < f->channels; ++i) inverse_mdct(f->channel_buffers[i], n, f, m->blockflag); CHECK(f); // this shouldn't be necessary, unless we exited on an error // and want to flush to get to the next packet flush_packet(f); if (f->first_decode) { // assume we start so first non-discarded sample is sample 0 // this isn't to spec, but spec would require us to read ahead // and decode the size of all current frames--could be done, // but presumably it's not a commonly used feature f->current_loc = -n2; // start of first frame is positioned for discard // we might have to discard samples "from" the next frame too, // if we're lapping a large block then a small at the start? f->discard_samples_deferred = n - right_end; f->current_loc_valid = TRUE; f->first_decode = FALSE; } else if (f->discard_samples_deferred) { if (f->discard_samples_deferred >= right_start - left_start) { f->discard_samples_deferred -= (right_start - left_start); left_start = right_start; *p_left = left_start; } else { left_start += f->discard_samples_deferred; *p_left = left_start; f->discard_samples_deferred = 0; } } else if (f->previous_length == 0 && f->current_loc_valid) { // we're recovering from a seek... that means we're going to discard // the samples from this packet even though we know our position from // the last page header, so we need to update the position based on // the discarded samples here // but wait, the code below is going to add this in itself even // on a discard, so we don't need to do it here... } // check if we have ogg information about the sample # for this packet if (f->last_seg_which == f->end_seg_with_known_loc) { // if we have a valid current loc, and this is final: if (f->current_loc_valid && (f->page_flag & PAGEFLAG_last_page)) { uint32 current_end = f->known_loc_for_packet - (n-right_end); // then let's infer the size of the (probably) short final frame if (current_end < f->current_loc + (right_end-left_start)) { if (current_end < f->current_loc) { // negative truncation, that's impossible! *len = 0; } else { *len = current_end - f->current_loc; } *len += left_start; if (*len > right_end) *len = right_end; // this should never happen f->current_loc += *len; return TRUE; } } // otherwise, just set our sample loc // guess that the ogg granule pos refers to the _middle_ of the // last frame? // set f->current_loc to the position of left_start f->current_loc = f->known_loc_for_packet - (n2-left_start); f->current_loc_valid = TRUE; } if (f->current_loc_valid) f->current_loc += (right_start - left_start); if (f->alloc.alloc_buffer) assert(f->alloc.alloc_buffer_length_in_bytes == f->temp_offset); *len = right_end; // ignore samples after the window goes to 0 CHECK(f); return TRUE; } static int vorbis_decode_packet(vorb *f, int *len, int *p_left, int *p_right) { int mode, left_end, right_end; if (!vorbis_decode_initial(f, p_left, &left_end, p_right, &right_end, &mode)) return 0; return vorbis_decode_packet_rest(f, len, f->mode_config + mode, *p_left, left_end, *p_right, right_end, p_left); } static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right) { int prev,i,j; // we use right&left (the start of the right- and left-window sin()-regions) // to determine how much to return, rather than inferring from the rules // (same result, clearer code); 'left' indicates where our sin() window // starts, therefore where the previous window's right edge starts, and // therefore where to start mixing from the previous buffer. 'right' // indicates where our sin() ending-window starts, therefore that's where // we start saving, and where our returned-data ends. // mixin from previous window if (f->previous_length) { int i,j, n = f->previous_length; float *w = get_window(f, n); for (i=0; i < f->channels; ++i) { for (j=0; j < n; ++j) f->channel_buffers[i][left+j] = f->channel_buffers[i][left+j]*w[ j] + f->previous_window[i][ j]*w[n-1-j]; } } prev = f->previous_length; // last half of this data becomes previous window f->previous_length = len - right; // @OPTIMIZE: could avoid this copy by double-buffering the // output (flipping previous_window with channel_buffers), but // then previous_window would have to be 2x as large, and // channel_buffers couldn't be temp mem (although they're NOT // currently temp mem, they could be (unless we want to level // performance by spreading out the computation)) for (i=0; i < f->channels; ++i) for (j=0; right+j < len; ++j) f->previous_window[i][j] = f->channel_buffers[i][right+j]; if (!prev) // there was no previous packet, so this data isn't valid... // this isn't entirely true, only the would-have-overlapped data // isn't valid, but this seems to be what the spec requires return 0; // truncate a short frame if (len < right) right = len; f->samples_output += right-left; return right - left; } static int vorbis_pump_first_frame(stb_vorbis *f) { int len, right, left, res; res = vorbis_decode_packet(f, &len, &left, &right); if (res) vorbis_finish_frame(f, len, left, right); return res; } #ifndef STB_VORBIS_NO_PUSHDATA_API static int is_whole_packet_present(stb_vorbis *f, int end_page) { // make sure that we have the packet available before continuing... // this requires a full ogg parse, but we know we can fetch from f->stream // instead of coding this out explicitly, we could save the current read state, // read the next packet with get8() until end-of-packet, check f->eof, then // reset the state? but that would be slower, esp. since we'd have over 256 bytes // of state to restore (primarily the page segment table) int s = f->next_seg, first = TRUE; uint8 *p = f->stream; if (s != -1) { // if we're not starting the packet with a 'continue on next page' flag for (; s < f->segment_count; ++s) { p += f->segments[s]; if (f->segments[s] < 255) // stop at first short segment break; } // either this continues, or it ends it... if (end_page) if (s < f->segment_count-1) return error(f, VORBIS_invalid_stream); if (s == f->segment_count) s = -1; // set 'crosses page' flag if (p > f->stream_end) return error(f, VORBIS_need_more_data); first = FALSE; } for (; s == -1;) { uint8 *q; int n; // check that we have the page header ready if (p + 26 >= f->stream_end) return error(f, VORBIS_need_more_data); // validate the page if (memcmp(p, ogg_page_header, 4)) return error(f, VORBIS_invalid_stream); if (p[4] != 0) return error(f, VORBIS_invalid_stream); if (first) { // the first segment must NOT have 'continued_packet', later ones MUST if (f->previous_length) if ((p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream); // if no previous length, we're resynching, so we can come in on a continued-packet, // which we'll just drop } else { if (!(p[5] & PAGEFLAG_continued_packet)) return error(f, VORBIS_invalid_stream); } n = p[26]; // segment counts q = p+27; // q points to segment table p = q + n; // advance past header // make sure we've read the segment table if (p > f->stream_end) return error(f, VORBIS_need_more_data); for (s=0; s < n; ++s) { p += q[s]; if (q[s] < 255) break; } if (end_page) if (s < n-1) return error(f, VORBIS_invalid_stream); if (s == n) s = -1; // set 'crosses page' flag if (p > f->stream_end) return error(f, VORBIS_need_more_data); first = FALSE; } return TRUE; } #endif // !STB_VORBIS_NO_PUSHDATA_API static int start_decoder(vorb *f) { uint8 header[6], x,y; int len,i,j,k, max_submaps = 0; int longest_floorlist=0; // first page, first packet if (!start_page(f)) return FALSE; // validate page flag if (!(f->page_flag & PAGEFLAG_first_page)) return error(f, VORBIS_invalid_first_page); if (f->page_flag & PAGEFLAG_last_page) return error(f, VORBIS_invalid_first_page); if (f->page_flag & PAGEFLAG_continued_packet) return error(f, VORBIS_invalid_first_page); // check for expected packet length if (f->segment_count != 1) return error(f, VORBIS_invalid_first_page); if (f->segments[0] != 30) return error(f, VORBIS_invalid_first_page); // read packet // check packet header if (get8(f) != VORBIS_packet_id) return error(f, VORBIS_invalid_first_page); if (!getn(f, header, 6)) return error(f, VORBIS_unexpected_eof); if (!vorbis_validate(header)) return error(f, VORBIS_invalid_first_page); // vorbis_version if (get32(f) != 0) return error(f, VORBIS_invalid_first_page); f->channels = get8(f); if (!f->channels) return error(f, VORBIS_invalid_first_page); if (f->channels > STB_VORBIS_MAX_CHANNELS) return error(f, VORBIS_too_many_channels); f->sample_rate = get32(f); if (!f->sample_rate) return error(f, VORBIS_invalid_first_page); get32(f); // bitrate_maximum get32(f); // bitrate_nominal get32(f); // bitrate_minimum x = get8(f); { int log0,log1; log0 = x & 15; log1 = x >> 4; f->blocksize_0 = 1 << log0; f->blocksize_1 = 1 << log1; if (log0 < 6 || log0 > 13) return error(f, VORBIS_invalid_setup); if (log1 < 6 || log1 > 13) return error(f, VORBIS_invalid_setup); if (log0 > log1) return error(f, VORBIS_invalid_setup); } // framing_flag x = get8(f); if (!(x & 1)) return error(f, VORBIS_invalid_first_page); // second packet! if (!start_page(f)) return FALSE; if (!start_packet(f)) return FALSE; do { len = next_segment(f); skip(f, len); f->bytes_in_seg = 0; } while (len); // third packet! if (!start_packet(f)) return FALSE; #ifndef STB_VORBIS_NO_PUSHDATA_API if (IS_PUSH_MODE(f)) { if (!is_whole_packet_present(f, TRUE)) { // convert error in ogg header to write type if (f->error == VORBIS_invalid_stream) f->error = VORBIS_invalid_setup; return FALSE; } } #endif crc32_init(); // always init it, to avoid multithread race conditions if (get8_packet(f) != VORBIS_packet_setup) return error(f, VORBIS_invalid_setup); for (i=0; i < 6; ++i) header[i] = get8_packet(f); if (!vorbis_validate(header)) return error(f, VORBIS_invalid_setup); // codebooks f->codebook_count = get_bits(f,8) + 1; f->codebooks = (Codebook *) setup_malloc(f, sizeof(*f->codebooks) * f->codebook_count); if (f->codebooks == NULL) return error(f, VORBIS_outofmem); memset(f->codebooks, 0, sizeof(*f->codebooks) * f->codebook_count); for (i=0; i < f->codebook_count; ++i) { uint32 *values; int ordered, sorted_count; int total=0; uint8 *lengths; Codebook *c = f->codebooks+i; CHECK(f); x = get_bits(f, 8); if (x != 0x42) return error(f, VORBIS_invalid_setup); x = get_bits(f, 8); if (x != 0x43) return error(f, VORBIS_invalid_setup); x = get_bits(f, 8); if (x != 0x56) return error(f, VORBIS_invalid_setup); x = get_bits(f, 8); c->dimensions = (get_bits(f, 8)<<8) + x; x = get_bits(f, 8); y = get_bits(f, 8); c->entries = (get_bits(f, 8)<<16) + (y<<8) + x; ordered = get_bits(f,1); c->sparse = ordered ? 0 : get_bits(f,1); if (c->dimensions == 0 && c->entries != 0) return error(f, VORBIS_invalid_setup); if (c->sparse) lengths = (uint8 *) setup_temp_malloc(f, c->entries); else lengths = c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries); if (!lengths) return error(f, VORBIS_outofmem); if (ordered) { int current_entry = 0; int current_length = get_bits(f,5) + 1; while (current_entry < c->entries) { int limit = c->entries - current_entry; int n = get_bits(f, ilog(limit)); if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); } memset(lengths + current_entry, current_length, n); current_entry += n; ++current_length; } } else { for (j=0; j < c->entries; ++j) { int present = c->sparse ? get_bits(f,1) : 1; if (present) { lengths[j] = get_bits(f, 5) + 1; ++total; if (lengths[j] == 32) return error(f, VORBIS_invalid_setup); } else { lengths[j] = NO_CODE; } } } if (c->sparse && total >= c->entries >> 2) { // convert sparse items to non-sparse! if (c->entries > (int) f->setup_temp_memory_required) f->setup_temp_memory_required = c->entries; c->codeword_lengths = (uint8 *) setup_malloc(f, c->entries); if (c->codeword_lengths == NULL) return error(f, VORBIS_outofmem); memcpy(c->codeword_lengths, lengths, c->entries); setup_temp_free(f, lengths, c->entries); // note this is only safe if there have been no intervening temp mallocs! lengths = c->codeword_lengths; c->sparse = 0; } // compute the size of the sorted tables if (c->sparse) { sorted_count = total; } else { sorted_count = 0; #ifndef STB_VORBIS_NO_HUFFMAN_BINARY_SEARCH for (j=0; j < c->entries; ++j) if (lengths[j] > STB_VORBIS_FAST_HUFFMAN_LENGTH && lengths[j] != NO_CODE) ++sorted_count; #endif } c->sorted_entries = sorted_count; values = NULL; CHECK(f); if (!c->sparse) { c->codewords = (uint32 *) setup_malloc(f, sizeof(c->codewords[0]) * c->entries); if (!c->codewords) return error(f, VORBIS_outofmem); } else { unsigned int size; if (c->sorted_entries) { c->codeword_lengths = (uint8 *) setup_malloc(f, c->sorted_entries); if (!c->codeword_lengths) return error(f, VORBIS_outofmem); c->codewords = (uint32 *) setup_temp_malloc(f, sizeof(*c->codewords) * c->sorted_entries); if (!c->codewords) return error(f, VORBIS_outofmem); values = (uint32 *) setup_temp_malloc(f, sizeof(*values) * c->sorted_entries); if (!values) return error(f, VORBIS_outofmem); } size = c->entries + (sizeof(*c->codewords) + sizeof(*values)) * c->sorted_entries; if (size > f->setup_temp_memory_required) f->setup_temp_memory_required = size; } if (!compute_codewords(c, lengths, c->entries, values)) { if (c->sparse) setup_temp_free(f, values, 0); return error(f, VORBIS_invalid_setup); } if (c->sorted_entries) { // allocate an extra slot for sentinels c->sorted_codewords = (uint32 *) setup_malloc(f, sizeof(*c->sorted_codewords) * (c->sorted_entries+1)); if (c->sorted_codewords == NULL) return error(f, VORBIS_outofmem); // allocate an extra slot at the front so that c->sorted_values[-1] is defined // so that we can catch that case without an extra if c->sorted_values = ( int *) setup_malloc(f, sizeof(*c->sorted_values ) * (c->sorted_entries+1)); if (c->sorted_values == NULL) return error(f, VORBIS_outofmem); ++c->sorted_values; c->sorted_values[-1] = -1; compute_sorted_huffman(c, lengths, values); } if (c->sparse) { setup_temp_free(f, values, sizeof(*values)*c->sorted_entries); setup_temp_free(f, c->codewords, sizeof(*c->codewords)*c->sorted_entries); setup_temp_free(f, lengths, c->entries); c->codewords = NULL; } compute_accelerated_huffman(c); CHECK(f); c->lookup_type = get_bits(f, 4); if (c->lookup_type > 2) return error(f, VORBIS_invalid_setup); if (c->lookup_type > 0) { uint16 *mults; c->minimum_value = float32_unpack(get_bits(f, 32)); c->delta_value = float32_unpack(get_bits(f, 32)); c->value_bits = get_bits(f, 4)+1; c->sequence_p = get_bits(f,1); if (c->lookup_type == 1) { c->lookup_values = lookup1_values(c->entries, c->dimensions); } else { c->lookup_values = c->entries * c->dimensions; } if (c->lookup_values == 0) return error(f, VORBIS_invalid_setup); mults = (uint16 *) setup_temp_malloc(f, sizeof(mults[0]) * c->lookup_values); if (mults == NULL) return error(f, VORBIS_outofmem); for (j=0; j < (int) c->lookup_values; ++j) { int q = get_bits(f, c->value_bits); if (q == EOP) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_invalid_setup); } mults[j] = q; } #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK if (c->lookup_type == 1) { int len, sparse = c->sparse; float last=0; // pre-expand the lookup1-style multiplicands, to avoid a divide in the inner loop if (sparse) { if (c->sorted_entries == 0) goto skip; c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->sorted_entries * c->dimensions); } else c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->entries * c->dimensions); if (c->multiplicands == NULL) { setup_temp_free(f,mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } len = sparse ? c->sorted_entries : c->entries; for (j=0; j < len; ++j) { unsigned int z = sparse ? c->sorted_values[j] : j; unsigned int div=1; for (k=0; k < c->dimensions; ++k) { int off = (z / div) % c->lookup_values; float val = mults[off]; val = mults[off]*c->delta_value + c->minimum_value + last; c->multiplicands[j*c->dimensions + k] = val; if (c->sequence_p) last = val; if (k+1 < c->dimensions) { if (div > UINT_MAX / (unsigned int) c->lookup_values) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_invalid_setup); } div *= c->lookup_values; } } } c->lookup_type = 2; } else #endif { float last=0; CHECK(f); c->multiplicands = (codetype *) setup_malloc(f, sizeof(c->multiplicands[0]) * c->lookup_values); if (c->multiplicands == NULL) { setup_temp_free(f, mults,sizeof(mults[0])*c->lookup_values); return error(f, VORBIS_outofmem); } for (j=0; j < (int) c->lookup_values; ++j) { float val = mults[j] * c->delta_value + c->minimum_value + last; c->multiplicands[j] = val; if (c->sequence_p) last = val; } } #ifndef STB_VORBIS_DIVIDES_IN_CODEBOOK skip:; #endif setup_temp_free(f, mults, sizeof(mults[0])*c->lookup_values); CHECK(f); } CHECK(f); } // time domain transfers (notused) x = get_bits(f, 6) + 1; for (i=0; i < x; ++i) { uint32 z = get_bits(f, 16); if (z != 0) return error(f, VORBIS_invalid_setup); } // Floors f->floor_count = get_bits(f, 6)+1; f->floor_config = (Floor *) setup_malloc(f, f->floor_count * sizeof(*f->floor_config)); if (f->floor_config == NULL) return error(f, VORBIS_outofmem); for (i=0; i < f->floor_count; ++i) { f->floor_types[i] = get_bits(f, 16); if (f->floor_types[i] > 1) return error(f, VORBIS_invalid_setup); if (f->floor_types[i] == 0) { Floor0 *g = &f->floor_config[i].floor0; g->order = get_bits(f,8); g->rate = get_bits(f,16); g->bark_map_size = get_bits(f,16); g->amplitude_bits = get_bits(f,6); g->amplitude_offset = get_bits(f,8); g->number_of_books = get_bits(f,4) + 1; for (j=0; j < g->number_of_books; ++j) g->book_list[j] = get_bits(f,8); return error(f, VORBIS_feature_not_supported); } else { stbv__floor_ordering p[31*8+2]; Floor1 *g = &f->floor_config[i].floor1; int max_class = -1; g->partitions = get_bits(f, 5); for (j=0; j < g->partitions; ++j) { g->partition_class_list[j] = get_bits(f, 4); if (g->partition_class_list[j] > max_class) max_class = g->partition_class_list[j]; } for (j=0; j <= max_class; ++j) { g->class_dimensions[j] = get_bits(f, 3)+1; g->class_subclasses[j] = get_bits(f, 2); if (g->class_subclasses[j]) { g->class_masterbooks[j] = get_bits(f, 8); if (g->class_masterbooks[j] >= f->codebook_count) return error(f, VORBIS_invalid_setup); } for (k=0; k < 1 << g->class_subclasses[j]; ++k) { g->subclass_books[j][k] = get_bits(f,8)-1; if (g->subclass_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); } } g->floor1_multiplier = get_bits(f,2)+1; g->rangebits = get_bits(f,4); g->Xlist[0] = 0; g->Xlist[1] = 1 << g->rangebits; g->values = 2; for (j=0; j < g->partitions; ++j) { int c = g->partition_class_list[j]; for (k=0; k < g->class_dimensions[c]; ++k) { g->Xlist[g->values] = get_bits(f, g->rangebits); ++g->values; } } // precompute the sorting for (j=0; j < g->values; ++j) { p[j].x = g->Xlist[j]; p[j].id = j; } qsort(p, g->values, sizeof(p[0]), point_compare); for (j=0; j < g->values; ++j) g->sorted_order[j] = (uint8) p[j].id; // precompute the neighbors for (j=2; j < g->values; ++j) { int low,hi; neighbors(g->Xlist, j, &low,&hi); g->neighbors[j][0] = low; g->neighbors[j][1] = hi; } if (g->values > longest_floorlist) longest_floorlist = g->values; } } // Residue f->residue_count = get_bits(f, 6)+1; f->residue_config = (Residue *) setup_malloc(f, f->residue_count * sizeof(f->residue_config[0])); if (f->residue_config == NULL) return error(f, VORBIS_outofmem); memset(f->residue_config, 0, f->residue_count * sizeof(f->residue_config[0])); for (i=0; i < f->residue_count; ++i) { uint8 residue_cascade[64]; Residue *r = f->residue_config+i; f->residue_types[i] = get_bits(f, 16); if (f->residue_types[i] > 2) return error(f, VORBIS_invalid_setup); r->begin = get_bits(f, 24); r->end = get_bits(f, 24); if (r->end < r->begin) return error(f, VORBIS_invalid_setup); r->part_size = get_bits(f,24)+1; r->classifications = get_bits(f,6)+1; r->classbook = get_bits(f,8); if (r->classbook >= f->codebook_count) return error(f, VORBIS_invalid_setup); for (j=0; j < r->classifications; ++j) { uint8 high_bits=0; uint8 low_bits=get_bits(f,3); if (get_bits(f,1)) high_bits = get_bits(f,5); residue_cascade[j] = high_bits*8 + low_bits; } r->residue_books = (short (*)[8]) setup_malloc(f, sizeof(r->residue_books[0]) * r->classifications); if (r->residue_books == NULL) return error(f, VORBIS_outofmem); for (j=0; j < r->classifications; ++j) { for (k=0; k < 8; ++k) { if (residue_cascade[j] & (1 << k)) { r->residue_books[j][k] = get_bits(f, 8); if (r->residue_books[j][k] >= f->codebook_count) return error(f, VORBIS_invalid_setup); } else { r->residue_books[j][k] = -1; } } } // precompute the classifications[] array to avoid inner-loop mod/divide // call it 'classdata' since we already have r->classifications r->classdata = (uint8 **) setup_malloc(f, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); if (!r->classdata) return error(f, VORBIS_outofmem); memset(r->classdata, 0, sizeof(*r->classdata) * f->codebooks[r->classbook].entries); for (j=0; j < f->codebooks[r->classbook].entries; ++j) { int classwords = f->codebooks[r->classbook].dimensions; int temp = j; r->classdata[j] = (uint8 *) setup_malloc(f, sizeof(r->classdata[j][0]) * classwords); if (r->classdata[j] == NULL) return error(f, VORBIS_outofmem); for (k=classwords-1; k >= 0; --k) { r->classdata[j][k] = temp % r->classifications; temp /= r->classifications; } } } f->mapping_count = get_bits(f,6)+1; f->mapping = (Mapping *) setup_malloc(f, f->mapping_count * sizeof(*f->mapping)); if (f->mapping == NULL) return error(f, VORBIS_outofmem); memset(f->mapping, 0, f->mapping_count * sizeof(*f->mapping)); for (i=0; i < f->mapping_count; ++i) { Mapping *m = f->mapping + i; int mapping_type = get_bits(f,16); if (mapping_type != 0) return error(f, VORBIS_invalid_setup); m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan)); if (m->chan == NULL) return error(f, VORBIS_outofmem); if (get_bits(f,1)) m->submaps = get_bits(f,4)+1; else m->submaps = 1; if (m->submaps > max_submaps) max_submaps = m->submaps; if (get_bits(f,1)) { m->coupling_steps = get_bits(f,8)+1; for (k=0; k < m->coupling_steps; ++k) { m->chan[k].magnitude = get_bits(f, ilog(f->channels-1)); m->chan[k].angle = get_bits(f, ilog(f->channels-1)); if (m->chan[k].magnitude >= f->channels) return error(f, VORBIS_invalid_setup); if (m->chan[k].angle >= f->channels) return error(f, VORBIS_invalid_setup); if (m->chan[k].magnitude == m->chan[k].angle) return error(f, VORBIS_invalid_setup); } } else m->coupling_steps = 0; // reserved field if (get_bits(f,2)) return error(f, VORBIS_invalid_setup); if (m->submaps > 1) { for (j=0; j < f->channels; ++j) { m->chan[j].mux = get_bits(f, 4); if (m->chan[j].mux >= m->submaps) return error(f, VORBIS_invalid_setup); } } else // @SPECIFICATION: this case is missing from the spec for (j=0; j < f->channels; ++j) m->chan[j].mux = 0; for (j=0; j < m->submaps; ++j) { get_bits(f,8); // discard m->submap_floor[j] = get_bits(f,8); m->submap_residue[j] = get_bits(f,8); if (m->submap_floor[j] >= f->floor_count) return error(f, VORBIS_invalid_setup); if (m->submap_residue[j] >= f->residue_count) return error(f, VORBIS_invalid_setup); } } // Modes f->mode_count = get_bits(f, 6)+1; for (i=0; i < f->mode_count; ++i) { Mode *m = f->mode_config+i; m->blockflag = get_bits(f,1); m->windowtype = get_bits(f,16); m->transformtype = get_bits(f,16); m->mapping = get_bits(f,8); if (m->windowtype != 0) return error(f, VORBIS_invalid_setup); if (m->transformtype != 0) return error(f, VORBIS_invalid_setup); if (m->mapping >= f->mapping_count) return error(f, VORBIS_invalid_setup); } flush_packet(f); f->previous_length = 0; for (i=0; i < f->channels; ++i) { f->channel_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1); f->previous_window[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); f->finalY[i] = (int16 *) setup_malloc(f, sizeof(int16) * longest_floorlist); if (f->channel_buffers[i] == NULL || f->previous_window[i] == NULL || f->finalY[i] == NULL) return error(f, VORBIS_outofmem); #ifdef STB_VORBIS_NO_DEFER_FLOOR f->floor_buffers[i] = (float *) setup_malloc(f, sizeof(float) * f->blocksize_1/2); if (f->floor_buffers[i] == NULL) return error(f, VORBIS_outofmem); #endif } if (!init_blocksize(f, 0, f->blocksize_0)) return FALSE; if (!init_blocksize(f, 1, f->blocksize_1)) return FALSE; f->blocksize[0] = f->blocksize_0; f->blocksize[1] = f->blocksize_1; #ifdef STB_VORBIS_DIVIDE_TABLE if (integer_divide_table[1][1]==0) for (i=0; i < DIVTAB_NUMER; ++i) for (j=1; j < DIVTAB_DENOM; ++j) integer_divide_table[i][j] = i / j; #endif // compute how much temporary memory is needed // 1. { uint32 imdct_mem = (f->blocksize_1 * sizeof(float) >> 1); uint32 classify_mem; int i,max_part_read=0; for (i=0; i < f->residue_count; ++i) { Residue *r = f->residue_config + i; int n_read = r->end - r->begin; int part_read = n_read / r->part_size; if (part_read > max_part_read) max_part_read = part_read; } #ifndef STB_VORBIS_DIVIDES_IN_RESIDUE classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(uint8 *)); #else classify_mem = f->channels * (sizeof(void*) + max_part_read * sizeof(int *)); #endif f->temp_memory_required = classify_mem; if (imdct_mem > f->temp_memory_required) f->temp_memory_required = imdct_mem; } f->first_decode = TRUE; if (f->alloc.alloc_buffer) { assert(f->temp_offset == f->alloc.alloc_buffer_length_in_bytes); // check if there's enough temp memory so we don't error later if (f->setup_offset + sizeof(*f) + f->temp_memory_required > (unsigned) f->temp_offset) return error(f, VORBIS_outofmem); } f->first_audio_page_offset = stb_vorbis_get_file_offset(f); return TRUE; } static void vorbis_deinit(stb_vorbis *p) { int i,j; if (p->residue_config) { for (i=0; i < p->residue_count; ++i) { Residue *r = p->residue_config+i; if (r->classdata) { for (j=0; j < p->codebooks[r->classbook].entries; ++j) setup_free(p, r->classdata[j]); setup_free(p, r->classdata); } setup_free(p, r->residue_books); } } if (p->codebooks) { CHECK(p); for (i=0; i < p->codebook_count; ++i) { Codebook *c = p->codebooks + i; setup_free(p, c->codeword_lengths); setup_free(p, c->multiplicands); setup_free(p, c->codewords); setup_free(p, c->sorted_codewords); // c->sorted_values[-1] is the first entry in the array setup_free(p, c->sorted_values ? c->sorted_values-1 : NULL); } setup_free(p, p->codebooks); } setup_free(p, p->floor_config); setup_free(p, p->residue_config); if (p->mapping) { for (i=0; i < p->mapping_count; ++i) setup_free(p, p->mapping[i].chan); setup_free(p, p->mapping); } CHECK(p); for (i=0; i < p->channels && i < STB_VORBIS_MAX_CHANNELS; ++i) { setup_free(p, p->channel_buffers[i]); setup_free(p, p->previous_window[i]); #ifdef STB_VORBIS_NO_DEFER_FLOOR setup_free(p, p->floor_buffers[i]); #endif setup_free(p, p->finalY[i]); } for (i=0; i < 2; ++i) { setup_free(p, p->A[i]); setup_free(p, p->B[i]); setup_free(p, p->C[i]); setup_free(p, p->window[i]); setup_free(p, p->bit_reverse[i]); } #ifndef STB_VORBIS_NO_STDIO if (p->close_on_free) fclose(p->f); #endif } void stb_vorbis_close(stb_vorbis *p) { if (p == NULL) return; vorbis_deinit(p); setup_free(p,p); } static void vorbis_init(stb_vorbis *p, const stb_vorbis_alloc *z) { memset(p, 0, sizeof(*p)); // NULL out all malloc'd pointers to start if (z) { p->alloc = *z; p->alloc.alloc_buffer_length_in_bytes = (p->alloc.alloc_buffer_length_in_bytes+3) & ~3; p->temp_offset = p->alloc.alloc_buffer_length_in_bytes; } p->eof = 0; p->error = VORBIS__no_error; p->stream = NULL; p->codebooks = NULL; p->page_crc_tests = -1; #ifndef STB_VORBIS_NO_STDIO p->close_on_free = FALSE; p->f = NULL; #endif } int stb_vorbis_get_sample_offset(stb_vorbis *f) { if (f->current_loc_valid) return f->current_loc; else return -1; } stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f) { stb_vorbis_info d; d.channels = f->channels; d.sample_rate = f->sample_rate; d.setup_memory_required = f->setup_memory_required; d.setup_temp_memory_required = f->setup_temp_memory_required; d.temp_memory_required = f->temp_memory_required; d.max_frame_size = f->blocksize_1 >> 1; return d; } int stb_vorbis_get_error(stb_vorbis *f) { int e = f->error; f->error = VORBIS__no_error; return e; } static stb_vorbis * vorbis_alloc(stb_vorbis *f) { stb_vorbis *p = (stb_vorbis *) setup_malloc(f, sizeof(*p)); return p; } #ifndef STB_VORBIS_NO_PUSHDATA_API void stb_vorbis_flush_pushdata(stb_vorbis *f) { f->previous_length = 0; f->page_crc_tests = 0; f->discard_samples_deferred = 0; f->current_loc_valid = FALSE; f->first_decode = FALSE; f->samples_output = 0; f->channel_buffer_start = 0; f->channel_buffer_end = 0; } static int vorbis_search_for_page_pushdata(vorb *f, uint8 *data, int data_len) { int i,n; for (i=0; i < f->page_crc_tests; ++i) f->scan[i].bytes_done = 0; // if we have room for more scans, search for them first, because // they may cause us to stop early if their header is incomplete if (f->page_crc_tests < STB_VORBIS_PUSHDATA_CRC_COUNT) { if (data_len < 4) return 0; data_len -= 3; // need to look for 4-byte sequence, so don't miss // one that straddles a boundary for (i=0; i < data_len; ++i) { if (data[i] == 0x4f) { if (0==memcmp(data+i, ogg_page_header, 4)) { int j,len; uint32 crc; // make sure we have the whole page header if (i+26 >= data_len || i+27+data[i+26] >= data_len) { // only read up to this page start, so hopefully we'll // have the whole page header start next time data_len = i; break; } // ok, we have it all; compute the length of the page len = 27 + data[i+26]; for (j=0; j < data[i+26]; ++j) len += data[i+27+j]; // scan everything up to the embedded crc (which we must 0) crc = 0; for (j=0; j < 22; ++j) crc = crc32_update(crc, data[i+j]); // now process 4 0-bytes for ( ; j < 26; ++j) crc = crc32_update(crc, 0); // len is the total number of bytes we need to scan n = f->page_crc_tests++; f->scan[n].bytes_left = len-j; f->scan[n].crc_so_far = crc; f->scan[n].goal_crc = data[i+22] + (data[i+23] << 8) + (data[i+24]<<16) + (data[i+25]<<24); // if the last frame on a page is continued to the next, then // we can't recover the sample_loc immediately if (data[i+27+data[i+26]-1] == 255) f->scan[n].sample_loc = ~0; else f->scan[n].sample_loc = data[i+6] + (data[i+7] << 8) + (data[i+ 8]<<16) + (data[i+ 9]<<24); f->scan[n].bytes_done = i+j; if (f->page_crc_tests == STB_VORBIS_PUSHDATA_CRC_COUNT) break; // keep going if we still have room for more } } } } for (i=0; i < f->page_crc_tests;) { uint32 crc; int j; int n = f->scan[i].bytes_done; int m = f->scan[i].bytes_left; if (m > data_len - n) m = data_len - n; // m is the bytes to scan in the current chunk crc = f->scan[i].crc_so_far; for (j=0; j < m; ++j) crc = crc32_update(crc, data[n+j]); f->scan[i].bytes_left -= m; f->scan[i].crc_so_far = crc; if (f->scan[i].bytes_left == 0) { // does it match? if (f->scan[i].crc_so_far == f->scan[i].goal_crc) { // Houston, we have page data_len = n+m; // consumption amount is wherever that scan ended f->page_crc_tests = -1; // drop out of page scan mode f->previous_length = 0; // decode-but-don't-output one frame f->next_seg = -1; // start a new page f->current_loc = f->scan[i].sample_loc; // set the current sample location // to the amount we'd have decoded had we decoded this page f->current_loc_valid = f->current_loc != ~0U; return data_len; } // delete entry f->scan[i] = f->scan[--f->page_crc_tests]; } else { ++i; } } return data_len; } // return value: number of bytes we used int stb_vorbis_decode_frame_pushdata( stb_vorbis *f, // the file we're decoding const uint8 *data, int data_len, // the memory available for decoding int *channels, // place to write number of float * buffers float ***output, // place to write float ** array of float * buffers int *samples // place to write number of output samples ) { int i; int len,right,left; if (!IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); if (f->page_crc_tests >= 0) { *samples = 0; return vorbis_search_for_page_pushdata(f, (uint8 *) data, data_len); } f->stream = (uint8 *) data; f->stream_end = (uint8 *) data + data_len; f->error = VORBIS__no_error; // check that we have the entire packet in memory if (!is_whole_packet_present(f, FALSE)) { *samples = 0; return 0; } if (!vorbis_decode_packet(f, &len, &left, &right)) { // save the actual error we encountered enum STBVorbisError error = f->error; if (error == VORBIS_bad_packet_type) { // flush and resynch f->error = VORBIS__no_error; while (get8_packet(f) != EOP) if (f->eof) break; *samples = 0; return (int) (f->stream - data); } if (error == VORBIS_continued_packet_flag_invalid) { if (f->previous_length == 0) { // we may be resynching, in which case it's ok to hit one // of these; just discard the packet f->error = VORBIS__no_error; while (get8_packet(f) != EOP) if (f->eof) break; *samples = 0; return (int) (f->stream - data); } } // if we get an error while parsing, what to do? // well, it DEFINITELY won't work to continue from where we are! stb_vorbis_flush_pushdata(f); // restore the error that actually made us bail f->error = error; *samples = 0; return 1; } // success! len = vorbis_finish_frame(f, len, left, right); for (i=0; i < f->channels; ++i) f->outputs[i] = f->channel_buffers[i] + left; if (channels) *channels = f->channels; *samples = len; *output = f->outputs; return (int) (f->stream - data); } stb_vorbis *stb_vorbis_open_pushdata( const unsigned char *data, int data_len, // the memory available for decoding int *data_used, // only defined if result is not NULL int *error, const stb_vorbis_alloc *alloc) { stb_vorbis *f, p; vorbis_init(&p, alloc); p.stream = (uint8 *) data; p.stream_end = (uint8 *) data + data_len; p.push_mode = TRUE; if (!start_decoder(&p)) { if (p.eof) *error = VORBIS_need_more_data; else *error = p.error; return NULL; } f = vorbis_alloc(&p); if (f) { *f = p; *data_used = (int) (f->stream - data); *error = 0; return f; } else { vorbis_deinit(&p); return NULL; } } #endif // STB_VORBIS_NO_PUSHDATA_API unsigned int stb_vorbis_get_file_offset(stb_vorbis *f) { #ifndef STB_VORBIS_NO_PUSHDATA_API if (f->push_mode) return 0; #endif if (USE_MEMORY(f)) return (unsigned int) (f->stream - f->stream_start); #ifndef STB_VORBIS_NO_STDIO return (unsigned int) (ftell(f->f) - f->f_start); #endif } #ifndef STB_VORBIS_NO_PULLDATA_API // // DATA-PULLING API // static uint32 vorbis_find_page(stb_vorbis *f, uint32 *end, uint32 *last) { for(;;) { int n; if (f->eof) return 0; n = get8(f); if (n == 0x4f) { // page header candidate unsigned int retry_loc = stb_vorbis_get_file_offset(f); int i; // check if we're off the end of a file_section stream if (retry_loc - 25 > f->stream_len) return 0; // check the rest of the header for (i=1; i < 4; ++i) if (get8(f) != ogg_page_header[i]) break; if (f->eof) return 0; if (i == 4) { uint8 header[27]; uint32 i, crc, goal, len; for (i=0; i < 4; ++i) header[i] = ogg_page_header[i]; for (; i < 27; ++i) header[i] = get8(f); if (f->eof) return 0; if (header[4] != 0) goto invalid; goal = header[22] + (header[23] << 8) + (header[24]<<16) + (header[25]<<24); for (i=22; i < 26; ++i) header[i] = 0; crc = 0; for (i=0; i < 27; ++i) crc = crc32_update(crc, header[i]); len = 0; for (i=0; i < header[26]; ++i) { int s = get8(f); crc = crc32_update(crc, s); len += s; } if (len && f->eof) return 0; for (i=0; i < len; ++i) crc = crc32_update(crc, get8(f)); // finished parsing probable page if (crc == goal) { // we could now check that it's either got the last // page flag set, OR it's followed by the capture // pattern, but I guess TECHNICALLY you could have // a file with garbage between each ogg page and recover // from it automatically? So even though that paranoia // might decrease the chance of an invalid decode by // another 2^32, not worth it since it would hose those // invalid-but-useful files? if (end) *end = stb_vorbis_get_file_offset(f); if (last) { if (header[5] & 0x04) *last = 1; else *last = 0; } set_file_offset(f, retry_loc-1); return 1; } } invalid: // not a valid page, so rewind and look for next one set_file_offset(f, retry_loc); } } } #define SAMPLE_unknown 0xffffffff // seeking is implemented with a binary search, which narrows down the range to // 64K, before using a linear search (because finding the synchronization // pattern can be expensive, and the chance we'd find the end page again is // relatively high for small ranges) // // two initial interpolation-style probes are used at the start of the search // to try to bound either side of the binary search sensibly, while still // working in O(log n) time if they fail. static int get_seek_page_info(stb_vorbis *f, ProbedPage *z) { uint8 header[27], lacing[255]; int i,len; // record where the page starts z->page_start = stb_vorbis_get_file_offset(f); // parse the header getn(f, header, 27); if (header[0] != 'O' || header[1] != 'g' || header[2] != 'g' || header[3] != 'S') return 0; getn(f, lacing, header[26]); // determine the length of the payload len = 0; for (i=0; i < header[26]; ++i) len += lacing[i]; // this implies where the page ends z->page_end = z->page_start + 27 + header[26] + len; // read the last-decoded sample out of the data z->last_decoded_sample = header[6] + (header[7] << 8) + (header[8] << 16) + (header[9] << 24); // restore file state to where we were set_file_offset(f, z->page_start); return 1; } // rarely used function to seek back to the preceeding page while finding the // start of a packet static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset) { unsigned int previous_safe, end; // now we want to seek back 64K from the limit if (limit_offset >= 65536 && limit_offset-65536 >= f->first_audio_page_offset) previous_safe = limit_offset - 65536; else previous_safe = f->first_audio_page_offset; set_file_offset(f, previous_safe); while (vorbis_find_page(f, &end, NULL)) { if (end >= limit_offset && stb_vorbis_get_file_offset(f) < limit_offset) return 1; set_file_offset(f, end); } return 0; } // implements the search logic for finding a page and starting decoding. if // the function succeeds, current_loc_valid will be true and current_loc will // be less than or equal to the provided sample number (the closer the // better). static int seek_to_sample_coarse(stb_vorbis *f, uint32 sample_number) { ProbedPage left, right, mid; int i, start_seg_with_known_loc, end_pos, page_start; uint32 delta, stream_length, padding; double offset, bytes_per_sample; int probe = 0; // find the last page and validate the target sample stream_length = stb_vorbis_stream_length_in_samples(f); if (stream_length == 0) return error(f, VORBIS_seek_without_length); if (sample_number > stream_length) return error(f, VORBIS_seek_invalid); // this is the maximum difference between the window-center (which is the // actual granule position value), and the right-start (which the spec // indicates should be the granule position (give or take one)). padding = ((f->blocksize_1 - f->blocksize_0) >> 2); if (sample_number < padding) sample_number = 0; else sample_number -= padding; left = f->p_first; while (left.last_decoded_sample == ~0U) { // (untested) the first page does not have a 'last_decoded_sample' set_file_offset(f, left.page_end); if (!get_seek_page_info(f, &left)) goto error; } right = f->p_last; assert(right.last_decoded_sample != ~0U); // starting from the start is handled differently if (sample_number <= left.last_decoded_sample) { if (stb_vorbis_seek_start(f)) return 1; return 0; } while (left.page_end != right.page_start) { assert(left.page_end < right.page_start); // search range in bytes delta = right.page_start - left.page_end; if (delta <= 65536) { // there's only 64K left to search - handle it linearly set_file_offset(f, left.page_end); } else { if (probe < 2) { if (probe == 0) { // first probe (interpolate) double data_bytes = right.page_end - left.page_start; bytes_per_sample = data_bytes / right.last_decoded_sample; offset = left.page_start + bytes_per_sample * (sample_number - left.last_decoded_sample); } else { // second probe (try to bound the other side) double error = ((double) sample_number - mid.last_decoded_sample) * bytes_per_sample; if (error >= 0 && error < 8000) error = 8000; if (error < 0 && error > -8000) error = -8000; offset += error * 2; } // ensure the offset is valid if (offset < left.page_end) offset = left.page_end; if (offset > right.page_start - 65536) offset = right.page_start - 65536; set_file_offset(f, (unsigned int) offset); } else { // binary search for large ranges (offset by 32K to ensure // we don't hit the right page) set_file_offset(f, left.page_end + (delta / 2) - 32768); } if (!vorbis_find_page(f, NULL, NULL)) goto error; } for (;;) { if (!get_seek_page_info(f, &mid)) goto error; if (mid.last_decoded_sample != ~0U) break; // (untested) no frames end on this page set_file_offset(f, mid.page_end); assert(mid.page_start < right.page_start); } // if we've just found the last page again then we're in a tricky file, // and we're close enough. if (mid.page_start == right.page_start) break; if (sample_number < mid.last_decoded_sample) right = mid; else left = mid; ++probe; } // seek back to start of the last packet page_start = left.page_start; set_file_offset(f, page_start); if (!start_page(f)) return error(f, VORBIS_seek_failed); end_pos = f->end_seg_with_known_loc; assert(end_pos >= 0); for (;;) { for (i = end_pos; i > 0; --i) if (f->segments[i-1] != 255) break; start_seg_with_known_loc = i; if (start_seg_with_known_loc > 0 || !(f->page_flag & PAGEFLAG_continued_packet)) break; // (untested) the final packet begins on an earlier page if (!go_to_page_before(f, page_start)) goto error; page_start = stb_vorbis_get_file_offset(f); if (!start_page(f)) goto error; end_pos = f->segment_count - 1; } // prepare to start decoding f->current_loc_valid = FALSE; f->last_seg = FALSE; f->valid_bits = 0; f->packet_bytes = 0; f->bytes_in_seg = 0; f->previous_length = 0; f->next_seg = start_seg_with_known_loc; for (i = 0; i < start_seg_with_known_loc; i++) skip(f, f->segments[i]); // start decoding (optimizable - this frame is generally discarded) if (!vorbis_pump_first_frame(f)) return 0; if (f->current_loc > sample_number) return error(f, VORBIS_seek_failed); return 1; error: // try to restore the file to a valid state stb_vorbis_seek_start(f); return error(f, VORBIS_seek_failed); } // the same as vorbis_decode_initial, but without advancing static int peek_decode_initial(vorb *f, int *p_left_start, int *p_left_end, int *p_right_start, int *p_right_end, int *mode) { int bits_read, bytes_read; if (!vorbis_decode_initial(f, p_left_start, p_left_end, p_right_start, p_right_end, mode)) return 0; // either 1 or 2 bytes were read, figure out which so we can rewind bits_read = 1 + ilog(f->mode_count-1); if (f->mode_config[*mode].blockflag) bits_read += 2; bytes_read = (bits_read + 7) / 8; f->bytes_in_seg += bytes_read; f->packet_bytes -= bytes_read; skip(f, -bytes_read); if (f->next_seg == -1) f->next_seg = f->segment_count - 1; else f->next_seg--; f->valid_bits = 0; return 1; } int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number) { uint32 max_frame_samples; if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); // fast page-level search if (!seek_to_sample_coarse(f, sample_number)) return 0; assert(f->current_loc_valid); assert(f->current_loc <= sample_number); // linear search for the relevant packet max_frame_samples = (f->blocksize_1*3 - f->blocksize_0) >> 2; while (f->current_loc < sample_number) { int left_start, left_end, right_start, right_end, mode, frame_samples; if (!peek_decode_initial(f, &left_start, &left_end, &right_start, &right_end, &mode)) return error(f, VORBIS_seek_failed); // calculate the number of samples returned by the next frame frame_samples = right_start - left_start; if (f->current_loc + frame_samples > sample_number) { return 1; // the next frame will contain the sample } else if (f->current_loc + frame_samples + max_frame_samples > sample_number) { // there's a chance the frame after this could contain the sample vorbis_pump_first_frame(f); } else { // this frame is too early to be relevant f->current_loc += frame_samples; f->previous_length = 0; maybe_start_packet(f); flush_packet(f); } } // the next frame will start with the sample assert(f->current_loc == sample_number); return 1; } int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number) { if (!stb_vorbis_seek_frame(f, sample_number)) return 0; if (sample_number != f->current_loc) { int n; uint32 frame_start = f->current_loc; stb_vorbis_get_frame_float(f, &n, NULL); assert(sample_number > frame_start); assert(f->channel_buffer_start + (int) (sample_number-frame_start) <= f->channel_buffer_end); f->channel_buffer_start += (sample_number - frame_start); } return 1; } int stb_vorbis_seek_start(stb_vorbis *f) { if (IS_PUSH_MODE(f)) { return error(f, VORBIS_invalid_api_mixing); } set_file_offset(f, f->first_audio_page_offset); f->previous_length = 0; f->first_decode = TRUE; f->next_seg = -1; return vorbis_pump_first_frame(f); } unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) { unsigned int restore_offset, previous_safe; unsigned int end, last_page_loc; if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); if (!f->total_samples) { unsigned int last; uint32 lo,hi; char header[6]; // first, store the current decode position so we can restore it restore_offset = stb_vorbis_get_file_offset(f); // now we want to seek back 64K from the end (the last page must // be at most a little less than 64K, but let's allow a little slop) if (f->stream_len >= 65536 && f->stream_len-65536 >= f->first_audio_page_offset) previous_safe = f->stream_len - 65536; else previous_safe = f->first_audio_page_offset; set_file_offset(f, previous_safe); // previous_safe is now our candidate 'earliest known place that seeking // to will lead to the final page' if (!vorbis_find_page(f, &end, &last)) { // if we can't find a page, we're hosed! f->error = VORBIS_cant_find_last_page; f->total_samples = 0xffffffff; goto done; } // check if there are more pages last_page_loc = stb_vorbis_get_file_offset(f); // stop when the last_page flag is set, not when we reach eof; // this allows us to stop short of a 'file_section' end without // explicitly checking the length of the section while (!last) { set_file_offset(f, end); if (!vorbis_find_page(f, &end, &last)) { // the last page we found didn't have the 'last page' flag // set. whoops! break; } previous_safe = last_page_loc+1; last_page_loc = stb_vorbis_get_file_offset(f); } set_file_offset(f, last_page_loc); // parse the header getn(f, (unsigned char *)header, 6); // extract the absolute granule position lo = get32(f); hi = get32(f); if (lo == 0xffffffff && hi == 0xffffffff) { f->error = VORBIS_cant_find_last_page; f->total_samples = SAMPLE_unknown; goto done; } if (hi) lo = 0xfffffffe; // saturate f->total_samples = lo; f->p_last.page_start = last_page_loc; f->p_last.page_end = end; f->p_last.last_decoded_sample = lo; done: set_file_offset(f, restore_offset); } return f->total_samples == SAMPLE_unknown ? 0 : f->total_samples; } float stb_vorbis_stream_length_in_seconds(stb_vorbis *f) { return stb_vorbis_stream_length_in_samples(f) / (float) f->sample_rate; } int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output) { int len, right,left,i; if (IS_PUSH_MODE(f)) return error(f, VORBIS_invalid_api_mixing); if (!vorbis_decode_packet(f, &len, &left, &right)) { f->channel_buffer_start = f->channel_buffer_end = 0; return 0; } len = vorbis_finish_frame(f, len, left, right); for (i=0; i < f->channels; ++i) f->outputs[i] = f->channel_buffers[i] + left; f->channel_buffer_start = left; f->channel_buffer_end = left+len; if (channels) *channels = f->channels; if (output) *output = f->outputs; return len; } #ifndef STB_VORBIS_NO_STDIO stb_vorbis * stb_vorbis_open_file_section(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc, unsigned int length) { stb_vorbis *f, p; vorbis_init(&p, alloc); p.f = file; p.f_start = (uint32) ftell(file); p.stream_len = length; p.close_on_free = close_on_free; if (start_decoder(&p)) { f = vorbis_alloc(&p); if (f) { *f = p; vorbis_pump_first_frame(f); return f; } } if (error) *error = p.error; vorbis_deinit(&p); return NULL; } stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, const stb_vorbis_alloc *alloc) { unsigned int len, start; start = (unsigned int) ftell(file); fseek(file, 0, SEEK_END); len = (unsigned int) (ftell(file) - start); fseek(file, start, SEEK_SET); return stb_vorbis_open_file_section(file, close_on_free, error, alloc, len); } stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) { FILE *f = fopen(filename, "rb"); if (f) return stb_vorbis_open_file(f, TRUE, error, alloc); if (error) *error = VORBIS_file_open_failure; return NULL; } #endif // STB_VORBIS_NO_STDIO stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc) { stb_vorbis *f, p; if (data == NULL) return NULL; vorbis_init(&p, alloc); p.stream = (uint8 *) data; p.stream_end = (uint8 *) data + len; p.stream_start = (uint8 *) p.stream; p.stream_len = len; p.push_mode = FALSE; if (start_decoder(&p)) { f = vorbis_alloc(&p); if (f) { *f = p; vorbis_pump_first_frame(f); if (error) *error = VORBIS__no_error; return f; } } if (error) *error = p.error; vorbis_deinit(&p); return NULL; } #ifndef STB_VORBIS_NO_INTEGER_CONVERSION #define PLAYBACK_MONO 1 #define PLAYBACK_LEFT 2 #define PLAYBACK_RIGHT 4 #define L (PLAYBACK_LEFT | PLAYBACK_MONO) #define C (PLAYBACK_LEFT | PLAYBACK_RIGHT | PLAYBACK_MONO) #define R (PLAYBACK_RIGHT | PLAYBACK_MONO) static int8 channel_position[7][6] = { { 0 }, { C }, { L, R }, { L, C, R }, { L, R, L, R }, { L, C, R, L, R }, { L, C, R, L, R, C }, }; #ifndef STB_VORBIS_NO_FAST_SCALED_FLOAT typedef union { float f; int i; } float_conv; typedef char stb_vorbis_float_size_test[sizeof(float)==4 && sizeof(int) == 4]; #define FASTDEF(x) float_conv x // add (1<<23) to convert to int, then divide by 2^SHIFT, then add 0.5/2^SHIFT to round #define MAGIC(SHIFT) (1.5f * (1 << (23-SHIFT)) + 0.5f/(1 << SHIFT)) #define ADDEND(SHIFT) (((150-SHIFT) << 23) + (1 << 22)) #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) (temp.f = (x) + MAGIC(s), temp.i - ADDEND(s)) #define check_endianness() #else #define FAST_SCALED_FLOAT_TO_INT(temp,x,s) ((int) ((x) * (1 << (s)))) #define check_endianness() #define FASTDEF(x) #endif static void copy_samples(short *dest, float *src, int len) { int i; check_endianness(); for (i=0; i < len; ++i) { FASTDEF(temp); int v = FAST_SCALED_FLOAT_TO_INT(temp, src[i],15); if ((unsigned int) (v + 32768) > 65535) v = v < 0 ? -32768 : 32767; dest[i] = v; } } static void compute_samples(int mask, short *output, int num_c, float **data, int d_offset, int len) { #define BUFFER_SIZE 32 float buffer[BUFFER_SIZE]; int i,j,o,n = BUFFER_SIZE; check_endianness(); for (o = 0; o < len; o += BUFFER_SIZE) { memset(buffer, 0, sizeof(buffer)); if (o + n > len) n = len - o; for (j=0; j < num_c; ++j) { if (channel_position[num_c][j] & mask) { for (i=0; i < n; ++i) buffer[i] += data[j][d_offset+o+i]; } } for (i=0; i < n; ++i) { FASTDEF(temp); int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); if ((unsigned int) (v + 32768) > 65535) v = v < 0 ? -32768 : 32767; output[o+i] = v; } } } static void compute_stereo_samples(short *output, int num_c, float **data, int d_offset, int len) { #define BUFFER_SIZE 32 float buffer[BUFFER_SIZE]; int i,j,o,n = BUFFER_SIZE >> 1; // o is the offset in the source data check_endianness(); for (o = 0; o < len; o += BUFFER_SIZE >> 1) { // o2 is the offset in the output data int o2 = o << 1; memset(buffer, 0, sizeof(buffer)); if (o + n > len) n = len - o; for (j=0; j < num_c; ++j) { int m = channel_position[num_c][j] & (PLAYBACK_LEFT | PLAYBACK_RIGHT); if (m == (PLAYBACK_LEFT | PLAYBACK_RIGHT)) { for (i=0; i < n; ++i) { buffer[i*2+0] += data[j][d_offset+o+i]; buffer[i*2+1] += data[j][d_offset+o+i]; } } else if (m == PLAYBACK_LEFT) { for (i=0; i < n; ++i) { buffer[i*2+0] += data[j][d_offset+o+i]; } } else if (m == PLAYBACK_RIGHT) { for (i=0; i < n; ++i) { buffer[i*2+1] += data[j][d_offset+o+i]; } } } for (i=0; i < (n<<1); ++i) { FASTDEF(temp); int v = FAST_SCALED_FLOAT_TO_INT(temp,buffer[i],15); if ((unsigned int) (v + 32768) > 65535) v = v < 0 ? -32768 : 32767; output[o2+i] = v; } } } static void convert_samples_short(int buf_c, short **buffer, int b_offset, int data_c, float **data, int d_offset, int samples) { int i; if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { static int channel_selector[3][2] = { {0}, {PLAYBACK_MONO}, {PLAYBACK_LEFT, PLAYBACK_RIGHT} }; for (i=0; i < buf_c; ++i) compute_samples(channel_selector[buf_c][i], buffer[i]+b_offset, data_c, data, d_offset, samples); } else { int limit = buf_c < data_c ? buf_c : data_c; for (i=0; i < limit; ++i) copy_samples(buffer[i]+b_offset, data[i]+d_offset, samples); for ( ; i < buf_c; ++i) memset(buffer[i]+b_offset, 0, sizeof(short) * samples); } } int stb_vorbis_get_frame_short(stb_vorbis *f, int num_c, short **buffer, int num_samples) { float **output; int len = stb_vorbis_get_frame_float(f, NULL, &output); if (len > num_samples) len = num_samples; if (len) convert_samples_short(num_c, buffer, 0, f->channels, output, 0, len); return len; } static void convert_channels_short_interleaved(int buf_c, short *buffer, int data_c, float **data, int d_offset, int len) { int i; check_endianness(); if (buf_c != data_c && buf_c <= 2 && data_c <= 6) { assert(buf_c == 2); for (i=0; i < buf_c; ++i) compute_stereo_samples(buffer, data_c, data, d_offset, len); } else { int limit = buf_c < data_c ? buf_c : data_c; int j; for (j=0; j < len; ++j) { for (i=0; i < limit; ++i) { FASTDEF(temp); float f = data[i][d_offset+j]; int v = FAST_SCALED_FLOAT_TO_INT(temp, f,15);//data[i][d_offset+j],15); if ((unsigned int) (v + 32768) > 65535) v = v < 0 ? -32768 : 32767; *buffer++ = v; } for ( ; i < buf_c; ++i) *buffer++ = 0; } } } int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts) { float **output; int len; if (num_c == 1) return stb_vorbis_get_frame_short(f,num_c,&buffer, num_shorts); len = stb_vorbis_get_frame_float(f, NULL, &output); if (len) { if (len*num_c > num_shorts) len = num_shorts / num_c; convert_channels_short_interleaved(num_c, buffer, f->channels, output, 0, len); } return len; } int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts) { float **outputs; int len = num_shorts / channels; int n=0; int z = f->channels; if (z > channels) z = channels; while (n < len) { int k = f->channel_buffer_end - f->channel_buffer_start; if (n+k >= len) k = len - n; if (k) convert_channels_short_interleaved(channels, buffer, f->channels, f->channel_buffers, f->channel_buffer_start, k); buffer += k*channels; n += k; f->channel_buffer_start += k; if (n == len) break; if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; } return n; } int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int len) { float **outputs; int n=0; int z = f->channels; if (z > channels) z = channels; while (n < len) { int k = f->channel_buffer_end - f->channel_buffer_start; if (n+k >= len) k = len - n; if (k) convert_samples_short(channels, buffer, n, f->channels, f->channel_buffers, f->channel_buffer_start, k); n += k; f->channel_buffer_start += k; if (n == len) break; if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; } return n; } #ifndef STB_VORBIS_NO_STDIO int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output) { int data_len, offset, total, limit, error; short *data; stb_vorbis *v = stb_vorbis_open_filename(filename, &error, NULL); if (v == NULL) return -1; limit = v->channels * 4096; *channels = v->channels; if (sample_rate) *sample_rate = v->sample_rate; offset = data_len = 0; total = limit; data = (short *) malloc(total * sizeof(*data)); if (data == NULL) { stb_vorbis_close(v); return -2; } for (;;) { int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset); if (n == 0) break; data_len += n; offset += n * v->channels; if (offset + limit > total) { short *data2; total *= 2; data2 = (short *) realloc(data, total * sizeof(*data)); if (data2 == NULL) { free(data); stb_vorbis_close(v); return -2; } data = data2; } } *output = data; stb_vorbis_close(v); return data_len; } #endif // NO_STDIO int stb_vorbis_decode_memory(const uint8 *mem, int len, int *channels, int *sample_rate, short **output) { int data_len, offset, total, limit, error; short *data; stb_vorbis *v = stb_vorbis_open_memory(mem, len, &error, NULL); if (v == NULL) return -1; limit = v->channels * 4096; *channels = v->channels; if (sample_rate) *sample_rate = v->sample_rate; offset = data_len = 0; total = limit; data = (short *) malloc(total * sizeof(*data)); if (data == NULL) { stb_vorbis_close(v); return -2; } for (;;) { int n = stb_vorbis_get_frame_short_interleaved(v, v->channels, data+offset, total-offset); if (n == 0) break; data_len += n; offset += n * v->channels; if (offset + limit > total) { short *data2; total *= 2; data2 = (short *) realloc(data, total * sizeof(*data)); if (data2 == NULL) { free(data); stb_vorbis_close(v); return -2; } data = data2; } } *output = data; stb_vorbis_close(v); return data_len; } #endif // STB_VORBIS_NO_INTEGER_CONVERSION int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats) { float **outputs; int len = num_floats / channels; int n=0; int z = f->channels; if (z > channels) z = channels; while (n < len) { int i,j; int k = f->channel_buffer_end - f->channel_buffer_start; if (n+k >= len) k = len - n; for (j=0; j < k; ++j) { for (i=0; i < z; ++i) *buffer++ = f->channel_buffers[i][f->channel_buffer_start+j]; for ( ; i < channels; ++i) *buffer++ = 0; } n += k; f->channel_buffer_start += k; if (n == len) break; if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; } return n; } int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples) { float **outputs; int n=0; int z = f->channels; if (z > channels) z = channels; while (n < num_samples) { int i; int k = f->channel_buffer_end - f->channel_buffer_start; if (n+k >= num_samples) k = num_samples - n; if (k) { for (i=0; i < z; ++i) memcpy(buffer[i]+n, f->channel_buffers[i]+f->channel_buffer_start, sizeof(float)*k); for ( ; i < channels; ++i) memset(buffer[i]+n, 0, sizeof(float) * k); } n += k; f->channel_buffer_start += k; if (n == num_samples) break; if (!stb_vorbis_get_frame_float(f, NULL, &outputs)) break; } return n; } #endif // STB_VORBIS_NO_PULLDATA_API /* Version history 1.10 - 2017/03/03 - more robust seeking; fix negative ilog(); clear error in open_memory 1.09 - 2016/04/04 - back out 'avoid discarding last frame' fix from previous version 1.08 - 2016/04/02 - fixed multiple warnings; fix setup memory leaks; avoid discarding last frame of audio data 1.07 - 2015/01/16 - fixed some warnings, fix mingw, const-correct API some more crash fixes when out of memory or with corrupt files 1.06 - 2015/08/31 - full, correct support for seeking API (Dougall Johnson) some crash fixes when out of memory or with corrupt files 1.05 - 2015/04/19 - don't define __forceinline if it's redundant 1.04 - 2014/08/27 - fix missing const-correct case in API 1.03 - 2014/08/07 - Warning fixes 1.02 - 2014/07/09 - Declare qsort compare function _cdecl on windows 1.01 - 2014/06/18 - fix stb_vorbis_get_samples_float 1.0 - 2014/05/26 - fix memory leaks; fix warnings; fix bugs in multichannel (API change) report sample rate for decode-full-file funcs 0.99996 - bracket #include <malloc.h> for macintosh compilation by Laurent Gomila 0.99995 - use union instead of pointer-cast for fast-float-to-int to avoid alias-optimization problem 0.99994 - change fast-float-to-int to work in single-precision FPU mode, remove endian-dependence 0.99993 - remove assert that fired on legal files with empty tables 0.99992 - rewind-to-start 0.99991 - bugfix to stb_vorbis_get_samples_short by Bernhard Wodo 0.9999 - (should have been 0.99990) fix no-CRT support, compiling as C++ 0.9998 - add a full-decode function with a memory source 0.9997 - fix a bug in the read-from-FILE case in 0.9996 addition 0.9996 - query length of vorbis stream in samples/seconds 0.9995 - bugfix to another optimization that only happened in certain files 0.9994 - bugfix to one of the optimizations that caused significant (but inaudible?) errors 0.9993 - performance improvements; runs in 99% to 104% of time of reference implementation 0.9992 - performance improvement of IMDCT; now performs close to reference implementation 0.9991 - performance improvement of IMDCT 0.999 - (should have been 0.9990) performance improvement of IMDCT 0.998 - no-CRT support from Casey Muratori 0.997 - bugfixes for bugs found by Terje Mathisen 0.996 - bugfix: fast-huffman decode initialized incorrectly for sparse codebooks; fixing gives 10% speedup - found by Terje Mathisen 0.995 - bugfix: fix to 'effective' overrun detection - found by Terje Mathisen 0.994 - bugfix: garbage decode on final VQ symbol of a non-multiple - found by Terje Mathisen 0.993 - bugfix: pushdata API required 1 extra byte for empty page (failed to consume final page if empty) - found by Terje Mathisen 0.992 - fixes for MinGW warning 0.991 - turn fast-float-conversion on by default 0.990 - fix push-mode seek recovery if you seek into the headers 0.98b - fix to bad release of 0.98 0.98 - fix push-mode seek recovery; robustify float-to-int and support non-fast mode 0.97 - builds under c++ (typecasting, don't use 'class' keyword) 0.96 - somehow MY 0.95 was right, but the web one was wrong, so here's my 0.95 rereleased as 0.96, fixes a typo in the clamping code 0.95 - clamping code for 16-bit functions 0.94 - not publically released 0.93 - fixed all-zero-floor case (was decoding garbage) 0.92 - fixed a memory leak 0.91 - conditional compiles to omit parts of the API and the infrastructure to support them: STB_VORBIS_NO_PULLDATA_API, STB_VORBIS_NO_PUSHDATA_API, STB_VORBIS_NO_STDIO, STB_VORBIS_NO_INTEGER_CONVERSION 0.90 - first public release */ #endif // STB_VORBIS_HEADER_ONLY /* ------------------------------------------------------------------------------ This software is available under 2 licenses -- choose whichever you prefer. ------------------------------------------------------------------------------ ALTERNATIVE A - MIT License Copyright (c) 2017 Sean Barrett Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ ALTERNATIVE B - Public Domain (www.unlicense.org) This is free and unencumbered software released into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. In jurisdictions that recognize copyright laws, the author or authors of this software dedicate any and all copyright interest in the software to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this software under copyright law. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ------------------------------------------------------------------------------ */ ���������������������������������������������������������������������������������go-lib-5.6.0.9/stb_vorbis/stb_vorbis.go�������������������������������������������������������������000664 �000000 �000000 �00000011036 13753517240 017711� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������package stb_vorbis /* #include "stb_vorbis.h" #include <stdlib.h> #cgo LDFLAGS: -lm */ import "C" import ( "errors" "fmt" "reflect" "unsafe" ) type Info struct { SampleRate uint Channels int } type Decoder struct { Ptr unsafe.Pointer } func (v Decoder) native() *C.stb_vorbis { return (*C.stb_vorbis)(v.Ptr) } func wrapDecoder(ptr *C.stb_vorbis) Decoder { return Decoder{Ptr: unsafe.Pointer(ptr)} } func OpenFile(filename string) (Decoder, error) { filename0 := C.CString(filename) var errCode C.int ret := C.stb_vorbis_open_filename(filename0, &errCode, nil) C.free(unsafe.Pointer(filename0)) if errCode != 0 { return Decoder{}, Error{Code: int(errCode)} } return wrapDecoder(ret), nil } func DecodeFile(filename string) (result []int16, channels int, sampleRate int, err error) { filename0 := C.CString(filename) var channels0 C.int var sampleRate0 C.int var output *C.short ret := C.stb_vorbis_decode_filename(filename0, &channels0, &sampleRate0, &output) C.free(unsafe.Pointer(filename0)) if ret < 0 { return nil, 0, 0, errors.New("decode filename error") } var slice []C.short setSliceDataLen(unsafe.Pointer(&slice), unsafe.Pointer(output), int(ret*channels0)) result = make([]int16, len(slice)) for i, v := range slice { result[i] = int16(v) } return result, int(channels0), int(sampleRate0), nil } func setSliceDataLen(pSlice, pData unsafe.Pointer, len int) { header := (*reflect.SliceHeader)(pSlice) header.Cap = len header.Len = len header.Data = uintptr(pData) } func (d Decoder) Close() { C.stb_vorbis_close(d.native()) } const ( NoError = C.VORBIS__no_error NeedMoreData = C.VORBIS_need_more_data InvalidAPIMixing = C.VORBIS_invalid_api_mixing OutOfMem = C.VORBIS_outofmem FeatureNotSupported = C.VORBIS_feature_not_supported TooManyChannels = C.VORBIS_too_many_channels FileOpenFailure = C.VORBIS_file_open_failure SeekWithoutLength = C.VORBIS_seek_without_length UnexpectedEOF = C.VORBIS_unexpected_eof SeekInvalid = C.VORBIS_seek_invalid // vorbis errors: InvalidSetup = C.VORBIS_invalid_setup InvalidStream = C.VORBIS_invalid_stream // ogg errors: MissingCapturePattern = C.VORBIS_missing_capture_pattern InvalidStreamStructureVersion = C.VORBIS_invalid_stream_structure_version InvalidContinuedPacketFlag = C.VORBIS_continued_packet_flag_invalid IncorrectStreamSerialNumber = C.VORBIS_incorrect_stream_serial_number InvalidFirstPage = C.VORBIS_invalid_first_page BadPacketType = C.VORBIS_bad_packet_type CantFindLastPage = C.VORBIS_cant_find_last_page SeekFailed = C.VORBIS_seek_failed ) type Error struct { Code int } func (err Error) Error() string { switch err.Code { case NeedMoreData: return "need more data" case FeatureNotSupported: return "feature not supported" case FileOpenFailure: return "file open failure" case InvalidAPIMixing: return "invalid API mixing" case OutOfMem: return "out of memory" case SeekInvalid: return "seek invalid" case SeekWithoutLength: return "seek without length" case TooManyChannels: return "too many channels" case UnexpectedEOF: return "unexpected EOF" case InvalidSetup: return "invalid setup" case InvalidStream: return "invalid stream" case MissingCapturePattern: return "ogg missing capture pattern" case InvalidStreamStructureVersion: return "ogg invalid stream structure version" case InvalidContinuedPacketFlag: return "ogg invalid continued packet flag" case IncorrectStreamSerialNumber: return "ogg incorrect stream serial number" case InvalidFirstPage: return "ogg invalid first page" case BadPacketType: return "ogg bad packet type" case CantFindLastPage: return "ogg can't find last page" case SeekFailed: return "ogg seek failed" } return fmt.Sprintf("other vorbis error(%d)", err.Code) } func (d Decoder) GetError() error { ret := C.stb_vorbis_get_error(d.native()) if ret == NoError { return nil } return Error{ Code: int(ret), } } func (d Decoder) GetInfo() Info { ret := C.stb_vorbis_get_info(d.native()) return Info{ SampleRate: uint(ret.sample_rate), Channels: int(ret.channels), } } func (d Decoder) StreamLengthInSamples() uint { ret := C.stb_vorbis_stream_length_in_samples(d.native()) return uint(ret) } func (d Decoder) GetSamplesShortInterleaved(channels int, buffer []byte) int { buf := (*C.short)(unsafe.Pointer(&buffer[0])) ret := C.stb_vorbis_get_samples_short_interleaved(d.native(), C.int(channels), buf, C.int(len(buffer)/2)) return int(ret) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/stb_vorbis/stb_vorbis.h��������������������������������������������������������������000664 �000000 �000000 �00000035077 13753517240 017546� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef STB_VORBIS_INCLUDE_STB_VORBIS_H #define STB_VORBIS_INCLUDE_STB_VORBIS_H #if defined(STB_VORBIS_NO_CRT) && !defined(STB_VORBIS_NO_STDIO) #define STB_VORBIS_NO_STDIO 1 #endif #ifndef STB_VORBIS_NO_STDIO #include <stdio.h> #endif #ifdef __cplusplus extern "C" { #endif /////////// THREAD SAFETY // Individual stb_vorbis* handles are not thread-safe; you cannot decode from // them from multiple threads at the same time. However, you can have multiple // stb_vorbis* handles and decode from them independently in multiple thrads. /////////// MEMORY ALLOCATION // normally stb_vorbis uses malloc() to allocate memory at startup, // and alloca() to allocate temporary memory during a frame on the // stack. (Memory consumption will depend on the amount of setup // data in the file and how you set the compile flags for speed // vs. size. In my test files the maximal-size usage is ~150KB.) // // You can modify the wrapper functions in the source (setup_malloc, // setup_temp_malloc, temp_malloc) to change this behavior, or you // can use a simpler allocation model: you pass in a buffer from // which stb_vorbis will allocate _all_ its memory (including the // temp memory). "open" may fail with a VORBIS_outofmem if you // do not pass in enough data; there is no way to determine how // much you do need except to succeed (at which point you can // query get_info to find the exact amount required. yes I know // this is lame). // // If you pass in a non-NULL buffer of the type below, allocation // will occur from it as described above. Otherwise just pass NULL // to use malloc()/alloca() typedef struct { char *alloc_buffer; int alloc_buffer_length_in_bytes; } stb_vorbis_alloc; /////////// FUNCTIONS USEABLE WITH ALL INPUT MODES typedef struct stb_vorbis stb_vorbis; typedef struct { unsigned int sample_rate; int channels; unsigned int setup_memory_required; unsigned int setup_temp_memory_required; unsigned int temp_memory_required; int max_frame_size; } stb_vorbis_info; // get general information about the file extern stb_vorbis_info stb_vorbis_get_info(stb_vorbis *f); // get the last error detected (clears it, too) extern int stb_vorbis_get_error(stb_vorbis *f); // close an ogg vorbis file and free all memory in use extern void stb_vorbis_close(stb_vorbis *f); // this function returns the offset (in samples) from the beginning of the // file that will be returned by the next decode, if it is known, or -1 // otherwise. after a flush_pushdata() call, this may take a while before // it becomes valid again. // NOT WORKING YET after a seek with PULLDATA API extern int stb_vorbis_get_sample_offset(stb_vorbis *f); // returns the current seek point within the file, or offset from the beginning // of the memory buffer. In pushdata mode it returns 0. extern unsigned int stb_vorbis_get_file_offset(stb_vorbis *f); /////////// PUSHDATA API #ifndef STB_VORBIS_NO_PUSHDATA_API // this API allows you to get blocks of data from any source and hand // them to stb_vorbis. you have to buffer them; stb_vorbis will tell // you how much it used, and you have to give it the rest next time; // and stb_vorbis may not have enough data to work with and you will // need to give it the same data again PLUS more. Note that the Vorbis // specification does not bound the size of an individual frame. extern stb_vorbis *stb_vorbis_open_pushdata( const unsigned char * datablock, int datablock_length_in_bytes, int *datablock_memory_consumed_in_bytes, int *error, const stb_vorbis_alloc *alloc_buffer); // create a vorbis decoder by passing in the initial data block containing // the ogg&vorbis headers (you don't need to do parse them, just provide // the first N bytes of the file--you're told if it's not enough, see below) // on success, returns an stb_vorbis *, does not set error, returns the amount of // data parsed/consumed on this call in *datablock_memory_consumed_in_bytes; // on failure, returns NULL on error and sets *error, does not change *datablock_memory_consumed // if returns NULL and *error is VORBIS_need_more_data, then the input block was // incomplete and you need to pass in a larger block from the start of the file extern int stb_vorbis_decode_frame_pushdata( stb_vorbis *f, const unsigned char *datablock, int datablock_length_in_bytes, int *channels, // place to write number of float * buffers float ***output, // place to write float ** array of float * buffers int *samples // place to write number of output samples ); // decode a frame of audio sample data if possible from the passed-in data block // // return value: number of bytes we used from datablock // // possible cases: // 0 bytes used, 0 samples output (need more data) // N bytes used, 0 samples output (resynching the stream, keep going) // N bytes used, M samples output (one frame of data) // note that after opening a file, you will ALWAYS get one N-bytes,0-sample // frame, because Vorbis always "discards" the first frame. // // Note that on resynch, stb_vorbis will rarely consume all of the buffer, // instead only datablock_length_in_bytes-3 or less. This is because it wants // to avoid missing parts of a page header if they cross a datablock boundary, // without writing state-machiney code to record a partial detection. // // The number of channels returned are stored in *channels (which can be // NULL--it is always the same as the number of channels reported by // get_info). *output will contain an array of float* buffers, one per // channel. In other words, (*output)[0][0] contains the first sample from // the first channel, and (*output)[1][0] contains the first sample from // the second channel. extern void stb_vorbis_flush_pushdata(stb_vorbis *f); // inform stb_vorbis that your next datablock will not be contiguous with // previous ones (e.g. you've seeked in the data); future attempts to decode // frames will cause stb_vorbis to resynchronize (as noted above), and // once it sees a valid Ogg page (typically 4-8KB, as large as 64KB), it // will begin decoding the _next_ frame. // // if you want to seek using pushdata, you need to seek in your file, then // call stb_vorbis_flush_pushdata(), then start calling decoding, then once // decoding is returning you data, call stb_vorbis_get_sample_offset, and // if you don't like the result, seek your file again and repeat. #endif ////////// PULLING INPUT API #ifndef STB_VORBIS_NO_PULLDATA_API // This API assumes stb_vorbis is allowed to pull data from a source-- // either a block of memory containing the _entire_ vorbis stream, or a // FILE * that you or it create, or possibly some other reading mechanism // if you go modify the source to replace the FILE * case with some kind // of callback to your code. (But if you don't support seeking, you may // just want to go ahead and use pushdata.) #if !defined(STB_VORBIS_NO_STDIO) && !defined(STB_VORBIS_NO_INTEGER_CONVERSION) extern int stb_vorbis_decode_filename(const char *filename, int *channels, int *sample_rate, short **output); #endif #if !defined(STB_VORBIS_NO_INTEGER_CONVERSION) extern int stb_vorbis_decode_memory(const unsigned char *mem, int len, int *channels, int *sample_rate, short **output); #endif // decode an entire file and output the data interleaved into a malloc()ed // buffer stored in *output. The return value is the number of samples // decoded, or -1 if the file could not be opened or was not an ogg vorbis file. // When you're done with it, just free() the pointer returned in *output. extern stb_vorbis * stb_vorbis_open_memory(const unsigned char *data, int len, int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from an ogg vorbis stream in memory (note // this must be the entire stream!). on failure, returns NULL and sets *error #ifndef STB_VORBIS_NO_STDIO extern stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from a filename via fopen(). on failure, // returns NULL and sets *error (possibly to VORBIS_file_open_failure). extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close, int *error, const stb_vorbis_alloc *alloc_buffer); // create an ogg vorbis decoder from an open FILE *, looking for a stream at // the _current_ seek point (ftell). on failure, returns NULL and sets *error. // note that stb_vorbis must "own" this stream; if you seek it in between // calls to stb_vorbis, it will become confused. Morever, if you attempt to // perform stb_vorbis_seek_*() operations on this file, it will assume it // owns the _entire_ rest of the file after the start point. Use the next // function, stb_vorbis_open_file_section(), to limit it. extern stb_vorbis * stb_vorbis_open_file_section(FILE *f, int close_handle_on_close, int *error, const stb_vorbis_alloc *alloc_buffer, unsigned int len); // create an ogg vorbis decoder from an open FILE *, looking for a stream at // the _current_ seek point (ftell); the stream will be of length 'len' bytes. // on failure, returns NULL and sets *error. note that stb_vorbis must "own" // this stream; if you seek it in between calls to stb_vorbis, it will become // confused. #endif extern int stb_vorbis_seek_frame(stb_vorbis *f, unsigned int sample_number); extern int stb_vorbis_seek(stb_vorbis *f, unsigned int sample_number); // these functions seek in the Vorbis file to (approximately) 'sample_number'. // after calling seek_frame(), the next call to get_frame_*() will include // the specified sample. after calling stb_vorbis_seek(), the next call to // stb_vorbis_get_samples_* will start with the specified sample. If you // do not need to seek to EXACTLY the target sample when using get_samples_*, // you can also use seek_frame(). extern int stb_vorbis_seek_start(stb_vorbis *f); // this function is equivalent to stb_vorbis_seek(f,0) extern unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f); extern float stb_vorbis_stream_length_in_seconds(stb_vorbis *f); // these functions return the total length of the vorbis stream extern int stb_vorbis_get_frame_float(stb_vorbis *f, int *channels, float ***output); // decode the next frame and return the number of samples. the number of // channels returned are stored in *channels (which can be NULL--it is always // the same as the number of channels reported by get_info). *output will // contain an array of float* buffers, one per channel. These outputs will // be overwritten on the next call to stb_vorbis_get_frame_*. // // You generally should not intermix calls to stb_vorbis_get_frame_*() // and stb_vorbis_get_samples_*(), since the latter calls the former. #ifndef STB_VORBIS_NO_INTEGER_CONVERSION extern int stb_vorbis_get_frame_short_interleaved(stb_vorbis *f, int num_c, short *buffer, int num_shorts); extern int stb_vorbis_get_frame_short (stb_vorbis *f, int num_c, short **buffer, int num_samples); #endif // decode the next frame and return the number of *samples* per channel. // Note that for interleaved data, you pass in the number of shorts (the // size of your array), but the return value is the number of samples per // channel, not the total number of samples. // // The data is coerced to the number of channels you request according to the // channel coercion rules (see below). You must pass in the size of your // buffer(s) so that stb_vorbis will not overwrite the end of the buffer. // The maximum buffer size needed can be gotten from get_info(); however, // the Vorbis I specification implies an absolute maximum of 4096 samples // per channel. // Channel coercion rules: // Let M be the number of channels requested, and N the number of channels present, // and Cn be the nth channel; let stereo L be the sum of all L and center channels, // and stereo R be the sum of all R and center channels (channel assignment from the // vorbis spec). // M N output // 1 k sum(Ck) for all k // 2 * stereo L, stereo R // k l k > l, the first l channels, then 0s // k l k <= l, the first k channels // Note that this is not _good_ surround etc. mixing at all! It's just so // you get something useful. extern int stb_vorbis_get_samples_float_interleaved(stb_vorbis *f, int channels, float *buffer, int num_floats); extern int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, int num_samples); // gets num_samples samples, not necessarily on a frame boundary--this requires // buffering so you have to supply the buffers. DOES NOT APPLY THE COERCION RULES. // Returns the number of samples stored per channel; it may be less than requested // at the end of the file. If there are no more samples in the file, returns 0. #ifndef STB_VORBIS_NO_INTEGER_CONVERSION extern int stb_vorbis_get_samples_short_interleaved(stb_vorbis *f, int channels, short *buffer, int num_shorts); extern int stb_vorbis_get_samples_short(stb_vorbis *f, int channels, short **buffer, int num_samples); #endif // gets num_samples samples, not necessarily on a frame boundary--this requires // buffering so you have to supply the buffers. Applies the coercion rules above // to produce 'channels' channels. Returns the number of samples stored per channel; // it may be less than requested at the end of the file. If there are no more // samples in the file, returns 0. #endif //////// ERROR CODES enum STBVorbisError { VORBIS__no_error, VORBIS_need_more_data=1, // not a real error VORBIS_invalid_api_mixing, // can't mix API modes VORBIS_outofmem, // not enough memory VORBIS_feature_not_supported, // uses floor 0 VORBIS_too_many_channels, // STB_VORBIS_MAX_CHANNELS is too small VORBIS_file_open_failure, // fopen() failed VORBIS_seek_without_length, // can't seek in unknown-length file VORBIS_unexpected_eof=10, // file is truncated? VORBIS_seek_invalid, // seek past EOF // decoding errors (corrupt/invalid stream) -- you probably // don't care about the exact details of these // vorbis errors: VORBIS_invalid_setup=20, VORBIS_invalid_stream, // ogg errors: VORBIS_missing_capture_pattern=30, VORBIS_invalid_stream_structure_version, VORBIS_continued_packet_flag_invalid, VORBIS_incorrect_stream_serial_number, VORBIS_invalid_first_page, VORBIS_bad_packet_type, VORBIS_cant_find_last_page, VORBIS_seek_failed }; #ifdef __cplusplus } #endif #endif // STB_VORBIS_INCLUDE_STB_VORBIS_H �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/strv/��������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014027� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/strv/strv.go�������������������������������������������������������������������������000664 �000000 �000000 �00000004064 13753517240 015360� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package strv // string vector type Strv []string func (vector Strv) Contains(str string) bool { for _, e := range vector { if e == str { return true } } return false } func (v1 Strv) Equal(v2 Strv) bool { if len(v1) != len(v2) { return false } for i, e1 := range v1 { if e1 != v2[i] { return false } } return true } func (vector Strv) Uniq() Strv { var newVector Strv for _, e := range vector { if !newVector.Contains(e) { newVector = append(newVector, e) } } return newVector } func (vector Strv) FilterFunc(fn func(string) bool) Strv { if fn == nil { return vector } newVector := make(Strv, 0, len(vector)) for _, e := range vector { if fn(e) { continue } newVector = append(newVector, e) } return newVector } func (vector Strv) FilterEmpty() Strv { newVector := make(Strv, 0, len(vector)) for _, e := range vector { if len(e) == 0 { continue } newVector = append(newVector, e) } return newVector } func (vector Strv) Add(str string) (Strv, bool) { if vector.Contains(str) { return vector, false } return Strv(append(vector, str)), true } func (vector Strv) Delete(str string) (Strv, bool) { var found bool ret := make(Strv, 0, len(vector)) for _, e := range vector { if e == str { found = true continue } ret = append(ret, e) } return ret, found } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/strv/strv_test.go��������������������������������������������������������������������000664 �000000 �000000 �00000005661 13753517240 016423� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package strv import ( . "github.com/smartystreets/goconvey/convey" "testing" ) func TestContains(t *testing.T) { Convey("Contains", t, func(c C) { vector := Strv([]string{"a", "b", "c"}) c.So(vector.Contains("b"), ShouldBeTrue) c.So(vector.Contains("d"), ShouldBeFalse) }) } func TestEqual(t *testing.T) { Convey("Equal", t, func(c C) { v1 := Strv([]string{"a", "b", "c"}) v2 := Strv([]string{"a", "b", "c", "d"}) v3 := Strv(v1[:]) c.So(v1.Equal(v2), ShouldBeFalse) c.So(v1.Equal(v3), ShouldBeTrue) }) } func TestUniq(t *testing.T) { Convey("Uniq", t, func(c C) { vector := Strv([]string{"a", "b", "c", "c", "b", "a", "c"}) vector = vector.Uniq() c.So(vector, ShouldResemble, Strv([]string{"a", "b", "c"})) }) } func TestFilterFunc(t *testing.T) { Convey("FilterFunc", t, func(c C) { vector := Strv([]string{"hello", "", "world", "", "!"}) vector = vector.FilterFunc(func(str string) bool { return len(str) == 0 }) c.So(vector, ShouldResemble, Strv([]string{"hello", "world", "!"})) }) } func TestFilterEmpty(t *testing.T) { Convey("FilterEmpty", t, func(c C) { vector := Strv([]string{"hello", "", "world", "", "!"}) vector = vector.FilterEmpty() c.So(vector, ShouldResemble, Strv([]string{"hello", "world", "!"})) }) } func TestAdd(t *testing.T) { Convey("Add", t, func(c C) { vector := Strv([]string{"a", "b", "c"}) vector0, b0 := vector.Add("d") c.So(vector, ShouldResemble, Strv([]string{"a", "b", "c"})) c.So(vector0, ShouldResemble, Strv([]string{"a", "b", "c", "d"})) c.So(b0, ShouldBeTrue) vector1, b1 := vector.Add("c") c.So(vector, ShouldResemble, Strv([]string{"a", "b", "c"})) c.So(vector1, ShouldResemble, Strv([]string{"a", "b", "c"})) c.So(b1, ShouldBeFalse) }) } func TestDelete(t *testing.T) { Convey("Delete", t, func(c C) { vector := Strv([]string{"a", "b", "c"}) vector0, b0 := vector.Delete("d") c.So(vector, ShouldResemble, Strv([]string{"a", "b", "c"})) c.So(vector0, ShouldResemble, Strv([]string{"a", "b", "c"})) c.So(b0, ShouldBeFalse) vector1, b1 := vector.Delete("c") c.So(vector, ShouldResemble, Strv([]string{"a", "b", "c"})) c.So(vector1, ShouldResemble, Strv([]string{"a", "b"})) c.So(b1, ShouldBeTrue) }) } �������������������������������������������������������������������������������go-lib-5.6.0.9/tasker/������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014322� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/tasker/delay_task.go�����������������������������������������������������������������000664 �000000 �000000 �00000005427 13753517240 017001� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package tasker import ( "fmt" "reflect" "sync" "time" ) type DelayTask struct { timer *time.Timer handler reflect.Value argsType []reflect.Type duration time.Duration termination chan struct{} locker sync.Mutex } func NewDelayTask(duration time.Duration, cb interface{}) (*DelayTask, error) { handler, argsType, err := handleFuncSignature(cb) if err != nil { return nil, err } return &DelayTask{ handler: *handler, argsType: argsType, duration: duration, }, nil } func (task *DelayTask) Start(args ...interface{}) error { // if started, stop it, else nothing to do task.Stop() task.locker.Lock() defer task.locker.Unlock() if len(task.argsType) != len(args) { return fmt.Errorf("argument length expected %d, but got %d", len(task.argsType), len(args)) } // check each arg type for i, t := range task.argsType { t0 := reflect.TypeOf(args[i]) if t != t0 { return fmt.Errorf("args[%d] type expected %s, but got %s", i, t, t0) } } var values = make([]reflect.Value, len(args)) for i, v := range args { values[i] = reflect.ValueOf(v) } task.doStart(values) return nil } func (task *DelayTask) doStart(values []reflect.Value) { task.termination = make(chan struct{}) task.timer = time.NewTimer(task.duration) go func() { exit := task.termination timer := task.timer select { case <-exit: return case <-timer.C: task.handler.Call(values) return } }() } func (task *DelayTask) Stop() { task.locker.Lock() defer task.locker.Unlock() if task.termination != nil { close(task.termination) task.termination = nil // TODO: delete time.Sleep(time.Millisecond * 50) } if task.timer != nil { task.timer.Stop() } } func handleFuncSignature(f interface{}) (*reflect.Value, []reflect.Type, error) { fn := reflect.ValueOf(f) if fn.Kind() != reflect.Func { return nil, nil, fmt.Errorf("not a function") } fnType := fn.Type() fnNum := fnType.NumIn() argTypes := make([]reflect.Type, fnNum) for i := 0; i < fnNum; i++ { argTypes[i] = fnType.In(i) } return &fn, argTypes, nil } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/tasker/delay_task_manager.go���������������������������������������������������������000664 �000000 �000000 �00000003622 13753517240 020466� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package tasker import ( "fmt" "sync" "time" ) type DelayTaskManager struct { taskMap map[string]*DelayTask locker sync.Mutex } func NewDelayTaskManager() *DelayTaskManager { return &DelayTaskManager{ taskMap: make(map[string]*DelayTask), } } func (m *DelayTaskManager) AddTask(name string, duration time.Duration, cb interface{}) error { m.locker.Lock() defer m.locker.Unlock() if _, ok := m.taskMap[name]; ok { return fmt.Errorf("Task '%s' has exists", name) } task, err := NewDelayTask(duration, cb) if err != nil { return err } m.taskMap[name] = task return nil } func (m *DelayTaskManager) GetTask(name string) (*DelayTask, error) { m.locker.Lock() defer m.locker.Unlock() task, ok := m.taskMap[name] if !ok { return nil, fmt.Errorf("No task '%s' exists", name) } return task, nil } func (m *DelayTaskManager) DeleteTask(name string) { m.locker.Lock() defer m.locker.Unlock() task, ok := m.taskMap[name] if !ok { return } task.Stop() task = nil delete(m.taskMap, name) } func (m *DelayTaskManager) Destroy() { m.locker.Lock() defer m.locker.Unlock() for _, task := range m.taskMap { task.Stop() task = nil } m.taskMap = nil } ��������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/tasker/tasker_test.go����������������������������������������������������������������000664 �000000 �000000 �00000002760 13753517240 017206� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package tasker import ( "fmt" "testing" "time" ) func handleTask(id int, name string) { fmt.Printf("%v: %s\n", id, name) } func TestDelayTask(t *testing.T) { _, err := NewDelayTask(time.Second*1, nil) if err == nil { panic("Failed: should error, because if invalid callback function") } task, err := NewDelayTask(time.Second*1, handleTask) if err != nil { panic("Failed: should no error") } err = task.Start(1, "First") if err != nil { panic("Failed: should no error") } time.Sleep(time.Second * 2) err = task.Start(2, "Second") if err != nil { panic("Failed: should no error") } time.Sleep(time.Millisecond * 500) err = task.Start(3, "Third") if err != nil { panic("Failed: should no error") } time.Sleep(time.Millisecond * 1200) } ����������������go-lib-5.6.0.9/timer/�������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014151� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/timer/time.go������������������������������������������������������������������������000664 �000000 �000000 �00000003760 13753517240 015444� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package timer // #include <time.h> import "C" import ( "fmt" ) // TimeSpec holds times. type TimeSpec struct { seconds int64 nanoSeconds int64 } func (ts TimeSpec) String() string { return fmt.Sprintf("%d.%d", ts.Seconds(), ts.NanoSeconds()) } // Seconds returns the seconds. func (ts TimeSpec) Seconds() int64 { return ts.seconds } // Milliseconds returns the milliseconds func (ts TimeSpec) Milliseconds() int64 { return ts.seconds*1000 + ts.nanoSeconds/1000000 } // MicroSeconds returns milliseconds func (ts TimeSpec) MicroSeconds() int64 { return ts.seconds*1000000 + ts.nanoSeconds/1000 } // NanoSeconds returns nanoseconds func (ts TimeSpec) NanoSeconds() int64 { return ts.nanoSeconds } // GetMonotonicTime returns the monotonic time, used when the time should be effected by time adjust, like timer. // according to the sources of golang, the time.Now() is the CLOCK_REALTIME // which will be affected by discontinuous jumps in the system time. func GetMonotonicTime() TimeSpec { var ts C.struct_timespec // see http://man7.org/linux/man-pages/man2/clock_gettime.2.html for a list of CLOCK_ constants C.clock_gettime(C.CLOCK_MONOTONIC_RAW, &ts) // convert to something easier to manipulate return TimeSpec{int64(ts.tv_sec), int64(ts.tv_nsec)} } ����������������go-lib-5.6.0.9/timer/timer.go�����������������������������������������������������������������������000664 �000000 �000000 �00000004017 13753517240 015622� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package timer import ( "time" ) type _TimerState uint16 const ( _TimerStateNotStarted _TimerState = iota _TimerStateStarted _TimerStateStopped ) // Timer is used for reporting rate. type Timer struct { timer time.Time duration time.Duration lastDuration time.Duration state _TimerState } // NewTimer creates a new timer. func NewTimer() *Timer { timer := &Timer{ timer: time.Now(), duration: 0, state: _TimerStateNotStarted, } return timer } // Start the timer. func (timer *Timer) Start() { timer.state = _TimerStateStarted timer.timer = time.Now() } // Stop timer. func (timer *Timer) Stop() { if timer.state&_TimerStateStarted != 1 { return } timer.state = _TimerStateStopped timer.duration += time.Since(timer.timer) timer.lastDuration = timer.duration } // Continue a stopped timer. func (timer *Timer) Continue() { timer.Start() } // Reset a timer. func (timer *Timer) Reset() { timer.duration = time.Duration(0) timer.Start() } // Elapsed returns the duration from start to end if timer is stopped. // Elapsed returns the duration from start to now if timer is not stopped. func (timer *Timer) Elapsed() time.Duration { if timer.state == _TimerStateStarted { return timer.lastDuration + time.Since(timer.timer) } return timer.duration } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/timer/timer_test.go������������������������������������������������������������������000664 �000000 �000000 �00000005433 13753517240 016664� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package timer_test import ( . "github.com/smartystreets/goconvey/convey" . "pkg.deepin.io/lib/timer" "testing" "time" ) func TestTimer(t *testing.T) { Convey("just stop", t, func(c C) { timer := NewTimer() timer.Stop() c.So(timer.Elapsed(), ShouldEqual, 0) }) Convey("get elapse without stop", t, func(c C) { timer := NewTimer() timer.Start() time.Sleep(time.Second) c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second-time.Millisecond*100, time.Second+time.Millisecond*100) time.Sleep(time.Second) c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second*2-time.Millisecond*100, time.Second*3+time.Millisecond*100) }) Convey("stop and elapse", t, func(c C) { timer := NewTimer() timer.Start() time.Sleep(time.Second) timer.Stop() c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second-time.Millisecond*100, time.Second+time.Millisecond*100) time.Sleep(time.Second) c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second-time.Millisecond*100, time.Second+time.Millisecond*100) }) Convey("stop and continue", t, func(c C) { timer := NewTimer() timer.Start() time.Sleep(time.Second) c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second-time.Millisecond*100, time.Second+time.Millisecond*100) timer.Stop() c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second-time.Millisecond*100, time.Second+time.Millisecond*100) time.Sleep(time.Second) timer.Continue() c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second-time.Millisecond*100, time.Second+time.Millisecond*100) time.Sleep(time.Second) c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second*2-time.Millisecond*100, time.Second*2+time.Millisecond*100) }) Convey("reset", t, func(c C) { timer := NewTimer() timer.Start() time.Sleep(time.Second) c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second-time.Millisecond*100, time.Second+time.Millisecond*100) timer.Reset() time.Sleep(time.Second) c.So(timer.Elapsed(), ShouldBeBetweenOrEqual, time.Second-time.Millisecond*100, time.Second+time.Millisecond*100) }) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/�������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014172� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/group/�������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015326� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/group/group.go�����������������������������������������������������������������000664 �000000 �000000 �00000006475 13753517240 017025� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package group // #include <stdlib.h> // #include <grp.h> import "C" import ( "fmt" "unsafe" ) // Group wraps up `group` struct used in kernel type Group struct { Name string Passwd string // Password is encrypted if password-shadowing is on Gid uint32 Members *[]string // member list } // stringArrayC2Go_2 converts string array in C to string slice in Golang // It is a revised version of @stringArrayC2Go func stringArrayC2Go_2(strArrC **C.char) *[]string { strArr := make([]string, 0) arrIndex := (*[1 << 10]*C.char)(unsafe.Pointer(strArrC)) for _, p := range arrIndex { if p == nil { break } strArr = append(strArr, C.GoString(p)) } return &strArr } // groupC2Go converts `group` struct from C to golang native struct func groupC2Go(groupC *C.struct_group) *Group { members := stringArrayC2Go_2(groupC.gr_mem) return &Group{ Name: C.GoString(groupC.gr_name), Passwd: C.GoString(groupC.gr_passwd), Gid: uint32(groupC.gr_gid), Members: members, } } type GroupNotFoundError struct { Name string Gid uint32 } func (err *GroupNotFoundError) Error() string { if len(err.Name) > 0 { return fmt.Sprintf("Group with name `%s` not found!", err.Name) } else { return fmt.Sprintf("Group with gid `%d` not found!", err.Gid) } } // GetGroupByName wraps up `getgrnam` system call. // It retrieves group records from group file based on group name. func GetGroupByName(name string) (*Group, error) { nameC := C.CString(name) defer C.free(unsafe.Pointer(nameC)) groupC, err := C.getgrnam(nameC) if groupC == nil { if err == nil { return nil, &GroupNotFoundError{Name: name} } else { return nil, err } } else { return groupC2Go(groupC), nil } } // GetGroupByGid wraps up `getgrgid` system call. // It retrieves group records from group file based on gid. func GetGroupByGid(gid uint32) (*Group, error) { gidC := C.__gid_t(gid) groupC, err := C.getgrgid(gidC) if groupC == nil { if err == nil { return nil, &GroupNotFoundError{Gid: gid} } else { return nil, err } } else { return groupC2Go(groupC), nil } } // GetGroupEntry wraps up `getgrent` system call. // It performs sequential scans of the records in the group file. func GetGroupEntry() []*Group { var groups []*Group // Restart scanning from the begging of the group file. C.setgrent() for { groupC := C.getgrent() if groupC == nil { break } group := groupC2Go(groupC) groups = append(groups, group) } // Call endgrent() is necessary so that any subsequent getgrent() call will // reopen the group file and start from the beginning. C.endgrent() return groups } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/group/group_test.go������������������������������������������������������������000664 �000000 �000000 �00000003026 13753517240 020051� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package group import ( "testing" C "gopkg.in/check.v1" ) type testWrapper struct{} func init() { C.Suite(&testWrapper{}) } func Test(t *testing.T) { C.TestingT(t) } func (*testWrapper) TestGetGroupByName(c *C.C) { name := "root" group, err := GetGroupByName(name) c.Check(err, C.IsNil) c.Check(group.Gid, C.Equals, uint32(0)) name = "root2" group, err = GetGroupByName(name) c.Check(group, C.IsNil) c.Check(err, C.DeepEquals, &GroupNotFoundError{Name: name}) } func (*testWrapper) TestGetGroupByGid(c *C.C) { uid := uint32(0) group, err := GetGroupByGid(uid) c.Check(err, C.IsNil) c.Check(group.Name, C.Equals, "root") } func (*testWrapper) TestGetGroupEntry(c *C.C) { groups := GetGroupEntry() c.Check(len(groups), C.Not(C.Equals), 0) c.Check(groups[0].Name, C.Equals, "root") } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/passwd/������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015473� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/passwd/passwd.go���������������������������������������������������������������000664 �000000 �000000 �00000006106 13753517240 017326� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package passwd // #include <stdlib.h> // #include <pwd.h> import "C" import ( "fmt" "unsafe" ) // Passwd wraps up `passwd` struct used in kernel type Passwd struct { Name string Passwd string // Password is encrypted Uid uint32 Gid uint32 Comment string Home string Shell string } // passwdC2Go converts `passwd` struct from C to golang native struct func passwdC2Go(passwdC *C.struct_passwd) *Passwd { return &Passwd{ Name: C.GoString(passwdC.pw_name), Passwd: C.GoString(passwdC.pw_passwd), Uid: uint32(passwdC.pw_uid), Gid: uint32(passwdC.pw_gid), Comment: C.GoString(passwdC.pw_gecos), Home: C.GoString(passwdC.pw_dir), Shell: C.GoString(passwdC.pw_shell), } } type UserNotFoundError struct { Name string Uid uint32 } func (err *UserNotFoundError) Error() string { if len(err.Name) > 0 { return fmt.Sprintf("User with name `%s` not found!", err.Name) } else { return fmt.Sprintf("User with uid `%d` not found!", err.Uid) } } // GetPasswdByName wraps up `getpwnam` system call. // It retrieves records from the password file based on username. func GetPasswdByName(name string) (*Passwd, error) { nameC := C.CString(name) defer C.free(unsafe.Pointer(nameC)) passwdC, err := C.getpwnam(nameC) if passwdC == nil { if err == nil { return nil, &UserNotFoundError{Name: name} } else { return nil, err } } else { return passwdC2Go(passwdC), nil } } // GetPasswdByUid wraps up `getpwuid` system call. // It retrieves records from the password file based on uid. func GetPasswdByUid(uid uint32) (*Passwd, error) { uidC := C.__uid_t(uid) passwdC, err := C.getpwuid(uidC) if passwdC == nil { if err == nil { return nil, &UserNotFoundError{Uid: uid} } else { return nil, err } } else { return passwdC2Go(passwdC), nil } } // GetPasswdEntry wraps up `getpwent` system call // It performs sequential scans of the records in the password file. func GetPasswdEntry() []*Passwd { var passwds []*Passwd // Restart scanning from the begging of the password file. C.setpwent() for { passwdC := C.getpwent() if passwdC == nil { break } passwd := passwdC2Go(passwdC) passwds = append(passwds, passwd) } // Call endpwent() is necessary so that any subsequent getpwent() call will // reopen the password file and start from the beginning. C.endpwent() return passwds } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/passwd/passwd_test.go����������������������������������������������������������000664 �000000 �000000 �00000003117 13753517240 020364� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package passwd import ( "testing" C "gopkg.in/check.v1" ) type testWrapper struct{} func init() { C.Suite(&testWrapper{}) } func Test(t *testing.T) { C.TestingT(t) } func (*testWrapper) TestGetPasswdByName(c *C.C) { name := "root" passwd, err := GetPasswdByName(name) c.Check(passwd.Home, C.Equals, "/root") c.Check(passwd.Uid, C.Equals, uint32(0)) c.Check(err, C.IsNil) name = "root2" passwd, err = GetPasswdByName(name) c.Check(passwd, C.IsNil) c.Check(err, C.DeepEquals, &UserNotFoundError{Name: name}) } func (*testWrapper) TestGetPasswdByUid(c *C.C) { uid := uint32(0) passwd, err := GetPasswdByUid(uid) c.Check(err, C.IsNil) c.Check(passwd.Name, C.Equals, "root") } func (*testWrapper) TestGetPasswdEntry(c *C.C) { passwds := GetPasswdEntry() c.Check(len(passwds), C.Not(C.Equals), 0) c.Check(passwds[0].Name, C.Equals, "root") } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/shadow/������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015457� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/shadow/shadow.go���������������������������������������������������������������000664 �000000 �000000 �00000006157 13753517240 017304� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package shadow // #include <shadow.h> import "C" import ( "fmt" ) // spwd wraps up `spwd` (shadow password) used in kernel. type Shadow struct { Name string // login username Password string // encrypted password LastChange int64 // Date of last change since 1970-01-01 MinDays int64 // Min # of days between changes MaxDays int64 // Max # of days between changes Warn int64 // # of dayd before password expires to warn user to change it Inactive int64 // # of days after password expires until account is disabled Expire int64 // Date when account expires since 1970-01-01 Flag uint64 // reserved } // shadowC2Go converts `spwd` struct to golang native struct func shadowC2Go(shadowC *C.struct_spwd) *Shadow { return &Shadow{ Name: C.GoString(shadowC.sp_namp), Password: C.GoString(shadowC.sp_pwdp), LastChange: int64(shadowC.sp_lstchg), MinDays: int64(shadowC.sp_min), MaxDays: int64(shadowC.sp_max), Warn: int64(shadowC.sp_warn), Inactive: int64(shadowC.sp_inact), Expire: int64(shadowC.sp_expire), Flag: uint64(shadowC.sp_flag), } } type UserNotFoundError struct { Name string Uid uint32 } func (err *UserNotFoundError) Error() string { if len(err.Name) > 0 { return fmt.Sprintf("User with name `%s` not found!", err.Name) } else { return fmt.Sprintf("User with uid `%d` not found!", err.Uid) } } // GetShadowByName wraps up `getspnam` system call. // It returns the record in the shadow database file that matches the username // @name func GetShadowByName(name string) (*Shadow, error) { nameC := C.CString(name) shadowC, err := C.getspnam(nameC) if shadowC == nil { if err == nil { return nil, &UserNotFoundError{Name: name} } else { return nil, err } } else { return shadowC2Go(shadowC), nil } } // GetShadowEntry wraups up `getspent` system call. // It performs sequential scans of the records in the shadow file. func GetShadowEntry() []*Shadow { shadows := make([]*Shadow, 0) // Restart scanning from the begging of the shadow file. C.setspent() for shadowC, err := C.getspent(); shadowC != nil && err == nil; shadowC, err = C.getspent() { shadow := shadowC2Go(shadowC) shadows = append(shadows, shadow) } // Call endspent() is necessary so that any subsequent getspent() call will // reopen the shadow file and start from the beginning. C.endspent() return shadows } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/users/shadow/shadow_test.go����������������������������������������������������������000664 �000000 �000000 �00000002571 13753517240 020337� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package shadow import ( "syscall" "testing" C "gopkg.in/check.v1" ) type testWrapper struct{} func init() { C.Suite(&testWrapper{}) } func Test(t *testing.T) { C.TestingT(t) } func (*testWrapper) TestGetShadowByName(c *C.C) { name := "root" shadow, err := GetShadowByName(name) if err != nil { // Permission denied, current user has no access to shadow file c.Check(shadow, C.IsNil) c.Check(err, C.Equals, syscall.EACCES) } else { c.Check(shadow.Name, C.Equals, "root") } } func (*testWrapper) TestGetShadowEntry(c *C.C) { shadows := GetShadowEntry() if len(shadows) > 0 { c.Check(shadows[0].Name, C.Equals, "root") } } ���������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/�������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 014171� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/cache.go�����������������������������������������������������������������������000664 �000000 �000000 �00000002523 13753517240 015565� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "fmt" "os" "path" ) var DefaultCachePrefix = os.Getenv("HOME") + "/.cache/deepin" func GenerateCacheFilePath(keyword string) (dstfile string) { cachePathFormat := DefaultCachePrefix + "/%s" md5, _ := SumStrMd5(keyword) dstfile = fmt.Sprintf(cachePathFormat, md5) _ = EnsureDirExist(path.Dir(dstfile)) return } func GenerateCacheFilePathWithPrefix(prefix, keyword string) (dstfile string) { graphicCacheFormat := DefaultCachePrefix + "/%s/%s" md5, _ := SumStrMd5(keyword) dstfile = fmt.Sprintf(graphicCacheFormat, prefix, md5) _ = EnsureDirExist(path.Dir(dstfile)) return } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/config.go����������������������������������������������������������������������000664 �000000 �000000 �00000004521 13753517240 015767� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "encoding/json" "io/ioutil" "os" "path" "sync" ) var ( DefaultHomeConfigPrefix = os.Getenv("HOME") + "/.config/deepin/" DefaultSystemConfigPrefix = "/var/cache/deepin/" DefaultConfigExt = ".json" ) type Config struct { configFile string lock sync.Mutex } func (c *Config) Lock() { c.lock.Lock() } func (c *Config) Unlock() { c.lock.Unlock() } func (c *Config) SetConfigFile(file string) { c.configFile = file } func (c *Config) GetConfigFile() string { return c.configFile } func (c *Config) SetConfigName(name string) { c.SetConfigFile(DefaultHomeConfigPrefix + name + DefaultConfigExt) } func (c *Config) SetSystemConfigName(name string) { c.SetConfigFile(DefaultSystemConfigPrefix + name + DefaultConfigExt) } func (c *Config) IsConfigFileExists() bool { return IsFileExist(c.configFile) } func (c *Config) RemoveConfigFile() error { return os.Remove(c.configFile) } func (c *Config) Load(v interface{}) (err error) { if IsFileExist(c.configFile) { var fileContent []byte fileContent, err = ioutil.ReadFile(c.configFile) if err != nil { return } err = json.Unmarshal(fileContent, v) } else { err = c.Save(v) } return } func (c *Config) Save(v interface{}) (err error) { c.Lock() defer c.Unlock() _ = EnsureDirExist(path.Dir(c.configFile)) var fileContent []byte fileContent, err = c.GetFileContentToSave(v) if err != nil { return } err = ioutil.WriteFile(c.configFile, fileContent, 0644) return } func (c *Config) GetFileContentToSave(v interface{}) (fileContent []byte, err error) { fileContent, err = json.Marshal(v) return } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/config_test.go�����������������������������������������������������������������000664 �000000 �000000 �00000002506 13753517240 017027� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( C "gopkg.in/check.v1" ) type testConfig struct { core Config Data string } func newTestConfig() (c *testConfig) { c = &testConfig{} c.core.SetConfigName("test") return } func (c *testConfig) save() error { return c.core.Save(c) } func (c *testConfig) load() { _ = c.core.Load(c) } func (*testWrapper) TestConfig(c *C.C) { conf := newTestConfig() _ = conf.core.RemoveConfigFile() conf.Data = "data" err := conf.save() if err != nil { c.Skip("Save config failed:" + err.Error()) return } conf.Data = "" conf.load() c.Check(conf.Data, C.Equals, "data") } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/file.go������������������������������������������������������������������������000664 �000000 �000000 �00000010134 13753517240 015436� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "fmt" "io" "os" "path" ) func CopyFile(src, dest string) (err error) { if dest == src { return nil } sf, err := os.Open(src) if err != nil { return } defer sf.Close() df, err := os.Create(dest) if err != nil { return } defer df.Close() _, err = io.Copy(df, sf) return } func CopyDir(src, dest string) error { sInfo, err := os.Stat(src) if err != nil { return err } return iterCopyDir(src, dest, sInfo.Mode()) } func MoveDir(src, dest string) error { if !IsDir(src) { return fmt.Errorf("%q not a dir", src) } err := CopyDir(src, dest) if err != nil { return err } return os.RemoveAll(src) } func MoveFile(src, dest string) error { if IsDir(src) { return fmt.Errorf("%q not a file", src) } err := CopyFile(src, dest) if err != nil { return err } return os.RemoveAll(src) } func IsFileExist(path string) bool { // if is uri path, ensure it decoded path = DecodeURI(path) _, err := os.Stat(path) return err == nil || os.IsExist(err) } func IsDir(path string) bool { // if is uri path, ensure it decoded path = DecodeURI(path) if IsSymlink(path) { return symlinkIsDir(path) } f, err := os.Stat(path) if err != nil { return false } return f.IsDir() } func SymlinkFile(src, dest string) error { if !IsFileExist(src) { return fmt.Errorf("The src file '%s' not exist.", src) } if IsFileExist(dest) { if !IsSymlink(dest) { return fmt.Errorf("The dest file '%s' already exists.", dest) } err := os.Remove(dest) if err != nil { return err } } return os.Symlink(src, dest) } func IsSymlink(path string) bool { // if is uri path, ensure it decoded path = DecodeURI(path) f, err := os.Lstat(path) if err != nil { return false } if f.Mode()&os.ModeSymlink == os.ModeSymlink { return true } return false } func EnsureDirExist(path string) error { return os.MkdirAll(path, 0755) } func EnsureDirExistWithPerm(path string, perm os.FileMode) error { // TODO if path exists with wrong perm, fix it return os.MkdirAll(path, perm) } func CreateFile(filename string) error { fp, err := os.Create(filename) if err != nil { return err } return fp.Close() } func GetFilesInDir(dir string) ([]string, error) { if !IsDir(dir) { return nil, fmt.Errorf("The '%s' is not a dir", dir) } fp, err := os.Open(dir) if err != nil { return nil, err } defer fp.Close() names, err := fp.Readdirnames(0) if err != nil { return nil, err } var files []string for _, name := range names { file := path.Join(dir, name) files = append(files, file) } return files, nil } func iterCopyDir(src, dest string, mode os.FileMode) error { sr, err := os.Open(src) if err != nil { return err } defer sr.Close() finfos, err := sr.Readdir(0) if err != nil { return err } err = os.MkdirAll(dest, mode) if err != nil { return err } for _, fi := range finfos { sTmp := path.Join(src, fi.Name()) dTmp := path.Join(dest, fi.Name()) var err error if fi.IsDir() { err = iterCopyDir(sTmp, dTmp, fi.Mode()) } else { err = CopyFile(sTmp, dTmp) } if err != nil { return err } } return nil } // If 'link' is relative symlink, we need to cd it's parent dir. func symlinkIsDir(link string) bool { target, err := os.Readlink(link) if err != nil { return false } dir := path.Dir(link) if len(dir) == 0 { return IsDir(target) } return IsDir(path.Join(dir, target)) } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/file_test.go�������������������������������������������������������������������000664 �000000 �000000 �00000005473 13753517240 016507� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( C "gopkg.in/check.v1" "os" "sort" ) func (*testWrapper) TestCopyDir(c *C.C) { src := "testdata/copy-src" dest := "testdata/copy-dest" pwd, _ := os.Getwd() defer func() { _ = os.Chdir(pwd) }() err := os.RemoveAll(dest) if err != nil { return } err = CopyDir(src, dest) if err != nil { c.Error(err) return } sf, _ := os.Open(src) defer sf.Close() df, _ := os.Open(dest) defer df.Close() sNames, _ := sf.Readdirnames(-1) dNames, _ := df.Readdirnames(-1) sort.Strings(sNames) sort.Strings(dNames) for i := 0; i < len(sNames); i++ { c.Check(sNames[i], C.Equals, dNames[i]) } } func (*testWrapper) TestCreateFile(c *C.C) { err := CreateFile("") c.Check(err, C.NotNil) file := "testdata/create-testfile" err = CreateFile(file) c.Check(err, C.IsNil) os.Remove(file) file = "testdata/xxx/create-testfile" err = CreateFile(file) c.Check(err, C.NotNil) } func (*testWrapper) TestSymlinkFile(c *C.C) { var datas = []struct { src string dest string success bool }{ { src: "testdata/testfile", dest: "testdata/test_symlink", success: true, }, { src: "testdata/testfile", dest: "testdata/test1", success: false, }, { src: "testdata/testfile_xxx", dest: "testdata/test_symlink", success: false, }, } for _, data := range datas { if data.success { c.Check(SymlinkFile(data.src, data.dest), C.Equals, nil) os.Remove(data.dest) } else { c.Check(SymlinkFile(data.src, data.dest), C.Not(C.Equals), nil) } } } func (*testWrapper) TestGetFiles(c *C.C) { var datas = []struct { dir string length int ret bool }{ { dir: "testdata/test-get_files", length: 2, ret: true, }, { dir: "testdata/xxx", length: 0, ret: false, }, { dir: "testdata/testfile", length: 0, ret: false, }, } for _, data := range datas { files, err := GetFilesInDir(data.dir) c.Check(len(files), C.Equals, data.length) if data.ret { c.Check(err, C.Equals, nil) } else { c.Check(err, C.Not(C.Equals), nil) } } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/filesystem.go������������������������������������������������������������������000664 �000000 �000000 �00000002775 13753517240 016717� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils /* #include <stdlib.h> #include <sys/statvfs.h> */ import "C" import "unsafe" import "errors" type FilesystemInfo struct { TotalSize uint64 // byte FreeSize uint64 AvailSize uint64 UsedSize uint64 } func QueryFilesytemInfo(path string) (*FilesystemInfo, error) { buf := C.struct_statvfs{} cpath := C.CString(path) defer C.free(unsafe.Pointer(cpath)) if C.statvfs(cpath, &buf) != 0 { return nil, errors.New("Statvfs error.") } total := uint64(buf.f_blocks) * uint64(buf.f_frsize) free := uint64(buf.f_bfree) * uint64(buf.f_frsize) //Get real avail size instead of free size. avail := uint64(buf.f_bavail) * uint64(buf.f_frsize) return &FilesystemInfo{ TotalSize: total, FreeSize: free, AvailSize: avail, UsedSize: total - free, }, nil } ���go-lib-5.6.0.9/utils/keyfile.go���������������������������������������������������������������������000664 �000000 �000000 �00000013110 13753517240 016144� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "fmt" "os" "sync" "pkg.deepin.io/gir/glib-2.0" ) var ( kfLocker sync.Mutex ) func NewKeyFileFromFile(file string) (*glib.KeyFile, error) { kfLocker.Lock() defer kfLocker.Unlock() var kFile = glib.NewKeyFile() _, err := kFile.LoadFromFile(file, glib.KeyFileFlagsKeepComments| glib.KeyFileFlagsKeepTranslations) if err != nil { kFile.Free() return nil, err } return kFile, nil } func ReadKeyFromKeyFile(filename, group, key string, t interface{}) (interface{}, bool) { if !IsFileExist(filename) { return nil, false } kFile, err := NewKeyFileFromFile(filename) if err != nil { return nil, false } defer kFile.Free() switch t.(type) { case bool: value, err := kFile.GetBoolean(group, key) if err != nil { return nil, false } return value, true case []bool: _, value, err := kFile.GetBooleanList(group, key) if err != nil { return nil, false } return value, true case int, int32, uint32: value, err := kFile.GetInteger(group, key) if err != nil { return nil, false } return int32(value), true case int64: value, err := kFile.GetInt64(group, key) if err != nil { return nil, false } return int64(value), true case uint64: value, err := kFile.GetUint64(group, key) if err != nil { return nil, false } return uint64(value), true case []int, []int32, []uint32, []int64, []uint64: _, value, err := kFile.GetIntegerList(group, key) if err != nil { return nil, false } list := []int32{} for _, v := range value { list = append(list, int32(v)) } return list, true case float32, float64: value, err := kFile.GetDouble(group, key) if err != nil { return nil, false } return float64(value), true case []float32, []float64: _, value, err := kFile.GetDoubleList(group, key) if err != nil { return nil, false } list := []float64{} for _, v := range value { list = append(list, float64(v)) } return list, true case string: value, err := kFile.GetString(group, key) if err != nil { return nil, false } return value, true case []string: _, value, err := kFile.GetStringList(group, key) if err != nil { return nil, false } return value, true default: value, err := kFile.GetValue(group, key) if err != nil { return nil, false } return value, true } } func WriteKeyToKeyFile(filename, group, key string, value interface{}) bool { if len(filename) == 0 { return false } if !IsFileExist(filename) { err := CreateFile(filename) if err != nil { return false } } kFile, err := NewKeyFileFromFile(filename) if err != nil { return false } defer kFile.Free() switch vType := value.(type) { case bool: kFile.SetBoolean(group, key, vType) case []bool: kFile.SetBooleanList(group, key, vType) case int: kFile.SetInteger(group, key, int32(vType)) case int32: kFile.SetInteger(group, key, int32(vType)) case uint32: kFile.SetInteger(group, key, int32(vType)) case []int: list := vType tmp := []int32{} for _, l := range list { tmp = append(tmp, int32(l)) } kFile.SetIntegerList(group, key, tmp) case []int32: kFile.SetIntegerList(group, key, vType) case []uint32: list := vType tmp := []int32{} for _, l := range list { tmp = append(tmp, int32(l)) } kFile.SetIntegerList(group, key, tmp) case []int64: list := vType tmp := []int32{} for _, l := range list { tmp = append(tmp, int32(l)) } kFile.SetIntegerList(group, key, tmp) case []uint64: list := vType tmp := []int32{} for _, l := range list { tmp = append(tmp, int32(l)) } kFile.SetIntegerList(group, key, tmp) case int64: kFile.SetInt64(group, key, vType) case uint64: kFile.SetUint64(group, key, vType) case float32: kFile.SetDouble(group, key, float64(vType)) case float64: kFile.SetDouble(group, key, vType) case []float32: list := vType tmp := []float64{} for _, l := range list { tmp = append(tmp, float64(l)) } kFile.SetDoubleList(group, key, tmp) case []float64: kFile.SetDoubleList(group, key, vType) case string: kFile.SetString(group, key, vType) case []string: kFile.SetStringList(group, key, vType) } _, contents, err1 := kFile.ToData() if err1 != nil { return false } ok := WriteStringToKeyFile(filename, string(contents)) return ok } //TODO: Abandoned it //Do't use this interface. func WriteStringToKeyFile(filename, content string) bool { err := WriteStringToFile(filename, content) return err == nil } func WriteStringToFile(filename, content string) error { if len(filename) == 0 { return fmt.Errorf("Not found this file: %q", filename) } kfLocker.Lock() defer kfLocker.Unlock() var swapFile = filename + ".swap" fp, err := os.Create(filename + ".swap") if err != nil { return err } defer func() { _ = fp.Close() }() _, err = fp.WriteString(content) if err != nil { return err } _ = fp.Sync() return os.Rename(swapFile, filename) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/keyfile_test.go����������������������������������������������������������������000664 �000000 �000000 �00000002171 13753517240 017210� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( C "gopkg.in/check.v1" "os" ) func (*testWrapper) TestKeyFile(c *C.C) { file := "testdata/test_keyfile.ini" group := "Test" key := "id" value := "1234" c.Check(WriteKeyToKeyFile(file, group, key, value), C.Equals, true) ifc, ok := ReadKeyFromKeyFile(file, group, key, "") c.Check(ok, C.Equals, true) c.Check(value, C.Equals, ifc.(string)) os.Remove(file) } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/md5.go�������������������������������������������������������������������������000664 �000000 �000000 �00000002152 13753517240 015205� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "crypto/md5" "fmt" "io" "os" ) func SumStrMd5(str string) (string, bool) { return fmt.Sprintf("%x", md5.Sum([]byte(str))), true } func SumFileMd5(filename string) (string, bool) { f, err := os.Open(filename) if err != nil { return "", false } defer f.Close() h := md5.New() _, _ = io.Copy(h, f) return fmt.Sprintf("%x", h.Sum(nil)), true } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/md5_test.go��������������������������������������������������������������������000664 �000000 �000000 �00000002334 13753517240 016246� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( C "gopkg.in/check.v1" ) func (*testWrapper) TestMD5Sum(c *C.C) { testStr := "hello world" if ret, ok := SumStrMd5(testStr); !ok { c.Errorf("SumStrMd5 '%s' Faild", testStr) return } else { c.Check(ret, C.Equals, "5eb63bbbe01eeed093cb22bb8f5acdc3") } testFile := "testdata/testfile" if ret, ok := SumFileMd5(testFile); !ok { c.Errorf("SumFileMd5 '%s' Failed", testFile) return } else { c.Check(ret, C.Equals, "0a75266cc21da8c88a940b00d4d535b7") } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/os.go��������������������������������������������������������������������������000664 �000000 �000000 �00000004664 13753517240 015153� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils // #include <stdlib.h> import "C" import "unsafe" import ( "bytes" "fmt" "os" "os/exec" "os/user" "strings" "time" ) func IsEnvExists(envName string) (ok bool) { for _, e := range os.Environ() { if strings.HasPrefix(e, envName+"=") { ok = true break } } return } func UnsetEnv(envName string) (err error) { doUnsetEnvC(envName) // call C.unsetenv() is necessary envs := os.Environ() newEnvsData := make(map[string]string) for _, e := range envs { a := strings.SplitN(e, "=", 2) var name, value string if len(a) == 2 { name = a[0] value = a[1] } else { name = a[0] value = "" } if name != envName { newEnvsData[name] = value } } os.Clearenv() for e, v := range newEnvsData { err = os.Setenv(e, v) if err != nil { return } } return } func doUnsetEnvC(envName string) { cname := C.CString(envName) defer C.free(unsafe.Pointer(cname)) C.unsetenv(cname) } func GetUserName() string { info, err := user.Current() if err != nil { return "" } return info.Username } func ExecAndWait(timeout int, name string, arg ...string) (stdout, stderr string, err error) { cmd := exec.Command(name, arg...) var bufStdout, bufStderr bytes.Buffer cmd.Stdout = &bufStdout cmd.Stderr = &bufStderr err = cmd.Start() if err != nil { return } // wait for process finished done := make(chan error) go func() { done <- cmd.Wait() }() select { case <-time.After(time.Duration(timeout) * time.Second): if err = cmd.Process.Kill(); err != nil { return } <-done err = fmt.Errorf("time out and process was killed") case err = <-done: stdout = bufStdout.String() stderr = bufStderr.String() if err != nil { return } } return } ����������������������������������������������������������������������������go-lib-5.6.0.9/utils/schemas.go���������������������������������������������������������������������000664 �000000 �000000 �00000002513 13753517240 016144� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "fmt" "pkg.deepin.io/gir/gio-2.0" ) func CheckAndNewGSettings(schema string) (*gio.Settings, error) { if !IsGSchemaExist(schema) { return nil, fmt.Errorf("Not found this schema: %s", schema) } return gio.NewSettings(schema), nil } func IsGSchemaExist(schema string) bool { if isSchemaInList(schema, gio.SettingsListSchemas()) || isSchemaInList(schema, gio.SettingsListRelocatableSchemas()) { return true } return false } func isSchemaInList(schema string, list []string) bool { for _, s := range list { if schema == s { return true } } return false } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/schemas_test.go����������������������������������������������������������������000664 �000000 �000000 �00000003142 13753517240 017202� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import C "gopkg.in/check.v1" type schemaTest struct { schema string exist bool } func (*testWrapper) TestGSchemaIsExist(c *C.C) { schemas := []string{ "com.deepin.wacom", "com.deepin.touchpad", } list1 := []schemaTest{ schemaTest{"com.deepin.wacom", true}, schemaTest{"com.deepin.touchpad", true}, } list2 := []schemaTest{ schemaTest{"org.123.123", false}, schemaTest{"org/11/11", false}, schemaTest{"sdsdsvfdsfs", false}, schemaTest{"/dsfd/assasd", false}, schemaTest{".sds.sadsd.", false}, schemaTest{"-sds-sds-ss", false}, schemaTest{"(jjjj)", false}, schemaTest{"$fgg$", false}, } for _, t := range list1 { c.Check(isSchemaInList(t.schema, schemas), C.Equals, t.exist) } for _, t := range list2 { c.Check(IsGSchemaExist(t.schema), C.Equals, t.exist) c.Check(isSchemaInList(t.schema, schemas), C.Equals, t.exist) } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/����������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 016002� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/copy-dest/������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 017711� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/copy-dest/file1�������������������������������������������������������000664 �000000 �000000 �00000000050 13753517240 020627� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������sdddddddddsdxcvdxs sddddfsdsfffxccccccc ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/copy-dest/test/�������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 020670� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/copy-dest/test/file2��������������������������������������������������000664 �000000 �000000 �00000000032 13753517240 021607� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������qwsancsdjhdj sdvsdvjsdkjv ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/copy-src/�������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 017541� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/copy-src/file1��������������������������������������������������������000664 �000000 �000000 �00000000050 13753517240 020457� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������sdddddddddsdxcvdxs sddddfsdsfffxccccccc ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/copy-src/test/��������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 020520� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/copy-src/test/file2���������������������������������������������������000664 �000000 �000000 �00000000032 13753517240 021437� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������qwsancsdjhdj sdvsdvjsdkjv ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/test-get_files/�������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 020720� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/test-get_files/file1��������������������������������������������������000777 �000000 �000000 �00000000000 13753517240 023034� 2../test1��������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/test-get_files/file2��������������������������������������������������000777 �000000 �000000 �00000000000 13753517240 023614� 2../testfile�����������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/test1�����������������������������������������������������������������000664 �000000 �000000 �00000000015 13753517240 016761� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������test for md5 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/testdata/testfile��������������������������������������������������������������000664 �000000 �000000 �00000000015 13753517240 017540� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������test for md5 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/uri.go�������������������������������������������������������������������������000664 �000000 �000000 �00000007647 13753517240 015335� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "net/url" "strings" ) const ( SCHEME_FILE = "file://" SCHEME_FTP = "ftp://" SCHEME_HTTP = "http://" SCHEME_HTTPS = "https://" SCHEME_SMB = "smb://" ) func IsURI(s string) (ok bool) { scheme := GetURIScheme(s) if len(scheme) > 0 { ok = true } return } func GetURIScheme(uri string) (scheme string) { i := strings.Index(uri, "://") if i >= 0 { scheme = uri[0:i] } return } func GetURIContent(uri string) (content string) { i := strings.Index(uri, "://") if i >= 0 { content = uri[i+3:] } return } func EncodeURI(content, scheme string) (uri string) { u := url.URL{} if IsURI(content) { u.Path = DecodeURI(content) } else { u.Path = content } uri = scheme + u.String() return } func DecodeURI(uri string) (content string) { if IsURI(uri) { u, err := url.Parse(uri) if err != nil { return } content = u.Path } else { content = uri } return } func URIToPath(uri string) string { // TODO // return DecodeURI(uri) if isBeginWithStr(uri, SCHEME_FILE) { return uri[7:] } else if isBeginWithStr(uri, SCHEME_FTP) { return uri[6:] } else if isBeginWithStr(uri, SCHEME_HTTP) { return uri[7:] } else if isBeginWithStr(uri, SCHEME_HTTPS) { return uri[8:] } else if isBeginWithStr(uri, SCHEME_SMB) { return uri[6:] } else if isBeginWithStr(uri, "/") { return uri } return "" } func PathToURI(filepath, scheme string) string { // TODO // return EncodeURI(filepath, scheme) if len(filepath) < 1 || len(scheme) < 1 { return "" } switch scheme { case SCHEME_FILE: return pathToFileURI(filepath) case SCHEME_FTP: return pathToFtpURI(filepath) case SCHEME_HTTP: return pathToHttpURI(filepath) case SCHEME_HTTPS: return pathToHttpsURI(filepath) case SCHEME_SMB: return pathToSmbURI(filepath) } return "" } // TODO func pathToFileURI(filepath string) string { filepath = deleteStartSpace(filepath) if isBeginWithStr(filepath, "/") { return SCHEME_FILE + filepath } else if isBeginWithStr(filepath, SCHEME_FILE) { return filepath } return "" } func pathToFtpURI(filepath string) string { filepath = deleteStartSpace(filepath) if isBeginWithStr(filepath, "/") { return SCHEME_FTP + filepath } else if isBeginWithStr(filepath, SCHEME_FTP) { return filepath } return "" } func pathToHttpURI(filepath string) string { filepath = deleteStartSpace(filepath) if isBeginWithStr(filepath, "/") { return SCHEME_HTTP + filepath } else if isBeginWithStr(filepath, SCHEME_HTTP) { return filepath } return "" } func pathToHttpsURI(filepath string) string { filepath = deleteStartSpace(filepath) if isBeginWithStr(filepath, "/") { return SCHEME_HTTPS + filepath } else if isBeginWithStr(filepath, SCHEME_HTTPS) { return filepath } return "" } func pathToSmbURI(filepath string) string { filepath = deleteStartSpace(filepath) if isBeginWithStr(filepath, "/") { return SCHEME_SMB + filepath } else if isBeginWithStr(filepath, SCHEME_SMB) { return filepath } return "" } func deleteStartSpace(str string) string { // TODO if len(str) <= 0 { return "" } tmp := strings.TrimLeft(str, " ") return tmp } func isBeginWithStr(str, substr string) bool { return strings.HasPrefix(str, substr) } �����������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/user_special_dir.go������������������������������������������������������������000664 �000000 �000000 �00000002224 13753517240 020034� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "os/user" "path" ) func GetHomeDir() string { info, err := user.Current() if err != nil { return "" } return info.HomeDir } func GetConfigDir() string { if homeDir := GetHomeDir(); len(homeDir) > 0 { return path.Join(homeDir, ".config") } return "" } func GetCacheDir() string { if homeDir := GetHomeDir(); len(homeDir) > 0 { return path.Join(homeDir, ".cache") } return "" } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/utils.go�����������������������������������������������������������������������000664 �000000 �000000 �00000004514 13753517240 015664� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "crypto/rand" "fmt" "io" "reflect" ) func IsElementEqual(e1, e2 interface{}) bool { if e1 == nil && e2 == nil { return true } return reflect.DeepEqual(e1, e2) } func IsElementInList(e interface{}, list interface{}) bool { if list == nil { return false } v := reflect.ValueOf(list) if !v.IsValid() { return false } if v.Type().Kind() == reflect.Slice || v.Type().Kind() == reflect.Array { l := v.Len() for i := 0; i < l; i++ { if IsElementEqual(e, v.Index(i).Interface()) { return true } } } return false } func GenUuid() string { uuid := make([]byte, 16) n, err := io.ReadFull(rand.Reader, uuid) if n != len(uuid) || err != nil { panic("This can failed?") } // variant bits; see section 4.1.1 uuid[8] = uuid[8]&^0xc0 | 0x80 // version 4 (pseudo-random); see section 4.1.3 uuid[6] = uuid[6]&^0xf0 | 0x40 return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]) } func RandString(n int) string { const alphanum = "0123456789abcdef" var bytes = make([]byte, n) _, _ = rand.Read(bytes) for i, b := range bytes { bytes[i] = alphanum[b%byte(len(alphanum))] } return string(bytes) } func IsInterfaceNil(v interface{}) bool { if v == nil { return true } value := reflect.ValueOf(v) // The argument must be a chan, func, interface, map, pointer, or // slice value; if it is not, Value.IsNil panics. switch value.Kind() { case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Interface, reflect.Slice: return value.IsNil() } // should be a not nil type for rest cases return false } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/utils_test.go������������������������������������������������������������������000664 �000000 �000000 �00000022070 13753517240 016720� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( C "gopkg.in/check.v1" "io/ioutil" "os" "regexp" "testing" ) type testWrapper struct{} // Hook up gocheck into the "go test" runner. func Test(t *testing.T) { C.TestingT(t) } func init() { C.Suite(&testWrapper{}) } func (*testWrapper) TestIsURI(c *C.C) { var data = []struct { value string result bool }{ {"", false}, {":", false}, {"://", false}, {"file:/", false}, {"file://", true}, {"file:///", true}, {"file:///usr/share", true}, {"unknown:///usr/share", true}, } for _, d := range data { c.Check(IsURI(d.value), C.Equals, d.result) } } func (*testWrapper) TestGetURIScheme(c *C.C) { var data = []struct { value, result string }{ {"", ""}, {":", ""}, {"://", ""}, {"file:/", ""}, {"file://", "file"}, {"file:///", "file"}, {"file:///usr/share", "file"}, {"unknown:///usr/share", "unknown"}, } for _, d := range data { c.Check(GetURIScheme(d.value), C.Equals, d.result) } } func (*testWrapper) TestGetURIContent(c *C.C) { var data = []struct { value, result string }{ {"", ""}, {":", ""}, {"://", ""}, {"file:/", ""}, {"file://", ""}, {"file:///", "/"}, {"file:///usr/share", "/usr/share"}, {"unknown:///usr/share", "/usr/share"}, } for _, d := range data { c.Check(GetURIContent(d.value), C.Equals, d.result) } } func (*testWrapper) TestEncodeURI(c *C.C) { var data = []struct { value, scheme, result string }{ {"", SCHEME_FILE, "file://"}, {"/usr/lib/share/test", SCHEME_FILE, "file:///usr/lib/share/test"}, {"/usr/lib/share/test", SCHEME_FTP, "ftp:///usr/lib/share/test"}, {"/usr/lib/share/test", SCHEME_HTTP, "http:///usr/lib/share/test"}, {"/usr/lib/share/test", SCHEME_HTTPS, "https:///usr/lib/share/test"}, {"/usr/lib/share/test", SCHEME_SMB, "smb:///usr/lib/share/test"}, {"/usr/lib/share/中文路径/1 2 3", SCHEME_FILE, "file:///usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203"}, {"file:///usr/lib/share/test", SCHEME_FILE, "file:///usr/lib/share/test"}, {"file:///usr/lib/share/test", SCHEME_FTP, "ftp:///usr/lib/share/test"}, {"file:///usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203", SCHEME_FILE, "file:///usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203"}, {"file:///usr/lib/share/中文路径/1 2 3", SCHEME_FILE, "file:///usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203"}, {"/usr/lib/share/中文路径/1 2 3", SCHEME_FILE, "file:///usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203"}, {"/home/fsh/Wallpapers/中文 name with %.jpg", SCHEME_FILE, "file:///home/fsh/Wallpapers/%E4%B8%AD%E6%96%87%20name%20with%20%25.jpg"}, {"file:///home/fsh/Wallpapers/%E4%B8%AD%E6%96%87%20name%20with%20%25.jpg", SCHEME_FILE, "file:///home/fsh/Wallpapers/%E4%B8%AD%E6%96%87%20name%20with%20%25.jpg"}, {"file:///usr/lib/share/test", SCHEME_FILE, "file:///usr/lib/share/test"}, } for _, d := range data { c.Check(EncodeURI(d.value, d.scheme), C.Equals, d.result) } } func (*testWrapper) TestDecodeURI(c *C.C) { var data = []struct { value, result string }{ {"", ""}, {"file:///usr/lib/share/test", "/usr/lib/share/test"}, {"ftp:///usr/lib/share/test", "/usr/lib/share/test"}, {"http:///usr/lib/share/test", "/usr/lib/share/test"}, {"https:///usr/lib/share/test", "/usr/lib/share/test"}, {"smb:///usr/lib/share/test", "/usr/lib/share/test"}, {"file:///usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203", "/usr/lib/share/中文路径/1 2 3"}, {"file:///usr/lib/share/中文路径/1 2 3", "/usr/lib/share/中文路径/1 2 3"}, {"file:///home/fsh/Wallpapers/%E4%B8%AD%E6%96%87%20name%20with%20%25.jpg", "/home/fsh/Wallpapers/中文 name with %.jpg"}, {"/usr/lib/share/test", "/usr/lib/share/test"}, } for _, d := range data { c.Check(DecodeURI(d.value), C.Equals, d.result) } } func (*testWrapper) TestPathToURI(c *C.C) { var data = []struct { value, scheme, result string }{ {"", SCHEME_FILE, ""}, {"/usr/lib/share/test", SCHEME_FILE, "file:///usr/lib/share/test"}, {"/usr/lib/share/test", SCHEME_FTP, "ftp:///usr/lib/share/test"}, {"/usr/lib/share/test", SCHEME_HTTP, "http:///usr/lib/share/test"}, {"/usr/lib/share/test", SCHEME_HTTPS, "https:///usr/lib/share/test"}, {"/usr/lib/share/test", SCHEME_SMB, "smb:///usr/lib/share/test"}, {"/usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203", SCHEME_FILE, "file:///usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203"}, } for _, d := range data { c.Check(PathToURI(d.value, d.scheme), C.Equals, d.result) } } func (*testWrapper) TestURIToPath(c *C.C) { var data = []struct { value, result string }{ {"", ""}, {"file:///usr/lib/share/test", "/usr/lib/share/test"}, {"ftp:///usr/lib/share/test", "/usr/lib/share/test"}, {"http:///usr/lib/share/test", "/usr/lib/share/test"}, {"https:///usr/lib/share/test", "/usr/lib/share/test"}, {"smb:///usr/lib/share/test", "/usr/lib/share/test"}, {"file:///usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203", "/usr/lib/share/%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84/1%202%203"}, {"/usr/lib/share/test", "/usr/lib/share/test"}, } for _, d := range data { c.Check(URIToPath(d.value), C.Equals, d.result) } } func (*testWrapper) TestIsFileExist(c *C.C) { var data = []struct { path, uri string }{ {"/tmp/deepin_test_file", "file:///tmp/deepin_test_file"}, {"/tmp/deepin_test_中文 name with %.jpg", "file:///tmp/deepin_test_%E4%B8%AD%E6%96%87%20name%20with%20%25.jpg"}, {"/tmp/deepin_test_file 中文路径", "file:///tmp/deepin_test_file%20%E4%B8%AD%E6%96%87%E8%B7%AF%E5%BE%84"}, {"/tmp/deepin_test_file 中文路径", "file:///tmp/deepin_test_file 中文路径"}, } for _, d := range data { os.Remove(d.path) c.Check(IsFileExist(d.path), C.Equals, false) _ = ioutil.WriteFile(d.path, nil, 0644) c.Check(IsFileExist(d.path), C.Equals, true) c.Check(IsFileExist(d.uri), C.Equals, true) os.Remove(d.path) } } func (*testWrapper) TestIsDir(c *C.C) { var infos = []struct { dir string ok bool }{ { dir: "testdata", ok: true, }, // test symlink dir //{ //dir: "testdata/utils", //ok: true, //}, { dir: "testdata/test1", ok: false, }, } for _, info := range infos { c.Check(IsDir(info.dir), C.Equals, info.ok) } } func (*testWrapper) TestIsSymlink(c *C.C) { testFile := "/tmp/deepin_test_file" testSymlink := "/tmp/deepin_test_symlink" os.Remove(testSymlink) c.Check(IsSymlink(testSymlink), C.Equals, false) _ = ioutil.WriteFile(testFile, nil, 0644) _ = os.Symlink(testFile, testSymlink) c.Check(IsSymlink(testSymlink), C.Equals, true) os.Remove(testSymlink) os.Remove(testFile) } func (*testWrapper) TestIsEnvExists(c *C.C) { testEnvName := "test_is_env_exists" testEnvValue := "test_env_value" c.Check(false, C.Equals, IsEnvExists(testEnvName)) os.Setenv(testEnvName, testEnvValue) c.Check(true, C.Equals, IsEnvExists(testEnvName)) } func (*testWrapper) TestUnsetEnv(c *C.C) { testEnvName := "test_unset_env" testEnvValue := "test_env_value" c.Check(false, C.Equals, IsEnvExists(testEnvName)) os.Setenv(testEnvName, testEnvValue) c.Check(true, C.Equals, IsEnvExists(testEnvName)) envCount := len(os.Environ()) _ = UnsetEnv(testEnvName) c.Check(false, C.Equals, IsEnvExists(testEnvName)) c.Check(len(os.Environ()), C.Equals, envCount-1) } func (*testWrapper) TestGenUuid(c *C.C) { validUuid := regexp.MustCompile(`^[a-z0-9]{8}(-[a-z0-9]{4}){3}-[a-z0-9]{12}$`) var lastUuid string for i := 0; i < 5; i++ { currentUuid := GenUuid() c.Check(currentUuid != lastUuid, C.Equals, true) c.Check(validUuid.MatchString(currentUuid), C.Equals, true) lastUuid = currentUuid } } func (*testWrapper) TestRandString(c *C.C) { validStr := regexp.MustCompile(`^[0-za-f]{10}$`) var lastStr string for i := 0; i < 5; i++ { currentStr := RandString(10) c.Check(currentStr != lastStr, C.Equals, true) c.Check(validStr.MatchString(currentStr), C.Equals, true) lastStr = currentStr } } func (*testWrapper) TestIsInterfaceNil(c *C.C) { c.Check(IsInterfaceNil(nil), C.Equals, true) c.Check(IsInterfaceNil(1), C.Equals, false) c.Check(IsInterfaceNil(true), C.Equals, false) c.Check(IsInterfaceNil(""), C.Equals, false) c.Check(IsInterfaceNil("str"), C.Equals, false) var a1 []int = nil c.Check(IsInterfaceNil(a1), C.Equals, true) var a2 []int = make([]int, 0) c.Check(IsInterfaceNil(a2), C.Equals, false) var ifcWrapper interface{} = "str" c.Check(IsInterfaceNil(ifcWrapper), C.Equals, false) } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/utils/watch_proxy.go�����������������������������������������������������������������000664 �000000 �000000 �00000005375 13753517240 017101� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package utils import ( "sync" "github.com/fsnotify/fsnotify" ) type WatchProxy struct { watcher *fsnotify.Watcher eventHandler func(fsnotify.Event) errorHandler func(error) fileList []string end chan bool endFlag bool lock sync.Mutex } func NewWatchProxy() *WatchProxy { w := &WatchProxy{} var err error w.watcher, err = fsnotify.NewWatcher() if err != nil { return nil } w.end = make(chan bool, 1) w.setEndFlag(true) return w } func (w *WatchProxy) setFileListWatch() { if w.watcher == nil { return } for _, filename := range w.fileList { _ = w.watcher.Add(filename) } } func (w *WatchProxy) removeFileListWatch() { if w.watcher == nil { return } for _, filename := range w.fileList { _ = w.watcher.Remove(filename) } } func (w *WatchProxy) SetFileList(fileList []string) { w.fileList = fileList } func (w *WatchProxy) SetEventHandler(f func(fsnotify.Event)) { w.eventHandler = f } func (w *WatchProxy) SetErrorHandler(f func(error)) { w.errorHandler = f } func (w *WatchProxy) ResetFileListWatch() { w.removeFileListWatch() w.setFileListWatch() } func (w *WatchProxy) StartWatch() { if !w.endFlag || w.eventHandler == nil { return } w.setEndFlag(false) if len(w.fileList) == 0 || w.watcher == nil { w.setEndFlag(true) return } w.setFileListWatch() for { select { case ev, ok := <-w.watcher.Events: if !ok { w.ResetFileListWatch() break } if w.eventHandler == nil { break } w.eventHandler(ev) case err, ok := <-w.watcher.Errors: if !ok { w.ResetFileListWatch() break } if w.errorHandler == nil { break } w.errorHandler(err) case <-w.end: if w.watcher == nil { return } w.watcher.Close() return } } } func (w *WatchProxy) EndWatch() { if !w.endFlag { w.setEndFlag(true) w.removeFileListWatch() w.end <- true } } func (w *WatchProxy) setEndFlag(value bool) { w.lock.Lock() w.endFlag = value w.lock.Unlock() } /** * Todo: func (w *WatchProxy) RestartWatch() {} **/ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/���������������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 013613� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/basedir/�������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015224� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/basedir/basedir.go���������������������������������������������������������������000664 �000000 �000000 �00000007212 13753517240 017166� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package basedir // XDG Base Directory Specification import ( "errors" "os" "os/user" "path/filepath" "strconv" "strings" "syscall" ) func GetUserHomeDir() string { dir := os.Getenv("HOME") if dir != "" { return filepath.Clean(dir) } user, err := user.Current() if err != nil { return "" } return filepath.Clean(user.HomeDir) } func GetUserDataDir() string { // default $HOME/.local/share defaultDir := filepath.Join(GetUserHomeDir(), ".local/share") return getUserDir("XDG_DATA_HOME", defaultDir) } func GetSystemDataDirs() []string { defaultDirs := []string{"/usr/local/share", "/usr/share"} return getSystemDirs("XDG_DATA_DIRS", defaultDirs) } func GetUserConfigDir() string { // default $HOME/.config defaultDir := filepath.Join(GetUserHomeDir(), ".config") return getUserDir("XDG_CONFIG_HOME", defaultDir) } func GetSystemConfigDirs() []string { defaultDirs := []string{"/etc/xdg"} return getSystemDirs("XDG_CONFIG_DIRS", defaultDirs) } func GetUserCacheDir() string { defaultDir := filepath.Join(GetUserHomeDir(), ".cache") return getUserDir("XDG_CACHE_HOME", defaultDir) } func GetUserRuntimeDir(strict bool) (string, error) { dir := os.Getenv("XDG_RUNTIME_DIR") if dir == "" || !filepath.IsAbs(dir) { if strict { return "", errors.New("env $XDG_RUNTIME_DIR is invalid") } // fallback runtime user dir fallback := "/tmp/goxdg-runtime-dir-fallback-" + strconv.Itoa(os.Getuid()) create := false fi, err := os.Lstat(fallback) if err != nil { if os.IsNotExist(err) { create = true } else { return "", err } // Lstat ok } else { // The fallback must be a directory if !fi.IsDir() { if err := os.Remove(fallback); err != nil { return "", err } create = true // Must be owned by the user and not accessible by anyone else } else if getFileInfoUid(fi) != os.Getuid() || (fi.Mode()&os.ModePerm) != 0700 { if err := os.RemoveAll(fallback); err != nil { return "", err } create = true } } if create { _ = os.Mkdir(fallback, 0700) } return fallback, nil } return filepath.Clean(dir), nil } func getUserDir(envVarName string, defaultDir string) string { dir := os.Getenv(envVarName) if dir == "" { return defaultDir } if !filepath.IsAbs(dir) { return defaultDir } return filepath.Clean(dir) } func getSystemDirs(envVarName string, defaultDirs []string) []string { dirsEnv := os.Getenv(envVarName) if dirsEnv == "" { return defaultDirs } dirs := filterNotAbs(strings.Split(dirsEnv, ":")) if len(dirs) == 0 { return defaultDirs } return dirs } // filter not absolute path and clean path func filterNotAbs(slice []string) []string { result := make([]string, 0, len(slice)) for _, path := range slice { if !filepath.IsAbs(path) { continue } result = append(result, filepath.Clean(path)) } return result } func getFileInfoUid(fi os.FileInfo) int { return int(fi.Sys().(*syscall.Stat_t).Uid) } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/basedir/basedir_test.go����������������������������������������������������������000664 �000000 �000000 �00000010357 13753517240 020231� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package basedir import ( "fmt" . "github.com/smartystreets/goconvey/convey" "os" "testing" ) func TestGetUserHomeDir(t *testing.T) { Convey("GetUserHomeDir", t, func(c C) { os.Setenv("HOME", "/home/test") dir := GetUserHomeDir() c.So(dir, ShouldEqual, "/home/test") }) } func TestGetUserDataDir(t *testing.T) { Convey("GetUserDataDir", t, func(c C) { os.Setenv("HOME", "/home/test") os.Setenv("XDG_DATA_HOME", "") dir := GetUserDataDir() c.So(dir, ShouldEqual, "/home/test/.local/share") os.Setenv("XDG_DATA_HOME", "a invalid path") dir = GetUserDataDir() c.So(dir, ShouldEqual, "/home/test/.local/share") os.Setenv("XDG_DATA_HOME", "/home/test/xdg") dir = GetUserDataDir() c.So(dir, ShouldEqual, "/home/test/xdg") }) } func TestFilterNotAbs(t *testing.T) { Convey("filterNotAbs", t, func(c C) { result := filterNotAbs([]string{ "a/is/invald", "b/is invalid", "c is invald", "/d/is/ok", "/e/is/ok/"}) c.So(result, ShouldResemble, []string{"/d/is/ok", "/e/is/ok"}) }) } func TestGetSystemDataDirs(t *testing.T) { Convey("GetSystemDataDirs", t, func(c C) { os.Setenv("XDG_DATA_DIRS", "/a:/b:/c") dirs := GetSystemDataDirs() c.So(dirs, ShouldResemble, []string{"/a", "/b", "/c"}) os.Setenv("XDG_DATA_DIRS", "/a:/b/:/c/") dirs = GetSystemDataDirs() c.So(dirs, ShouldResemble, []string{"/a", "/b", "/c"}) os.Setenv("XDG_DATA_DIRS", "/a:/b/:c is invald") dirs = GetSystemDataDirs() c.So(dirs, ShouldResemble, []string{"/a", "/b"}) os.Setenv("XDG_DATA_DIRS", "a/is/invald:b/is invalid :c is invald") dirs = GetSystemDataDirs() c.So(dirs, ShouldResemble, []string{"/usr/local/share", "/usr/share"}) os.Setenv("XDG_DATA_DIRS", "") dirs = GetSystemDataDirs() c.So(dirs, ShouldResemble, []string{"/usr/local/share", "/usr/share"}) }) } func TestGetUserConfigDir(t *testing.T) { Convey("GetUserConfigDir", t, func(c C) { os.Setenv("XDG_CONFIG_HOME", "") os.Setenv("HOME", "/home/test") dir := GetUserConfigDir() c.So(dir, ShouldEqual, "/home/test/.config") os.Setenv("XDG_CONFIG_HOME", "/home/test/myconfig") dir = GetUserConfigDir() c.So(dir, ShouldEqual, "/home/test/myconfig") }) } func TestGetSystemConfigDirs(t *testing.T) { Convey("GetSystemDirs", t, func(c C) { os.Setenv("XDG_CONFIG_DIRS", "/a:/b:/c") dirs := GetSystemConfigDirs() c.So(dirs, ShouldResemble, []string{"/a", "/b", "/c"}) os.Setenv("XDG_CONFIG_DIRS", "") dirs = GetSystemConfigDirs() c.So(dirs, ShouldResemble, []string{"/etc/xdg"}) }) } func TestGetUserCacheDir(t *testing.T) { Convey("GetUserCacheDir", t, func(c C) { os.Setenv("XDG_CACHE_HOME", "/cache/user/a") dir := GetUserCacheDir() c.So(dir, ShouldEqual, "/cache/user/a") os.Setenv("XDG_CACHE_HOME", "") os.Setenv("HOME", "/home/test") dir = GetUserCacheDir() c.So(dir, ShouldEqual, "/home/test/.cache") }) } func TestGetUserRuntimeDir(t *testing.T) { Convey("GetUserRuntimeDir", t, func(c C) { os.Setenv("XDG_RUNTIME_DIR", "/runtime/user/test") dir, err := GetUserRuntimeDir(true) c.So(err, ShouldBeNil) c.So(dir, ShouldEqual, "/runtime/user/test") os.Setenv("XDG_RUNTIME_DIR", "") dir, err = GetUserRuntimeDir(true) c.So(err, ShouldNotBeNil) c.So(dir, ShouldEqual, "") os.Setenv("XDG_RUNTIME_DIR", "a invalid path") dir, err = GetUserRuntimeDir(true) c.So(err, ShouldNotBeNil) c.So(dir, ShouldEqual, "") os.Setenv("XDG_RUNTIME_DIR", "") dir, err = GetUserRuntimeDir(false) c.So(err, ShouldBeNil) c.So(dir, ShouldEqual, fmt.Sprintf("/tmp/goxdg-runtime-dir-fallback-%d", os.Getuid())) }) } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/userdir/�������������������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 015270� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/userdir/testdata/����������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 017101� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/userdir/testdata/user-dirs.dirs��������������������������������������������������000664 �000000 �000000 �00000001162 13753517240 021701� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������# This file is written by xdg-user-dirs-update # If you want to change or add directories, just edit the line you're # interested in. All local changes will be retained on the next run # Format is XDG_xxx_DIR="$HOME/yyy", where yyy is a shell-escaped # homedir-relative path, or XDG_xxx_DIR="/yyy", where /yyy is an # absolute path. No other format is supported. # XDG_DESKTOP_DIR="$HOME/桌面" XDG_DOWNLOAD_DIR="$HOME/下载" XDG_TEMPLATES_DIR="$HOME/.Templates" XDG_PUBLICSHARE_DIR="$HOME/.Public" XDG_DOCUMENTS_DIR="$HOME/文档" XDG_MUSIC_DIR="$HOME/音乐" XDG_PICTURES_DIR="$HOME/图片" XDG_VIDEOS_DIR="$HOME/视频" ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/userdir/testdata2/���������������������������������������������������������������000775 �000000 �000000 �00000000000 13753517240 017163� 5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/userdir/testdata2/user-dirs.dirs�������������������������������������������������000664 �000000 �000000 �00000000407 13753517240 021764� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������XDG_DESKTOP_DIR="$HOME/MyDesktop" XDG_DOWNLOAD_DIR="$HOME/下载" XDG_TEMPLATES_DIR="$HOME/.Templates" XDG_PUBLICSHARE_DIR="$HOME/.Public" XDG_DOCUMENTS_DIR="$HOME/文档" XDG_MUSIC_DIR="$HOME/音乐" XDG_PICTURES_DIR="$HOME/图片" XDG_VIDEOS_DIR="$HOME/视频" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������go-lib-5.6.0.9/xdg/userdir/userdir.go���������������������������������������������������������������000664 �000000 �000000 �00000006735 13753517240 017307� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package userdir import ( "bufio" "bytes" "errors" "io" "os" "path/filepath" "pkg.deepin.io/lib/xdg/basedir" "sync" "unicode" ) const ( Desktop = "DESKTOP" Download = "DOWNLOAD" Templates = "TEMPLATES" PublicShare = "PUBLICSHARE" Documents = "DOCUMENTS" Music = "MUSIC" Pictures = "PICTURES" Videos = "VIDEOS" ) func parseUserDirsConfig(file string) (map[string]string, error) { result := make(map[string]string) homeDir := basedir.GetUserHomeDir() fh, err := os.Open(file) if err != nil { return nil, err } defer fh.Close() reader := bufio.NewReader(fh) for { line, err := reader.ReadBytes('\n') if err == io.EOF { break } else if err != nil { return nil, err } // remove newline at end line = bytes.TrimRightFunc(line, unicode.IsSpace) // skip comments if !bytes.HasPrefix(line, []byte("XDG_")) { continue } parts := bytes.SplitN(line, []byte{'='}, 2) if len(parts) != 2 { continue } key := parts[0] if !bytes.HasSuffix(key, []byte("_DIR")) { continue } // key match regexp /XDG_.*_DIR/ value, err := parseValue(parts[1], homeDir) if err != nil { continue } result[string(key)] = value } return result, nil } var errBadValueFormat = errors.New("bad value format") // Foramt of value is "$HOME/yyy" , where yyy is a shell-escaped // homedir-relative path, or "/yyy", where /yyy is an absolute path. // No other format is supported. func parseValue(val []byte, homeDir string) (string, error) { if len(val) < 3 { // min "/" return "", errBadValueFormat } // The first character and the last character must be equal to a if val[0] != '"' || val[len(val)-1] != '"' { return "", errBadValueFormat } val = val[1 : len(val)-1] var isRelative bool if bytes.HasPrefix(val, []byte("$HOME")) { isRelative = true val = val[5:] } if len(val) == 0 || val[0] != '/' { return "", errBadValueFormat } value := string(val) if isRelative { value = filepath.Join(homeDir, value) } return filepath.Clean(value), nil } var userDirsCache map[string]string var mutex sync.Mutex func Get(dir string) string { mutex.Lock() defer mutex.Unlock() if userDirsCache == nil { cfg, err := parseUserDirsConfig(getUserDirsConfigFile()) if err != nil { return basedir.GetUserHomeDir() } userDirsCache = cfg } if dir, ok := userDirsCache["XDG_"+dir+"_DIR"]; ok { return dir } else { return basedir.GetUserHomeDir() } } func ReloadCache() error { mutex.Lock() defer mutex.Unlock() cfg, err := parseUserDirsConfig(getUserDirsConfigFile()) if err != nil { return err } userDirsCache = cfg return nil } func getUserDirsConfigFile() string { // default ~/.config/user-dirs.dirs return filepath.Join(basedir.GetUserConfigDir(), "user-dirs.dirs") } �����������������������������������go-lib-5.6.0.9/xdg/userdir/userdir_test.go����������������������������������������������������������000664 �000000 �000000 �00000007076 13753517240 020345� 0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������000000 �000000 ������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2016 ~ 2018 Deepin Technology Co., Ltd. * * Author: jouyouyun <jouyouwen717@gmail.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package userdir import ( . "github.com/smartystreets/goconvey/convey" "os" "path/filepath" "testing" ) func TestParseValue(t *testing.T) { homeDir := "/home/test" Convey("parseValue", t, func(c C) { value, err := parseValue([]byte(`"$HOME/Desktop/"`), homeDir) c.So(err, ShouldBeNil) c.So(value, ShouldEqual, "/home/test/Desktop") value, err = parseValue([]byte(`"/home/test/DesktopA"`), homeDir) c.So(err, ShouldBeNil) c.So(value, ShouldEqual, "/home/test/DesktopA") value, err = parseValue([]byte(`"$HOME/"`), homeDir) c.So(err, ShouldBeNil) c.So(value, ShouldEqual, "/home/test") value, err = parseValue([]byte(`"/"`), homeDir) c.So(err, ShouldBeNil) c.So(value, ShouldEqual, "/") value, err = parseValue([]byte(""), homeDir) c.So(err, ShouldNotBeNil) c.So(value, ShouldEqual, "") value, err = parseValue([]byte("$HOME"), homeDir) c.So(err, ShouldNotBeNil) c.So(value, ShouldEqual, "") value, err = parseValue([]byte(`"not abs"`), homeDir) c.So(err, ShouldNotBeNil) c.So(value, ShouldEqual, "") }) } func TestParseUserDirsConfig(t *testing.T) { Convey("parseUserDirsConfig", t, func(c C) { os.Setenv("HOME", "/home/test") cfg, err := parseUserDirsConfig("./testdata/user-dirs.dirs") c.So(err, ShouldBeNil) c.So(cfg, ShouldResemble, map[string]string{"XDG_DESKTOP_DIR": "/home/test/桌面", "XDG_DOCUMENTS_DIR": "/home/test/文档", "XDG_DOWNLOAD_DIR": "/home/test/下载", "XDG_MUSIC_DIR": "/home/test/音乐", "XDG_PICTURES_DIR": "/home/test/图片", "XDG_PUBLICSHARE_DIR": "/home/test/.Public", "XDG_TEMPLATES_DIR": "/home/test/.Templates", "XDG_VIDEOS_DIR": "/home/test/视频"}) }) } func TestGet(t *testing.T) { Convey("Get", t, func(c C) { os.Setenv("HOME", "/home/test") testDataDir, err := filepath.Abs("./testdata") c.So(err, ShouldBeNil) os.Setenv("XDG_CONFIG_HOME", testDataDir) c.So(Get(Desktop), ShouldEqual, "/home/test/桌面") c.So(Get(Download), ShouldEqual, "/home/test/下载") c.So(Get(Templates), ShouldEqual, "/home/test/.Templates") c.So(Get(PublicShare), ShouldEqual, "/home/test/.Public") c.So(Get(Documents), ShouldEqual, "/home/test/文档") c.So(Get(Music), ShouldEqual, "/home/test/音乐") c.So(Get(Pictures), ShouldEqual, "/home/test/图片") c.So(Get(Videos), ShouldEqual, "/home/test/视频") c.So(Get("XXXX"), ShouldEqual, "/home/test") }) } func TestReloadCache(t *testing.T) { Convey("ReloadCache", t, func(c C) { os.Setenv("HOME", "/home/test") testDataDir, err := filepath.Abs("./testdata") c.So(err, ShouldBeNil) os.Setenv("XDG_CONFIG_HOME", testDataDir) c.So(Get(Desktop), ShouldEqual, "/home/test/桌面") testDataDir2, err := filepath.Abs("./testdata2") c.So(err, ShouldBeNil) os.Setenv("XDG_CONFIG_HOME", testDataDir2) err = ReloadCache() c.So(err, ShouldBeNil) c.So(Get(Desktop), ShouldEqual, "/home/test/MyDesktop") }) } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������