diff --git a/LICENSES/BSD-3-Clause.txt b/LICENSES/BSD-3-Clause.txt new file mode 100644 index 0000000..0741db7 --- /dev/null +++ b/LICENSES/BSD-3-Clause.txt @@ -0,0 +1,26 @@ +Copyright (c) . All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors +may be used to endorse or promote products derived from this software without +specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/LICENSES/GPL-2.0-or-later.txt b/LICENSES/GPL-2.0-or-later.txt new file mode 100644 index 0000000..1d80ac3 --- /dev/null +++ b/LICENSES/GPL-2.0-or-later.txt @@ -0,0 +1,319 @@ +GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public License is intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. This General Public License applies to +most of the Free Software Foundation's software and to any other program whose +authors commit to using it. (Some other Free Software Foundation software +is covered by the GNU Lesser General Public License instead.) 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 this service 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 make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or +for a fee, you must give the recipients all the rights that you have. 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. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If +the software is modified by someone else and passed on, we want its recipients +to know that what they have is not the original, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms +of this General Public License. The "Program", below, refers to any such program +or work, and a "work based on the Program" means either the Program or any +derivative work under copyright law: that is to say, a work containing the +Program or a portion of it, either verbatim or with modifications and/or translated +into another language. (Hereinafter, translation is included without limitation +in the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running the Program +is not restricted, and the output from the Program is covered only if its +contents constitute a work based on the Program (independent of having been +made by running the Program). Whether that is true depends on what the Program +does. + +1. You may copy and distribute 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 and disclaimer of warranty; +keep intact all the notices that refer to this License and to the absence +of any warranty; and give any other recipients of the Program a copy of this +License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, +thus forming a work based on the Program, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + +a) You must cause the modified files to carry prominent notices stating that +you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or +in part contains or is derived from the Program or any part thereof, to be +licensed as a whole at no charge to all third parties under the terms of this +License. + +c) If the modified program normally reads commands interactively when run, +you must cause it, when started running for such interactive use in the most +ordinary way, to print or display an announcement including an appropriate +copyright notice and a notice that there is no warranty (or else, saying that +you provide a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this License. +(Exception: if the Program itself is interactive but does not normally print +such an announcement, your work based on the Program is not required to print +an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Program, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Program. + +In addition, mere aggregation of another work not based on the Program with +the Program (or with a work based on the Program) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may copy and distribute the Program (or a work based on it, under Section +2) in object code or executable form under the terms of Sections 1 and 2 above +provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source code, +which must be distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give +any third party, for a charge no more than your cost of physically performing +source distribution, a complete machine-readable copy of the corresponding +source code, to be distributed under the terms of Sections 1 and 2 above on +a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute +corresponding source code. (This alternative is allowed only for noncommercial +distribution and only if you received the program in object code or executable +form with such an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for making +modifications to it. For an executable work, complete source code means all +the source code for all modules it contains, plus any associated interface +definition files, plus the scripts used to control compilation and installation +of the executable. However, as a special exception, the source code distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy the +source code from the same place counts as distribution of the source code, +even though third parties are not compelled to copy the source along with +the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except +as expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense or distribute the Program is void, and will automatically terminate +your rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses terminated +so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Program or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Program +(or any work based on the Program), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the Program), +the recipient automatically receives a license from the original licensor +to copy, distribute or modify the Program subject to these terms and conditions. +You may not impose any further restrictions on the recipients' exercise of +the rights granted herein. You are not responsible for enforcing compliance +by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Program at all. For example, if a +patent license would not permit royalty-free redistribution of the Program +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system, which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of +the 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 +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Program does not specify a version number of this License, you may choose +any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software Foundation, +write to the Free Software Foundation; we sometimes make exceptions for this. +Our decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing and reuse +of software generally. + + NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +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. +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 convey 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin +Street, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when +it starts in an interactive mode: + +Gnomovision version 69, Copyright (C) year name of author Gnomovision 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, the commands you use may be +called something other than `show w' and `show c'; they could even be mouse-clicks +or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the program, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' +(which makes passes at compilers) written by James Hacker. + +, 1 April 1989 Ty Coon, President of Vice This 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. diff --git a/LICENSES/LGPL-2.0-only.txt b/LICENSES/LGPL-2.0-only.txt new file mode 100644 index 0000000..5c96471 --- /dev/null +++ b/LICENSES/LGPL-2.0-only.txt @@ -0,0 +1,446 @@ +GNU LIBRARY GENERAL PUBLIC LICENSE + +Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. + +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is numbered 2 because +it goes with version 2 of the ordinary GPL.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Library General Public License, applies to some specially +designated Free Software Foundation software, and to any other libraries whose +authors decide to use it. You can use it for your libraries, 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 this service 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 make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library, or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +a program with the library, you must provide complete object files to the +recipients so that they can relink them with the library, after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +Our method of protecting your rights has two steps: (1) copyright the library, +and (2) offer you this license which gives you legal permission to copy, distribute +and/or modify the library. + +Also, for each distributor's protection, we want to make certain that everyone +understands that there is no warranty for this free library. If the library +is modified by someone else and passed on, we want its recipients to know +that what they have is not the original version, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that companies distributing free software will individually +obtain patent licenses, thus in effect transforming the program into proprietary +software. To prevent this, we have made it clear that any patent must be licensed +for everyone's free use or not licensed at all. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License, which was designed for utility programs. This license, +the GNU Library General Public License, applies to certain designated libraries. +This license is quite different from the ordinary one; be sure to read it +in full, and don't assume that anything in it is the same as in the ordinary +license. + +The reason we have a separate public license for some libraries is that they +blur the distinction we usually make between modifying or adding to a program +and simply using it. Linking a program with a library, without changing the +library, is in some sense simply using the library, and is analogous to running +a utility program or application program. However, in a textual and legal +sense, the linked executable is a combined work, a derivative of the original +library, and the ordinary General Public License treats it as such. + +Because of this blurred distinction, using the ordinary General Public License +for libraries did not effectively promote software sharing, because most developers +did not use the libraries. We concluded that weaker conditions might promote +sharing better. + +However, unrestricted linking of non-free programs would deprive the users +of those programs of all benefit from the free status of the libraries themselves. +This Library General Public License is intended to permit developers of non-free +programs to use free libraries, while preserving your freedom as a user of +such programs to change the free libraries that are incorporated in them. +(We have not seen how to achieve this as regards changes in header files, +but we have achieved it as regards changes in the actual functions of the +Library.) The hope is that this will lead to faster development of free libraries. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, while the latter only works together with the library. + +Note that it is possible for a library to be covered by the ordinary General +Public License rather than by this special one. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library which contains a +notice placed by the copyright holder or other authorized party saying it +may be distributed under the terms of this Library General Public License +(also called "this License"). Each licensee is addressed as "you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also compile or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +c) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +d) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the source code distributed need +not include anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the operating +system on which the executable runs, unless that component itself accompanies +the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties to this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Library 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 Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + +one line to give the library's name and an idea of what it does. + +Copyright (C) year name of author + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This library 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 Library General Public License for more +details. + +You should have received a copy of the GNU Library General Public License +along with this library; if not, write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +signature of Ty Coon, 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/LICENSES/LGPL-2.0-or-later.txt b/LICENSES/LGPL-2.0-or-later.txt new file mode 100644 index 0000000..5c96471 --- /dev/null +++ b/LICENSES/LGPL-2.0-or-later.txt @@ -0,0 +1,446 @@ +GNU LIBRARY GENERAL PUBLIC LICENSE + +Version 2, June 1991 Copyright (C) 1991 Free Software Foundation, Inc. + +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is numbered 2 because +it goes with version 2 of the ordinary GPL.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Library General Public License, applies to some specially +designated Free Software Foundation software, and to any other libraries whose +authors decide to use it. You can use it for your libraries, 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 this service 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 make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library, or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +a program with the library, you must provide complete object files to the +recipients so that they can relink them with the library, after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +Our method of protecting your rights has two steps: (1) copyright the library, +and (2) offer you this license which gives you legal permission to copy, distribute +and/or modify the library. + +Also, for each distributor's protection, we want to make certain that everyone +understands that there is no warranty for this free library. If the library +is modified by someone else and passed on, we want its recipients to know +that what they have is not the original version, so that any problems introduced +by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that companies distributing free software will individually +obtain patent licenses, thus in effect transforming the program into proprietary +software. To prevent this, we have made it clear that any patent must be licensed +for everyone's free use or not licensed at all. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License, which was designed for utility programs. This license, +the GNU Library General Public License, applies to certain designated libraries. +This license is quite different from the ordinary one; be sure to read it +in full, and don't assume that anything in it is the same as in the ordinary +license. + +The reason we have a separate public license for some libraries is that they +blur the distinction we usually make between modifying or adding to a program +and simply using it. Linking a program with a library, without changing the +library, is in some sense simply using the library, and is analogous to running +a utility program or application program. However, in a textual and legal +sense, the linked executable is a combined work, a derivative of the original +library, and the ordinary General Public License treats it as such. + +Because of this blurred distinction, using the ordinary General Public License +for libraries did not effectively promote software sharing, because most developers +did not use the libraries. We concluded that weaker conditions might promote +sharing better. + +However, unrestricted linking of non-free programs would deprive the users +of those programs of all benefit from the free status of the libraries themselves. +This Library General Public License is intended to permit developers of non-free +programs to use free libraries, while preserving your freedom as a user of +such programs to change the free libraries that are incorporated in them. +(We have not seen how to achieve this as regards changes in header files, +but we have achieved it as regards changes in the actual functions of the +Library.) The hope is that this will lead to faster development of free libraries. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, while the latter only works together with the library. + +Note that it is possible for a library to be covered by the ordinary General +Public License rather than by this special one. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library which contains a +notice placed by the copyright holder or other authorized party saying it +may be distributed under the terms of this Library General Public License +(also called "this License"). Each licensee is addressed as "you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also compile or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +c) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +d) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the source code distributed need +not include anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the operating +system on which the executable runs, unless that component itself accompanies +the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties to this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Library 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 Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +the exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + +one line to give the library's name and an idea of what it does. + +Copyright (C) year name of author + +This library is free software; you can redistribute it and/or modify it under +the terms of the GNU Library General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This library 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 Library General Public License for more +details. + +You should have received a copy of the GNU Library General Public License +along with this library; if not, write to the Free Software Foundation, Inc., +51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +signature of Ty Coon, 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/LICENSES/LGPL-2.1-or-later.txt b/LICENSES/LGPL-2.1-or-later.txt new file mode 100644 index 0000000..04bb156 --- /dev/null +++ b/LICENSES/LGPL-2.1-or-later.txt @@ -0,0 +1,468 @@ +GNU LESSER GENERAL PUBLIC LICENSE + +Version 2.1, February 1999 + +Copyright (C) 1991, 1999 Free Software Foundation, Inc. + +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts as the +successor of the GNU Library Public License, version 2, hence the version +number 2.1.] + +Preamble + +The licenses for most software are designed to take away your freedom to share +and change it. By contrast, the GNU General Public Licenses are intended to +guarantee your freedom to share and change free software--to make sure the +software is free for all its users. + +This license, the Lesser General Public License, applies to some specially +designated software packages--typically libraries--of the Free Software Foundation +and other authors who decide to use it. You can use it too, but we suggest +you first think carefully about whether this license or the ordinary General +Public License is the better strategy to use in any particular case, based +on the explanations below. + +When we speak of free software, we are referring to freedom of use, 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 this service if you +wish); that you receive source code or can get it if you want it; that you +can change the software and use pieces of it in new free programs; and that +you are informed that you can do these things. + +To protect your rights, we need to make restrictions that forbid distributors +to deny you these rights or to ask you to surrender these rights. These restrictions +translate to certain responsibilities for you if you distribute copies of +the library or if you modify it. + +For example, if you distribute copies of the library, whether gratis or for +a fee, you must give the recipients all the rights that we gave you. You must +make sure that they, too, receive or can get the source code. If you link +other code with the library, you must provide complete object files to the +recipients, so that they can relink them with the library after making changes +to the library and recompiling it. And you must show them these terms so they +know their rights. + +We protect your rights with a two-step method: (1) we copyright the library, +and (2) we offer you this license, which gives you legal permission to copy, +distribute and/or modify the library. + +To protect each distributor, we want to make it very clear that there is no +warranty for the free library. Also, if the library is modified by someone +else and passed on, the recipients should know that what they have is not +the original version, so that the original author's reputation will not be +affected by problems that might be introduced by others. + +Finally, software patents pose a constant threat to the existence of any free +program. We wish to make sure that a company cannot effectively restrict the +users of a free program by obtaining a restrictive license from a patent holder. +Therefore, we insist that any patent license obtained for a version of the +library must be consistent with the full freedom of use specified in this +license. + +Most GNU software, including some libraries, is covered by the ordinary GNU +General Public License. This license, the GNU Lesser General Public License, +applies to certain designated libraries, and is quite different from the ordinary +General Public License. We use this license for certain libraries in order +to permit linking those libraries into non-free programs. + +When a program is linked with a library, whether statically or using a shared +library, the combination of the two is legally speaking a combined work, a +derivative of the original library. The ordinary General Public License therefore +permits such linking only if the entire combination fits its criteria of freedom. +The Lesser General Public License permits more lax criteria for linking other +code with the library. + +We call this license the "Lesser" General Public License because it does Less +to protect the user's freedom than the ordinary General Public License. It +also provides other free software developers Less of an advantage over competing +non-free programs. These disadvantages are the reason we use the ordinary +General Public License for many libraries. However, the Lesser license provides +advantages in certain special circumstances. + +For example, on rare occasions, there may be a special need to encourage the +widest possible use of a certain library, so that it becomes a de-facto standard. +To achieve this, non-free programs must be allowed to use the library. A more +frequent case is that a free library does the same job as widely used non-free +libraries. In this case, there is little to gain by limiting the free library +to free software only, so we use the Lesser General Public License. + +In other cases, permission to use a particular library in non-free programs +enables a greater number of people to use a large body of free software. For +example, permission to use the GNU C Library in non-free programs enables +many more people to use the whole GNU operating system, as well as its variant, +the GNU/Linux operating system. + +Although the Lesser General Public License is Less protective of the users' +freedom, it does ensure that the user of a program that is linked with the +Library has the freedom and the wherewithal to run that program using a modified +version of the Library. + +The precise terms and conditions for copying, distribution and modification +follow. Pay close attention to the difference between a "work based on the +library" and a "work that uses the library". The former contains code derived +from the library, whereas the latter must be combined with the library in +order to run. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License Agreement applies to any software library or other program +which contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Lesser General +Public License (also called "this License"). Each licensee is addressed as +"you". + +A "library" means a collection of software functions and/or data prepared +so as to be conveniently linked with application programs (which use some +of those functions and data) to form executables. + +The "Library", below, refers to any such software library or work which has +been distributed under these terms. A "work based on the Library" means either +the Library or any derivative work under copyright law: that is to say, a +work containing the Library or a portion of it, either verbatim or with modifications +and/or translated straightforwardly into another language. (Hereinafter, translation +is included without limitation in the term "modification".) + +"Source code" for a work means the preferred form of the work for making modifications +to it. For a library, complete source code means all the source code for all +modules it contains, plus any associated interface definition files, plus +the scripts used to control compilation and installation of the library. + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running a program +using the Library is not restricted, and output from such a program is covered +only if its contents constitute a work based on the Library (independent of +the use of the Library in a tool for writing it). Whether that is true depends +on what the Library does and what the program that uses the Library does. + +1. You may copy and distribute verbatim copies of the Library's complete source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and disclaimer +of warranty; keep intact all the notices that refer to this License and to +the absence of any warranty; and distribute a copy of this License along with +the Library. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Library or any portion of it, +thus forming a work based on the Library, and copy and distribute such modifications +or work under the terms of Section 1 above, provided that you also meet all +of these conditions: + + a) The modified work must itself be a software library. + +b) You must cause the files modified to carry prominent notices stating that +you changed the files and the date of any change. + +c) You must cause the whole of the work to be licensed at no charge to all +third parties under the terms of this License. + +d) If a facility in the modified Library refers to a function or a table of +data to be supplied by an application program that uses the facility, other +than as an argument passed when the facility is invoked, then you must make +a good faith effort to ensure that, in the event an application does not supply +such function or table, the facility still operates, and performs whatever +part of its purpose remains meaningful. + +(For example, a function in a library to compute square roots has a purpose +that is entirely well-defined independent of the application. Therefore, Subsection +2d requires that any application-supplied function or table used by this function +must be optional: if the application does not supply it, the square root function +must still compute square roots.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Library, and can be reasonably +considered independent and separate works in themselves, then this License, +and its terms, do not apply to those sections when you distribute them as +separate works. But when you distribute the same sections as part of a whole +which is a work based on the Library, the distribution of the whole must be +on the terms of this License, whose permissions for other licensees extend +to the entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest your +rights to work written entirely by you; rather, the intent is to exercise +the right to control the distribution of derivative or collective works based +on the Library. + +In addition, mere aggregation of another work not based on the Library with +the Library (or with a work based on the Library) on a volume of a storage +or distribution medium does not bring the other work under the scope of this +License. + +3. You may opt to apply the terms of the ordinary GNU General Public License +instead of this License to a given copy of the Library. To do this, you must +alter all the notices that refer to this License, so that they refer to the +ordinary GNU General Public License, version 2, instead of to this License. +(If a newer version than version 2 of the ordinary GNU General Public License +has appeared, then you can specify that version instead if you wish.) Do not +make any other change in these notices. + +Once this change is made in a given copy, it is irreversible for that copy, +so the ordinary GNU General Public License applies to all subsequent copies +and derivative works made from that copy. + +This option is useful when you wish to copy part of the code of the Library +into a program that is not a library. + +4. You may copy and distribute the Library (or a portion or derivative of +it, under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you accompany it with the complete corresponding +machine-readable source code, which must be distributed under the terms of +Sections 1 and 2 above on a medium customarily used for software interchange. + +If distribution of object code is made by offering access to copy from a designated +place, then offering equivalent access to copy the source code from the same +place satisfies the requirement to distribute the source code, even though +third parties are not compelled to copy the source along with the object code. + +5. A program that contains no derivative of any portion of the Library, but +is designed to work with the Library by being compiled or linked with it, +is called a "work that uses the Library". Such a work, in isolation, is not +a derivative work of the Library, and therefore falls outside the scope of +this License. + +However, linking a "work that uses the Library" with the Library creates an +executable that is a derivative of the Library (because it contains portions +of the Library), rather than a "work that uses the library". The executable +is therefore covered by this License. Section 6 states terms for distribution +of such executables. + +When a "work that uses the Library" uses material from a header file that +is part of the Library, the object code for the work may be a derivative work +of the Library even though the source code is not. Whether this is true is +especially significant if the work can be linked without the Library, or if +the work is itself a library. The threshold for this to be true is not precisely +defined by law. + +If such an object file uses only numerical parameters, data structure layouts +and accessors, and small macros and small inline functions (ten lines or less +in length), then the use of the object file is unrestricted, regardless of +whether it is legally a derivative work. (Executables containing this object +code plus portions of the Library will still fall under Section 6.) + +Otherwise, if the work is a derivative of the Library, you may distribute +the object code for the work under the terms of Section 6. Any executables +containing that work also fall under Section 6, whether or not they are linked +directly with the Library itself. + +6. As an exception to the Sections above, you may also combine or link a "work +that uses the Library" with the Library to produce a work containing portions +of the Library, and distribute that work under terms of your choice, provided +that the terms permit modification of the work for the customer's own use +and reverse engineering for debugging such modifications. + +You must give prominent notice with each copy of the work that the Library +is used in it and that the Library and its use are covered by this License. +You must supply a copy of this License. If the work during execution displays +copyright notices, you must include the copyright notice for the Library among +them, as well as a reference directing the user to the copy of this License. +Also, you must do one of these things: + +a) Accompany the work with the complete corresponding machine-readable source +code for the Library including whatever changes were used in the work (which +must be distributed under Sections 1 and 2 above); and, if the work is an +executable linked with the Library, with the complete machine-readable "work +that uses the Library", as object code and/or source code, so that the user +can modify the Library and then relink to produce a modified executable containing +the modified Library. (It is understood that the user who changes the contents +of definitions files in the Library will not necessarily be able to recompile +the application to use the modified definitions.) + +b) Use a suitable shared library mechanism for linking with the Library. A +suitable mechanism is one that (1) uses at run time a copy of the library +already present on the user's computer system, rather than copying library +functions into the executable, and (2) will operate properly with a modified +version of the library, if the user installs one, as long as the modified +version is interface-compatible with the version that the work was made with. + +c) Accompany the work with a written offer, valid for at least three years, +to give the same user the materials specified in Subsection 6a, above, for +a charge no more than the cost of performing this distribution. + +d) If distribution of the work is made by offering access to copy from a designated +place, offer equivalent access to copy the above specified materials from +the same place. + +e) Verify that the user has already received a copy of these materials or +that you have already sent this user a copy. + +For an executable, the required form of the "work that uses the Library" must +include any data and utility programs needed for reproducing the executable +from it. However, as a special exception, the materials to be distributed +need not include anything that is normally distributed (in either source or +binary form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component itself +accompanies the executable. + +It may happen that this requirement contradicts the license restrictions of +other proprietary libraries that do not normally accompany the operating system. +Such a contradiction means you cannot use both them and the Library together +in an executable that you distribute. + +7. You may place library facilities that are a work based on the Library side-by-side +in a single library together with other library facilities not covered by +this License, and distribute such a combined library, provided that the separate +distribution of the work based on the Library and of the other library facilities +is otherwise permitted, and provided that you do these two things: + +a) Accompany the combined library with a copy of the same work based on the +Library, uncombined with any other library facilities. This must be distributed +under the terms of the Sections above. + +b) Give prominent notice with the combined library of the fact that part of +it is a work based on the Library, and explaining where to find the accompanying +uncombined form of the same work. + +8. You may not copy, modify, sublicense, link with, or distribute the Library +except as expressly provided under this License. Any attempt otherwise to +copy, modify, sublicense, link with, or distribute the Library is void, and +will automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will not +have their licenses terminated so long as such parties remain in full compliance. + +9. You are not required to accept this License, since you have not signed +it. However, nothing else grants you permission to modify or distribute the +Library or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the Library +(or any work based on the Library), you indicate your acceptance of this License +to do so, and all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +10. Each time you redistribute the Library (or any work based on the Library), +the recipient automatically receives a license from the original licensor +to copy, distribute, link with or modify the Library subject to these terms +and conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties with this License. + +11. If, as a consequence of a court judgment or allegation of patent infringement +or for any other reason (not limited to patent issues), 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 distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, then as +a consequence you may not distribute the Library at all. For example, if a +patent license would not permit royalty-free redistribution of the Library +by all those who receive copies directly or indirectly through you, then the +only way you could satisfy both it and this License would be to refrain entirely +from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents +or other property right claims or to contest validity of any such claims; +this section has the sole purpose of protecting the integrity of the free +software distribution system which is implemented by public license practices. +Many people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +12. If the distribution and/or use of the Library is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Library under this License may add an explicit geographical +distribution limitation excluding those countries, so that distribution is +permitted only in or among countries not thus excluded. In such case, this +License incorporates the limitation as if written in the body of this License. + +13. The Free Software Foundation may publish revised and/or new versions of +the Lesser 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 Library specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that version +or of any later version published by the Free Software Foundation. If the +Library does not specify a license version number, you may choose any version +ever published by the Free Software Foundation. + +14. If you wish to incorporate parts of the Library into other free programs +whose distribution conditions are incompatible with these, write to the author +to ask for permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make exceptions +for this. Our decision will be guided by the two goals of preserving the free +status of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + +15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR +THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY +"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 LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE +THE LIBRARY 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 LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH +HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Libraries + +If you develop a new library, and you want it to be of the greatest possible +use to the public, we recommend making it free software that everyone can +redistribute and change. You can do so by permitting redistribution under +these terms (or, alternatively, under the terms of the ordinary General Public +License). + +To apply these terms, attach the following notices to the library. It is safest +to attach them to the start of each source file to most effectively convey +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 library is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the Free +Software Foundation; either version 2.1 of the License, or (at your option) +any later version. + +This library 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 Lesser General Public License for more +details. + +You should have received a copy of the GNU Lesser General Public License along +with this library; if not, write to the Free Software Foundation, Inc., 51 +Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your school, +if any, to sign a "copyright disclaimer" for the library, if necessary. Here +is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in + +the library `Frob' (a library for tweaking knobs) written + +by James Random Hacker. + +< signature of Ty Coon > , 1 April 1990 + +Ty Coon, President of Vice + +That's all there is to it! diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt new file mode 100644 index 0000000..204b93d --- /dev/null +++ b/LICENSES/MIT.txt @@ -0,0 +1,19 @@ +MIT License Copyright (c) + +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 (including the next +paragraph) 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. diff --git a/LICENSES/MPL-1.1.txt b/LICENSES/MPL-1.1.txt new file mode 100644 index 0000000..b45d0e1 --- /dev/null +++ b/LICENSES/MPL-1.1.txt @@ -0,0 +1,422 @@ +Mozilla Public License Version 1.1 + + 1. Definitions. + +1.0.1. "Commercial Use" means distribution or otherwise making the Covered +Code available to a third party. + +1.1. "Contributor" means each entity that creates or contributes to the creation +of Modifications. + +1.2. "Contributor Version" means the combination of the Original Code, prior +Modifications used by a Contributor, and the Modifications made by that particular +Contributor. + +1.3. "Covered Code" means the Original Code or Modifications or the combination +of the Original Code and Modifications, in each case including portions thereof. + +1.4. "Electronic Distribution Mechanism" means a mechanism generally accepted +in the software development community for the electronic transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source Code. + +1.6. "Initial Developer" means the individual or entity identified as the +Initial Developer in the Source Code notice required by Exhibit A. + +1.7. "Larger Work" means a work which combines Covered Code or portions thereof +with code not governed by the terms of this License. + + 1.8. "License" means this document. + +1.8.1. "Licensable" means having the right to grant, to the maximum extent +possible, whether at the time of the initial grant or subsequently acquired, +any and all of the rights conveyed herein. + +1.9. "Modifications" means any addition to or deletion from the substance +or structure of either the Original Code or any previous Modifications. When +Covered Code is released as a series of files, a Modification is: + +Any addition to or deletion from the contents of a file containing Original +Code or previous Modifications. + +Any new file that contains any part of the Original Code or previous Modifications. + +1.10. "Original Code" means Source Code of computer software code which is +described in the Source Code notice required by Exhibit A as Original Code, +and which, at the time of its release under this License is not already Covered +Code governed by this License. + +1.10.1. "Patent Claims" means any patent claim(s), now owned or hereafter +acquired, including without limitation, method, process, and apparatus claims, +in any patent Licensable by grantor. + +1.11. "Source Code" means the preferred form of the Covered Code for making +modifications to it, including all modules it contains, plus any associated +interface definition files, scripts used to control compilation and installation +of an Executable, or source code differential comparisons against either the +Original Code or another well known, available Covered Code of the Contributor's +choice. The Source Code can be in a compressed or archival form, provided +the appropriate decompression or de-archiving software is widely available +for no charge. + +1.12. "You" (or "Your") means an individual or a legal entity exercising rights +under, and complying with all of the terms of, this License or a future version +of this License issued under Section 6.1. For legal entities, "You" includes +any entity which controls, is controlled by, or is under common control with +You. For purposes of this definition, "control" means (a) the power, direct +or indirect, to cause the direction or management of such entity, whether +by contract or otherwise, or (b) ownership of more than fifty percent (50%) +of the outstanding shares or beneficial ownership of such entity. + + 2. Source Code License. + +2.1. The Initial Developer Grant. The Initial Developer hereby grants You +a world-wide, royalty-free, non-exclusive license, subject to third party +intellectual property claims: + +a. under intellectual property rights (other than patent or trademark) Licensable +by Initial Developer to use, reproduce, modify, display, perform, sublicense +and distribute the Original Code (or portions thereof) with or without Modifications, +and/or as part of a Larger Work; and + +b. under Patents Claims infringed by the making, using or selling of Original +Code, to make, have made, use, practice, sell, and offer for sale, and/or +otherwise dispose of the Original Code (or portions thereof). + +c. the licenses granted in this Section 2.1 (a) and (b) are effective on the +date Initial Developer first distributes Original Code under the terms of +this License. + +d. Notwithstanding Section 2.1 (b) above, no patent license is granted: 1) +for code that You delete from the Original Code; 2) separate from the Original +Code; or 3) for infringements caused by: i) the modification of the Original +Code or ii) the combination of the Original Code with other software or devices. + +2.2. Contributor Grant. Subject to third party intellectual property claims, +each Contributor hereby grants You a world-wide, royalty-free, non-exclusive +license + +a. under intellectual property rights (other than patent or trademark) Licensable +by Contributor, to use, reproduce, modify, display, perform, sublicense and +distribute the Modifications created by such Contributor (or portions thereof) +either on an unmodified basis, with other Modifications, as Covered Code and/or +as part of a Larger Work; and + +b. under Patent Claims infringed by the making, using, or selling of Modifications +made by that Contributor either alone and/or in combination with its Contributor +Version (or portions of such combination), to make, use, sell, offer for sale, +have made, and/or otherwise dispose of: 1) Modifications made by that Contributor +(or portions thereof); and 2) the combination of Modifications made by that +Contributor with its Contributor Version (or portions of such combination). + +c. the licenses granted in Sections 2.2 (a) and 2.2 (b) are effective on the +date Contributor first makes Commercial Use of the Covered Code. + +d. Notwithstanding Section 2.2 (b) above, no patent license is granted: 1) +for any code that Contributor has deleted from the Contributor Version; 2) +separate from the Contributor Version; 3) for infringements caused by: i) +third party modifications of Contributor Version or ii) the combination of +Modifications made by that Contributor with other software (except as part +of the Contributor Version) or other devices; or 4) under Patent Claims infringed +by Covered Code in the absence of Modifications made by that Contributor. + + 3. Distribution Obligations. + +3.1. Application of License. The Modifications which You create or to which +You contribute are governed by the terms of this License, including without +limitation Section 2.2. The Source Code version of Covered Code may be distributed +only under the terms of this License or a future version of this License released +under Section 6.1, and You must include a copy of this License with every +copy of the Source Code You distribute. You may not offer or impose any terms +on any Source Code version that alters or restricts the applicable version +of this License or the recipients' rights hereunder. However, You may include +an additional document offering the additional rights described in Section +3.5. + +3.2. Availability of Source Code. Any Modification which You create or to +which You contribute must be made available in Source Code form under the +terms of this License either on the same media as an Executable version or +via an accepted Electronic Distribution Mechanism to anyone to whom you made +an Executable version available; and if made available via Electronic Distribution +Mechanism, must remain available for at least twelve (12) months after the +date it initially became available, or at least six (6) months after a subsequent +version of that particular Modification has been made available to such recipients. +You are responsible for ensuring that the Source Code version remains available +even if the Electronic Distribution Mechanism is maintained by a third party. + +3.3. Description of Modifications. You must cause all Covered Code to which +You contribute to contain a file documenting the changes You made to create +that Covered Code and the date of any change. You must include a prominent +statement that the Modification is derived, directly or indirectly, from Original +Code provided by the Initial Developer and including the name of the Initial +Developer in (a) the Source Code, and (b) in any notice in an Executable version +or related documentation in which You describe the origin or ownership of +the Covered Code. + + 3.4. Intellectual Property Matters + + (a) Third Party Claims + +If Contributor has knowledge that a license under a third party's intellectual +property rights is required to exercise the rights granted by such Contributor +under Sections 2.1 or 2.2, Contributor must include a text file with the Source +Code distribution titled "LEGAL" which describes the claim and the party making +the claim in sufficient detail that a recipient will know whom to contact. +If Contributor obtains such knowledge after the Modification is made available +as described in Section 3.2, Contributor shall promptly modify the LEGAL file +in all copies Contributor makes available thereafter and shall take other +steps (such as notifying appropriate mailing lists or newsgroups) reasonably +calculated to inform those who received the Covered Code that new knowledge +has been obtained. + + (b) Contributor APIs + +If Contributor's Modifications include an application programming interface +and Contributor has knowledge of patent licenses which are reasonably necessary +to implement that API, Contributor must also include this information in the +LEGAL file. + + (c) Representations. + +Contributor represents that, except as disclosed pursuant to Section 3.4 (a) +above, Contributor believes that Contributor's Modifications are Contributor's +original creation(s) and/or Contributor has sufficient rights to grant the +rights conveyed by this License. + +3.5. Required Notices. You must duplicate the notice in Exhibit A in each +file of the Source Code. If it is not possible to put such notice in a particular +Source Code file due to its structure, then You must include such notice in +a location (such as a relevant directory) where a user would be likely to +look for such a notice. If You created one or more Modification(s) You may +add your name as a Contributor to the notice described in Exhibit A. You must +also duplicate this License in any documentation for the Source Code where +You describe recipients' rights or ownership rights relating to Covered Code. +You may choose to offer, and to charge a fee for, warranty, support, indemnity +or liability obligations to one or more recipients of Covered Code. However, +You may do so only on Your own behalf, and not on behalf of the Initial Developer +or any Contributor. You must make it absolutely clear than any such warranty, +support, indemnity or liability obligation is offered by You alone, and You +hereby agree to indemnify the Initial Developer and every Contributor for +any liability incurred by the Initial Developer or such Contributor as a result +of warranty, support, indemnity or liability terms You offer. + +3.6. Distribution of Executable Versions. You may distribute Covered Code +in Executable form only if the requirements of Sections 3.1, 3.2, 3.3, 3.4 +and 3.5 have been met for that Covered Code, and if You include a notice stating +that the Source Code version of the Covered Code is available under the terms +of this License, including a description of how and where You have fulfilled +the obligations of Section 3.2. The notice must be conspicuously included +in any notice in an Executable version, related documentation or collateral +in which You describe recipients' rights relating to the Covered Code. You +may distribute the Executable version of Covered Code or ownership rights +under a license of Your choice, which may contain terms different from this +License, provided that You are in compliance with the terms of this License +and that the license for the Executable version does not attempt to limit +or alter the recipient's rights in the Source Code version from the rights +set forth in this License. If You distribute the Executable version under +a different license You must make it absolutely clear that any terms which +differ from this License are offered by You alone, not by the Initial Developer +or any Contributor. You hereby agree to indemnify the Initial Developer and +every Contributor for any liability incurred by the Initial Developer or such +Contributor as a result of any such terms You offer. + +3.7. Larger Works. You may create a Larger Work by combining Covered Code +with other code not governed by the terms of this License and distribute the +Larger Work as a single product. In such a case, You must make sure the requirements +of this License are fulfilled for the Covered Code. + + 4. Inability to Comply Due to Statute or Regulation. + +If it is impossible for You to comply with any of the terms of this License +with respect to some or all of the Covered Code due to statute, judicial order, +or regulation then You must: (a) comply with the terms of this License to +the maximum extent possible; and (b) describe the limitations and the code +they affect. Such description must be included in the LEGAL file described +in Section 3.4 and must be included with all distributions of the Source Code. +Except to the extent prohibited by statute or regulation, such description +must be sufficiently detailed for a recipient of ordinary skill to be able +to understand it. + + 5. Application of this License. + +This License applies to code to which the Initial Developer has attached the +notice in Exhibit A and to related Covered Code. + + 6. Versions of the License. + + 6.1. New Versions + +Netscape Communications Corporation ("Netscape") may publish revised and/or +new versions of the License from time to time. Each version will be given +a distinguishing version number. + + 6.2. Effect of New Versions + +Once Covered Code has been published under a particular version of the License, +You may always continue to use it under the terms of that version. You may +also choose to use such Covered Code under the terms of any subsequent version +of the License published by Netscape. No one other than Netscape has the right +to modify the terms applicable to Covered Code created under this License. + + 6.3. Derivative Works + +If You create or use a modified version of this License (which you may only +do in order to apply it to code which is not already Covered Code governed +by this License), You must (a) rename Your license so that the phrases "Mozilla", +"MOZILLAPL", "MOZPL", "Netscape", "MPL", "NPL" or any confusingly similar +phrase do not appear in your license (except to note that your license differs +from this License) and (b) otherwise make it clear that Your version of the +license contains terms which differ from the Mozilla Public License and Netscape +Public License. (Filling in the name of the Initial Developer, Original Code +or Contributor in the notice described in Exhibit A shall not of themselves +be deemed to be modifications of this License.) + + 7. DISCLAIMER OF WARRANTY + +COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES +THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR +PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN +ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME +THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER +OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED +CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + + 8. Termination + +8.1. This License and the rights granted hereunder will terminate automatically +if You fail to comply with terms herein and fail to cure such breach within +30 days of becoming aware of the breach. All sublicenses to the Covered Code +which are properly granted shall survive any termination of this License. +Provisions which, by their nature, must remain in effect beyond the termination +of this License shall survive. + +8.2. If You initiate litigation by asserting a patent infringement claim (excluding +declatory judgment actions) against Initial Developer or a Contributor (the +Initial Developer or Contributor against whom You file such action is referred +to as "Participant") alleging that: + +a. such Participant's Contributor Version directly or indirectly infringes +any patent, then any and all rights granted by such Participant to You under +Sections 2.1 and/or 2.2 of this License shall, upon 60 days notice from Participant +terminate prospectively, unless if within 60 days after receipt of notice +You either: (i) agree in writing to pay Participant a mutually agreeable reasonable +royalty for Your past and future use of Modifications made by such Participant, +or (ii) withdraw Your litigation claim with respect to the Contributor Version +against such Participant. If within 60 days of notice, a reasonable royalty +and payment arrangement are not mutually agreed upon in writing by the parties +or the litigation claim is not withdrawn, the rights granted by Participant +to You under Sections 2.1 and/or 2.2 automatically terminate at the expiration +of the 60 day notice period specified above. + +b. any software, hardware, or device, other than such Participant's Contributor +Version, directly or indirectly infringes any patent, then any rights granted +to You by such Participant under Sections 2.1(b) and 2.2(b) are revoked effective +as of the date You first made, used, sold, distributed, or had made, Modifications +made by that Participant. + +8.3. If You assert a patent infringement claim against Participant alleging +that such Participant's Contributor Version directly or indirectly infringes +any patent where such claim is resolved (such as by license or settlement) +prior to the initiation of patent infringement litigation, then the reasonable +value of the licenses granted by such Participant under Sections 2.1 or 2.2 +shall be taken into account in determining the amount or value of any payment +or license. + +8.4. In the event of termination under Sections 8.1 or 8.2 above, all end +user license agreements (excluding distributors and resellers) which have +been validly granted by You or any distributor hereunder prior to termination +shall survive termination. + + 9. LIMITATION OF LIABILITY + +UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING +NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY +OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF +ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, +OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES +FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY +AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE +BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY +SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH +PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. +SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL +OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO +YOU. + + 10. U.S. government end users + +The Covered Code is a "commercial item," as that term is defined in 48 C.F.R. +2.101 (Oct. 1995), consisting of "commercial computer software" and "commercial +computer software documentation," as such terms are used in 48 C.F.R. 12.212 +(Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through +227.7202-4 (June 1995), all U.S. Government End Users acquire Covered Code +with only those rights set forth herein. + + 11. Miscellaneous + +This License represents the complete agreement concerning subject matter hereof. +If any provision of this License is held to be unenforceable, such provision +shall be reformed only to the extent necessary to make it enforceable. This +License shall be governed by California law provisions (except to the extent +applicable law, if any, provides otherwise), excluding its conflict-of-law +provisions. With respect to disputes in which at least one party is a citizen +of, or an entity chartered or registered to do business in the United States +of America, any litigation relating to this License shall be subject to the +jurisdiction of the Federal Courts of the Northern District of California, +with venue lying in Santa Clara County, California, with the losing party +responsible for costs, including without limitation, court costs and reasonable +attorneys' fees and expenses. The application of the United Nations Convention +on Contracts for the International Sale of Goods is expressly excluded. Any +law or regulation which provides that the language of a contract shall be +construed against the drafter shall not apply to this License. + + 12. Responsibility for claims + +As between Initial Developer and the Contributors, each party is responsible +for claims and damages arising, directly or indirectly, out of its utilization +of rights under this License and You agree to work with Initial Developer +and Contributors to distribute such responsibility on an equitable basis. +Nothing herein is intended or shall be deemed to constitute any admission +of liability. + + 13. Multiple-licensed code + +Initial Developer may designate portions of the Covered Code as "Multiple-Licensed". +"Multiple-Licensed" means that the Initial Developer permits you to utilize +portions of the Covered Code under Your choice of the MPL or the alternative +licenses, if any, specified by the Initial Developer in the file described +in Exhibit A. Exhibit A - Mozilla Public License. + +"The contents of this file are subject to the Mozilla Public License Version +1.1 (the "License"); you may not use this file except in compliance with the +License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ + +Software distributed under the License is distributed on an "AS IS" basis, +WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for +the specific language governing rights and limitations under the License. + +The Original Code is ______________________________________ . + +The Initial Developer of the Original Code is ________________________ . + +Portions created by ______________________ are Copyright (C) ______ . All +Rights Reserved. + +Contributor(s): ______________________________________ . + +Alternatively, the contents of this file may be used under the terms of the +_____ license (the " [___] License"), in which case the provisions of [______] +License are applicable instead of those above. If you wish to allow use of +your version of this file only under the terms of the [____] License and not +to allow others to use your version of this file under the MPL, indicate your +decision by deleting the provisions above and replace them with the notice +and other provisions required by the [___] License. If you do not delete the +provisions above, a recipient may use your version of this file under either +the MPL or the [___] License." + +NOTE: The text of this Exhibit A may differ slightly from the text of the +notices in the Source Code files of the Original Code. You should use the +text of this Exhibit A rather than the text found in the Original Code Source +Code for Your Modifications. diff --git a/autotests/base64benchmark.cpp b/autotests/base64benchmark.cpp index 19d7726..fb8bf98 100644 --- a/autotests/base64benchmark.cpp +++ b/autotests/base64benchmark.cpp @@ -1,112 +1,99 @@ /* - Copyright (c) 2010 Volker Krause + SPDX-FileCopyrightText: 2010 Volker Krause - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library 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 Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. + SPDX-License-Identifier: LGPL-2.0-or-later */ #include #include #include #include #include #include "../src/kcodecsbase64.h" class Base64Benchmark : public QObject { Q_OBJECT private: static QByteArray fillByteArray(int size) { char c = 0; QByteArray result; result.reserve(size); while (result.size() < size) { result.append(c++); } return result; } void createTestSet() { QTest::addColumn("output"); QTest::addColumn("input"); QTest::newRow("empty") << QByteArray() << QByteArray(); QTest::newRow("128") << fillByteArray(128) << KCodecs::base64Encode(fillByteArray(128)); QTest::newRow("1k") << fillByteArray(1 << 10) << KCodecs::base64Encode(fillByteArray(1 << 10)); QTest::newRow("1M") << fillByteArray(1 << 20) << KCodecs::base64Encode(fillByteArray(1 << 20)); } private Q_SLOTS: void benchmarkKCodecDecode_data() { createTestSet(); } void benchmarkKCodecDecode() { QFETCH(QByteArray, input); QFETCH(QByteArray, output); QByteArray result; QBENCHMARK { result = KCodecs::base64Decode(input); } QCOMPARE(result, output); } void benchmarkQByteArrayDecode_data() { createTestSet(); } void benchmarkQByteArrayDecode() { QFETCH(QByteArray, input); QFETCH(QByteArray, output); QByteArray result; QBENCHMARK { result = QByteArray::fromBase64(input); } QCOMPARE(result, output); } void benchmarkKMimeBase64Decoder_data() { createTestSet(); } void benchmarkKMimeBase64Decoder() { QFETCH(QByteArray, input); QFETCH(QByteArray, output); QByteArray result; QBENCHMARK { KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64"); QVERIFY(codec); result.resize(codec->maxDecodedSizeFor(input.size())); KCodecs::Decoder *decoder = codec->makeDecoder(); QByteArray::const_iterator inputIt = input.constBegin(); QByteArray::iterator resultIt = result.begin(); decoder->decode(inputIt, input.constEnd(), resultIt, result.constEnd()); result.truncate(resultIt - result.begin()); delete decoder; } QCOMPARE(result, output); } }; QTEST_MAIN(Base64Benchmark) #include "base64benchmark.moc" diff --git a/autotests/codectest.cpp b/autotests/codectest.cpp index e089b66..42b32f5 100644 --- a/autotests/codectest.cpp +++ b/autotests/codectest.cpp @@ -1,110 +1,97 @@ /* - Copyright (c) 2010 Thomas McGuire - - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library 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 Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. + SPDX-FileCopyrightText: 2010 Thomas McGuire + + SPDX-License-Identifier: LGPL-2.0-or-later */ #include "codectest.h" #include #include #include "../src/kcodecs.h" using namespace KCodecs; QTEST_MAIN(CodecTest) enum Mode { Decode, Encode }; Q_DECLARE_METATYPE(Mode) void CodecTest::testCodecs_data() { QTest::addColumn("input"); QTest::addColumn("expResult"); QTest::addColumn("codecName"); QTest::addColumn("tag"); QTest::addColumn("mode"); QDir codecBaseDir(QFINDTESTDATA("data")); const QStringList lst = codecBaseDir.entryList(QStringList(), QDir::Dirs | QDir::NoDotAndDotDot, QDir::NoSort); for (const QString &dir : lst) { if (dir.toLower().startsWith(QLatin1String("codec_"))) { const QString codecName = dir.right(dir.size() - 6); QDir codecDir(codecBaseDir.path() + QLatin1String("/") + dir); const QStringList lst2 = codecDir.entryList(QStringList(), QDir::Files, QDir::NoSort); for (const QString &file : lst2) { if (file.toLower().endsWith(QLatin1String(".expected"))) { const QString dataFileNameBase = file.left(file.size() - 9); QFile dataFile(codecDir.path() + QLatin1Char('/') + dataFileNameBase); QFile expectedFile(codecDir.path() + QLatin1Char('/') + file); QVERIFY(dataFile.open(QIODevice::ReadOnly)); QVERIFY(expectedFile.open(QIODevice::ReadOnly)); Mode mode = Decode; if (file.contains(QLatin1String("-decode"))) { mode = Decode; } else if (file.contains(QLatin1String("-encode"))) { mode = Encode; } const QByteArray data = dataFile.readAll(); const QByteArray expected = expectedFile.readAll(); const QString tag = codecName + QLatin1Char('/') + dataFileNameBase; QTest::newRow(tag.toLatin1().constData()) << data << expected << codecName.toLatin1() << tag << mode; dataFile.close(); expectedFile.close(); } } } } } void CodecTest::testCodecs() { QFETCH(QByteArray, input); QFETCH(QByteArray, expResult); QFETCH(QByteArray, codecName); QFETCH(QString, tag); QFETCH(Mode, mode); Codec *codec = Codec::codecForName(codecName); QVERIFY(codec); QStringList blacklistedTags; if (blacklistedTags.contains(tag)) { QEXPECT_FAIL(tag.toLatin1().constData(), "Codec broken", Continue); } QByteArray result; if (mode == Decode) { result = codec->decode(input, Codec::NewlineLF); } else { result = codec->encode(input, Codec::NewlineLF); } // More usable version of QCOMPARE(result, expResult), in case the difference is at the end... if (result != expResult) { const QList lines = result.split('\n'); const QList expLines = expResult.split('\n'); if (lines.count() == expLines.count()) QCOMPARE(result.split('\n'), expResult.split('\n')); } QCOMPARE(result, expResult); } diff --git a/autotests/codectest.h b/autotests/codectest.h index 37a3cf5..03efec9 100644 --- a/autotests/codectest.h +++ b/autotests/codectest.h @@ -1,32 +1,19 @@ /* - Copyright (c) 2010 Thomas McGuire + SPDX-FileCopyrightText: 2010 Thomas McGuire - This library is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published by - the Free Software Foundation; either version 2 of the License, or (at your - option) any later version. - - This library 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 Library General Public - License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to the - Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. + SPDX-License-Identifier: LGPL-2.0-or-later */ #ifndef CODECTEST_H #define CODECTEST_H #include class CodecTest : public QObject { Q_OBJECT private Q_SLOTS: void testCodecs(); void testCodecs_data(); }; #endif diff --git a/autotests/kcharsetstest.cpp b/autotests/kcharsetstest.cpp index f969b23..dd33061 100644 --- a/autotests/kcharsetstest.cpp +++ b/autotests/kcharsetstest.cpp @@ -1,189 +1,178 @@ /* - * Copyright 2011 Romain Perier - * - * 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 2 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 . - */ + SPDX-FileCopyrightText: 2011 Romain Perier + + SPDX-License-Identifier: GPL-2.0-or-later +*/ #include "kcharsetstest.h" #include #include #include #include #include static bool encodingNameHasADescription(const QString &encodingName, const QStringList &descriptions) { for (const QString &description : descriptions) if (description.contains(encodingName)) { return true; } return false; } void KCharsetsTest::testSingleton() { QVERIFY(KCharsets::charsets() != nullptr); QCOMPARE(KCharsets::charsets(), KCharsets::charsets()); } void KCharsetsTest::testCodecForName_data() { QTest::addColumn("codec"); QTest::addColumn("expectedCodecFromKDE"); QTest::addColumn("expectedCodecFromQt"); QTest::newRow("utf8") << "utf8" << "UTF-8" << "UTF-8"; QTest::newRow("utf-8") << "utf-8" << "UTF-8" << "UTF-8"; QTest::newRow("UTF8") << "UTF8" << "UTF-8" << "UTF-8"; QTest::newRow("UTF-8") << "UTF-8" << "UTF-8" << "UTF-8"; QTest::newRow("Big5") << "Big5" << "Big5" << "Big5"; QTest::newRow("Big5-HKSCS") << "Big5-HKSCS" << "Big5-HKSCS" << "Big5-HKSCS"; QTest::newRow("EUC-JP") << "EUC-JP" << "EUC-JP" << "EUC-JP"; QTest::newRow("EUC-KR") << "EUC-KR" << "EUC-KR" << "EUC-KR"; QTest::newRow("CP 949") << "CP 949" << "CP 949" << "CP 949"; QTest::newRow("GB18030") << "GB18030" << "GB18030" << "GB18030"; QTest::newRow("GB2312") << "GB2312" << "GB2312" << "GB2312"; QTest::newRow("GBK") << "GBK" << "GBK" << "GBK"; QTest::newRow("IBM850") << "IBM850" << "IBM850" << "IBM850"; QTest::newRow("IBM866") << "IBM866" << "IBM866" << "IBM866"; QTest::newRow("IBM874") << "IBM874" << "IBM874" << "IBM874"; QTest::newRow("ISO 10646-UCS-2") << "ISO 10646-UCS-2" << "ISO 10646-UCS-2" << "ISO 10646-UCS-2"; QTest::newRow("ISO 8859-1") << "ISO 8859-1" << "ISO 8859-1" << "ISO 8859-1"; QTest::newRow("ISO 8859-11") << "ISO 8859-11" << "ISO 8859-11" << "ISO 8859-11"; QTest::newRow("ISO 8859-13") << "ISO 8859-13" << "ISO 8859-13" << "ISO 8859-13"; QTest::newRow("ISO 8859-14") << "ISO 8859-14" << "ISO 8859-14" << "ISO 8859-14"; QTest::newRow("ISO 8859-15") << "ISO 8859-15" << "ISO 8859-15" << "ISO 8859-15"; QTest::newRow("ISO 8859-16") << "ISO 8859-16" << "ISO 8859-16" << "ISO 8859-16"; QTest::newRow("ISO 8859-2") << "ISO 8859-2" << "ISO 8859-2" << "ISO 8859-2"; QTest::newRow("ISO 8859-3") << "ISO 8859-3" << "ISO 8859-3" << "ISO 8859-3"; QTest::newRow("ISO 8859-4") << "ISO 8859-4" << "ISO 8859-4" << "ISO 8859-4"; QTest::newRow("ISO 8859-5") << "ISO 8859-5" << "ISO 8859-5" << "ISO 8859-5"; QTest::newRow("ISO 8859-6") << "ISO 8859-6" << "ISO 8859-6" << "ISO 8859-6"; QTest::newRow("ISO 8859-7") << "ISO 8859-7" << "ISO 8859-7" << "ISO 8859-7"; QTest::newRow("ISO 8859-8") << "ISO 8859-8" << "ISO 8859-8" << "ISO 8859-8"; QTest::newRow("ISO 8859-8-I") << "ISO 8859-8-I" << "ISO 8859-8-I" << "ISO 8859-8-I"; QTest::newRow("ISO 8859-9") << "ISO 8859-9" << "ISO 8859-9" << "ISO 8859-9"; QTest::newRow("KOI8-R") << "KOI8-R" << "KOI8-R" << "KOI8-R"; QTest::newRow("KOI8-U") << "KOI8-U" << "KOI8-U" << "KOI8-U"; QTest::newRow("TIS620") << "TIS620" << "TIS620" << "TIS620"; QTest::newRow("TSCII") << "TSCII" << "TSCII" << "TSCII"; QTest::newRow("UTF-16") << "UTF-16" << "UTF-16" << "UTF-16"; QTest::newRow("UTF-8") << "UTF-8" << "UTF-8" << "UTF-8"; QTest::newRow("cp 1250") << "cp 1250" << "cp 1250" << "cp 1250"; QTest::newRow("cp 1251") << "cp 1251" << "cp 1251" << "cp 1251"; QTest::newRow("cp 1252") << "cp 1252" << "cp 1252" << "cp 1252"; QTest::newRow("cp 1253") << "cp 1253" << "cp 1253" << "cp 1253"; QTest::newRow("cp 1254") << "cp 1254" << "cp 1254" << "cp 1254"; QTest::newRow("cp 1255") << "cp 1255" << "cp 1255" << "cp 1255"; QTest::newRow("cp 1256") << "cp 1256" << "cp 1256" << "cp 1256"; QTest::newRow("cp 1257") << "cp 1257" << "cp 1257" << "cp 1257"; QTest::newRow("jis7") << "jis7" << "jis7" << "jis7"; QTest::newRow("sjis") << "sjis" << "sjis" << "sjis"; QTest::newRow("ucs2") << "ucs2" << "ucs2" << "ucs2"; QTest::newRow("utf7") << "utf7" << "utf7" << "utf7"; QTest::newRow("windows-1258") << "windows-1258" << "windows-1258" << "windows-1258"; QTest::newRow("winsami2") << "winsami2" << "winsami2" << "winsami2"; } void KCharsetsTest::testCodecForName() { KCharsets *singleton = KCharsets::charsets(); QFETCH(QString, codec); QFETCH(QString, expectedCodecFromKDE); QFETCH(QString, expectedCodecFromQt); if (QTextCodec::codecForName(codec.toLocal8Bit()) == nullptr) { qWarning() << "codec " << codec << "is not supported by QTextCodec !"; return; } QVERIFY(QTextCodec::codecForName(expectedCodecFromKDE.toLocal8Bit()) != nullptr); QCOMPARE(singleton->codecForName(codec)->name(), QTextCodec::codecForName(expectedCodecFromKDE.toLocal8Bit())->name()); QVERIFY(QTextCodec::codecForName(expectedCodecFromQt.toLocal8Bit()) != nullptr); QCOMPARE(QTextCodec::codecForName(codec.toLocal8Bit())->name(), QTextCodec::codecForName(expectedCodecFromQt.toLocal8Bit())->name()); } void KCharsetsTest::testFromEntity() { KCharsets *singleton = KCharsets::charsets(); QCOMPARE(singleton->fromEntity(QString::fromLatin1("Ӓ")), QChar(1234)); QCOMPARE(singleton->fromEntity(QString::fromLatin1("ሴ")), QChar(0x1234)); QCOMPARE(singleton->fromEntity(QString::fromLatin1("lt")), QChar::fromLatin1('<')); QCOMPARE(singleton->fromEntity(QString::fromLatin1("gt")), QChar::fromLatin1('>')); QCOMPARE(singleton->fromEntity(QString::fromLatin1("quot")), QChar::fromLatin1('"')); QCOMPARE(singleton->fromEntity(QString::fromLatin1("amp")), QChar::fromLatin1('&')); QCOMPARE(singleton->fromEntity(QString::fromLatin1("apos")), QChar::fromLatin1('\'')); } void KCharsetsTest::testToEntity() { QSKIP("KCharsets::toEntity test not implemented."); } void KCharsetsTest::testResolveEntities() { KCharsets *singleton = KCharsets::charsets(); QCOMPARE(singleton->resolveEntities(QString::fromLatin1(""'<Hello &World>'"")), QString::fromLatin1("\"\'\'\"")); } void KCharsetsTest::testEncodingNames() { KCharsets *singleton = KCharsets::charsets(); QCOMPARE(singleton->availableEncodingNames().count(), singleton->descriptiveEncodingNames().count()); for (const QString &encodingName : singleton->availableEncodingNames()) { bool ok = false; if (encodingName == QLatin1String("ucs2") || encodingName == QLatin1String("ISO 10646-UCS-2")) { singleton->codecForName(QStringLiteral("UTF-16"), ok); } else if (encodingName == QLatin1String("utf7")) { continue; } else { singleton->codecForName(encodingName, ok); } // The availability of some of the charsets below depends on whether Qt was built with ICU... if (!ok) { if (encodingName == QLatin1String("jis7")) { QEXPECT_FAIL("", "jis7 is missing in Qt", Continue); } if (encodingName == QLatin1String("winsami2")) { QEXPECT_FAIL("", "winsami2 is missing in Qt", Continue); } if (encodingName == QLatin1String("ISO 8859-16")) { // ICU bug? QEXPECT_FAIL("", "ISO 8859-16 is missing in Qt", Continue); } } if (!ok) { qDebug() << "Error:" << encodingName << "not found"; QVERIFY(false); } QVERIFY(encodingNameHasADescription(encodingName, singleton->descriptiveEncodingNames())); QVERIFY(!singleton->descriptionForEncoding(encodingName).isEmpty()); QCOMPARE(singleton->encodingForName(singleton->descriptionForEncoding(encodingName)), encodingName); } } QTEST_MAIN(KCharsetsTest) diff --git a/autotests/kcharsetstest.h b/autotests/kcharsetstest.h index 5e3cb3c..08007ac 100644 --- a/autotests/kcharsetstest.h +++ b/autotests/kcharsetstest.h @@ -1,36 +1,25 @@ /* - * Copyright 2011 Romain Perier - * - * 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 2 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 . - */ + SPDX-FileCopyrightText: 2011 Romain Perier + + SPDX-License-Identifier: GPL-2.0-or-later +*/ #ifndef KCHARSETSTEST_H #define KCHARSETSTEST_H #include class KCharsetsTest: public QObject { Q_OBJECT private Q_SLOTS: void testSingleton(); void testCodecForName_data(); void testCodecForName(); void testFromEntity(); void testToEntity(); void testResolveEntities(); void testEncodingNames(); }; #endif /* KCHARSETSTEST_H */ diff --git a/autotests/kcodecstest.cpp b/autotests/kcodecstest.cpp index b7c87b9..54d9687 100644 --- a/autotests/kcodecstest.cpp +++ b/autotests/kcodecstest.cpp @@ -1,110 +1,98 @@ /* - Copyright (c) 2006 Volker Krause + SPDX-FileCopyrightText: 2006 Volker Krause - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-License-Identifier: LGPL-2.0-only */ #include #include "kcodecstest.h" #include "../src/kcodecs.h" QTEST_MAIN(KCodecsTest) void KCodecsTest::testRFC2047decode() { // empty QCOMPARE(KCodecs::decodeRFC2047String(QString()), QString()); // identity QCOMPARE(KCodecs::decodeRFC2047String("bla"), QLatin1String("bla")); // utf-8 QCOMPARE(KCodecs::decodeRFC2047String("=?utf-8?q?Ingo=20Kl=C3=B6cker?= ", "utf-8"), QString::fromUtf8("Ingo Klöcker ")); QCOMPARE(KCodecs::decodeRFC2047String("=?utf-8?q?Ingo=20Kl=C3=B6cker?="), QString::fromUtf8("Ingo Klöcker")); // whitespaces between two encoded words /* QCOMPARE(KCodecs::decodeRFC2047String("=?utf-8?q?Ingo=20Kl=C3=B6cker?= =?utf-8?q?Ingo=20Kl=C3=B6cker?="), QString::fromUtf8("Ingo KlöckerIngo Klöcker")); */ /* QCOMPARE(KCodecs::decodeRFC2047String("=?utf-8?q?Ingo=20Kl=C3=B6cker?= foo =?utf-8?q?Ingo=20Kl=C3=B6cker?="), QString::fromUtf8("Ingo Klöcker foo Ingo Klöcker")); */ // iso-8859-x QCOMPARE(KCodecs::decodeRFC2047String("=?ISO-8859-1?Q?Andr=E9s_Ot=F3n?=", "utf-8"), QString::fromUtf8("Andrés Otón")); QCOMPARE(KCodecs::decodeRFC2047String("=?iso-8859-2?q?Rafa=B3_Rzepecki?=", "utf-8"), QString::fromUtf8("RafaÅ‚ Rzepecki")); QCOMPARE(KCodecs::decodeRFC2047String("=?iso-8859-9?Q?S=2E=C7a=F0lar?= Onur", "utf-8"), QString::fromUtf8("S.ÇaÄŸlar Onur")); QCOMPARE(KCodecs::decodeRFC2047String("Rafael =?iso-8859-15?q?Rodr=EDguez?=", "utf-8"), QString::fromUtf8("Rafael Rodríguez")); // language parameter according to RFC 2231, section 5 QCOMPARE(KCodecs::decodeRFC2047String("From: =?US-ASCII*EN?Q?Keith_Moore?= "), QString::fromUtf8("From: Keith Moore ")); // broken qp endoding (using lowercase) QCOMPARE(KCodecs::decodeRFC2047String("Subject: =?iso-8859-1?Q?Belangrijk=3a=20Verhuizing=20FTP=20server?="), QString::fromUtf8("Subject: Belangrijk: Verhuizing FTP server")); // mixed charsets, based on bug 125542 but pasted from above instead since I'm unable to enter those asian symbols QCOMPARE(KCodecs::decodeRFC2047String("Subject: =?utf-8?q?Ingo=20Kl=C3=B6cker?= unencoded words =?iso-8859-9?Q?S=2E=C7a=F0lar?="), QString::fromUtf8("Subject: Ingo Klöcker unencoded words S.Çağlar")); // illegal characters which are already encoded in the given encoding but are not ASCII (bug 206417) QCOMPARE(KCodecs::decodeRFC2047String("Subject: =?utf-8?Q?ÿÞѿÞûû,=20=D0=B4=D0=BE=D0=B1=D1=80=D1=8B=D0=B9=20=D0=B4=D0=B5=D0=BD=D1=8C?="), QString::fromUtf8("Subject: ÿÞѿÞûû, Îßñрыù ÎõÜь")); QCOMPARE(KCodecs::decodeRFC2047String("Subject: =?iso-8859-1?Q?ÖÄÜöäü?="), QString::fromLatin1("Subject: ÖÄÜöäü")); // Small data QCOMPARE(KCodecs::decodeRFC2047String("=?iso-8859-1?Q?c?="), QString::fromUtf8("c")); } void KCodecsTest::testInvalidDecode() { QByteArray encCharset; // invalid / incomplete encoded data QCOMPARE(KCodecs::decodeRFC2047String("="), QString::fromUtf8("=")); QCOMPARE(KCodecs::decodeRFC2047String("=?"), QString::fromUtf8("=?")); QCOMPARE(KCodecs::decodeRFC2047String("=?a?b?="), QString::fromUtf8("=?a?b?=")); QCOMPARE(KCodecs::decodeRFC2047String("=?a?b?c?"), QString::fromUtf8("=?a?b?c?")); QCOMPARE(KCodecs::decodeRFC2047String("=?a??c?="), QString::fromUtf8("=?a??c?=")); } void KCodecsTest::testRFC2047encode() { // empty QCOMPARE(KCodecs::encodeRFC2047String(QString(), "utf-8"), QByteArray()); // identity QCOMPARE(KCodecs::encodeRFC2047String(QLatin1String("bla"), "utf-8"), QByteArray("bla")); // utf-8 // expected value is probably wrong, libkmime will chose 'B' instead of 'Q' encoding QEXPECT_FAIL("", "libkmime will chose 'B' instead of 'Q' encoding", Continue); QCOMPARE(KCodecs::encodeRFC2047String(QString::fromUtf8("Ingo Klöcker "), "utf-8").constData(), "=?utf-8?q?Ingo=20Kl=C3=B6cker?= "); // Fallback to UTF-8 for encoding since the given charset can't encode the string const QString input = QString::fromUtf8("Êſðđŋħł"); const QByteArray result = KCodecs::encodeRFC2047String(input, "latin1"); QCOMPARE(KCodecs::decodeRFC2047String(result), input); QVERIFY(result.contains("utf-8")); } diff --git a/autotests/kcodecstest.h b/autotests/kcodecstest.h index 41a5689..5cfd0be 100644 --- a/autotests/kcodecstest.h +++ b/autotests/kcodecstest.h @@ -1,34 +1,22 @@ /* - Copyright (c) 2006 Volker Krause + SPDX-FileCopyrightText: 2006 Volker Krause - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-License-Identifier: LGPL-2.0-only */ #ifndef KCODECSTEST_H #define KCODECSTEST_H #include class KCodecsTest : public QObject { Q_OBJECT private Q_SLOTS: void testRFC2047decode(); void testInvalidDecode(); void testRFC2047encode(); }; #endif diff --git a/autotests/kemailaddresstest.cpp b/autotests/kemailaddresstest.cpp index 25a9063..917c5b4 100644 --- a/autotests/kemailaddresstest.cpp +++ b/autotests/kemailaddresstest.cpp @@ -1,587 +1,576 @@ /* - This file is part of the KDE project - Copyright (C) 2004 David Faure - Copyright (C) 2009 Thomas McGuire - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + This file is part of the KDE project + + SPDX-FileCopyrightText: 2004 David Faure + SPDX-FileCopyrightText: 2009 Thomas McGuire + + SPDX-License-Identifier: LGPL-2.0-only */ //krazy:excludeall=contractions #include "kemailaddresstest.h" #include "../src/kemailaddress.h" #include #include #include QTEST_MAIN(KEmailAddressTest) using namespace KEmailAddress; Q_DECLARE_METATYPE(EmailParseResult) void KEmailAddressTest::testGetNameAndEmail() { QFETCH(QString, input); QFETCH(QString, expName); QFETCH(QString, expEmail); QFETCH(bool, expRetVal); QString name, email; bool retVal = extractEmailAddressAndName(input, email, name); QCOMPARE(retVal, expRetVal); QCOMPARE(name, expName); QCOMPARE(email, expEmail); } void KEmailAddressTest::testGetNameAndEmail_data() { QTest::addColumn("input"); QTest::addColumn("expName"); QTest::addColumn("expEmail"); QTest::addColumn("expRetVal"); QTest::newRow("Empty input") << QString() << QString() << QString() << false; QTest::newRow("Email only") << "faure@kde.org" << QString() << "faure@kde.org" << false; QTest::newRow("Normal case") << "David Faure " << "David Faure" << "faure@kde.org" << true; QTest::newRow("Double-quotes 1") << "\"Faure, David\" " << "Faure, David" << "faure@kde.org" << true; QTest::newRow("Double-quotes 2") << " \"David Faure\"" << "David Faure" << "faure@kde.org" << true; QTest::newRow("Parenthesis 1") << "faure@kde.org (David Faure)" << "David Faure" << "faure@kde.org" << true; QTest::newRow("Parenthesis 2") << "(David Faure) faure@kde.org" << "David Faure" << "faure@kde.org" << true; QTest::newRow("Parenthesis 3") << "My Name (me) " << "My Name (me)" << "me@home.net" << true; // #93513 // As per https://intevation.de/roundup/kolab/issue858 QTest::newRow("Nested parenthesis") << "faure@kde.org (David (The Man) Faure)" << "David (The Man) Faure" << "faure@kde.org" << true; QTest::newRow("Double-quotes inside parenthesis 1") << "faure@kde.org (David \"Crazy\" Faure)" << "David \"Crazy\" Faure" << "faure@kde.org" << true; QTest::newRow("Double-quotes inside parenthesis 2") << "(David \"Crazy\" Faure) faure@kde.org" << "David \"Crazy\" Faure" << "faure@kde.org" << true; QTest::newRow("Parenthesis inside double-quotes 1") << "\"Faure (David)\" " << "Faure (David)" << "faure@kde.org" << true; QTest::newRow("Parenthesis inside double-quotes 2") << " \"Faure (David)\"" << "Faure (David)" << "faure@kde.org" << true; QTest::newRow("Space in email") << "David Faure < faure@kde.org >" << "David Faure" << "faure@kde.org" << true; QTest::newRow("'@' in name 1") << "faure@kde.org (a@b)" << "a@b" << "faure@kde.org" << true; QTest::newRow("'@' in name 2") << "\"a@b\" " << "a@b" << "faure@kde.org" << true; // While typing, when there's no '@' yet QTest::newRow("while typing 1") << "foo" << "foo" << QString() << false; QTest::newRow("while typing 2") << "foo <" << "foo" << QString() << false; QTest::newRow("while typing 3") << "foo , KHZ " << "Faure, David" << "faure@kde.org" << true; QTest::newRow("domain literals") << "Matt Douhan " << "Matt Douhan" << "matt@[123.123.123.123]" << true; QTest::newRow("@ inside the comment") << "\"Matt@Douhan\" " << "Matt@Douhan" << "matt@fruitsalad.org" << true; QTest::newRow("No '@'") << "foo " << "foo" << "distlist" << true; QTest::newRow("Backslash in display name") << "\"Lastname\\, Firstname\"" " " << "Lastname, Firstname" << "firstname@lastname.com" << true; QTest::newRow("# in domain") << "Matt Douhan " << "Matt Douhan" << "dm3tt@db0zdf.#rpl.deu.eu" << true; } void KEmailAddressTest::testIsValidEmailAddress() { QFETCH(QString, input); QFETCH(EmailParseResult, expErrorCode); QCOMPARE(isValidAddress(input), expErrorCode); } void KEmailAddressTest::testIsValidEmailAddress_data() { QTest::addColumn("input"); QTest::addColumn("expErrorCode"); // Too many @'s QTest::newRow("1") << "matt@@fruitsalad.org" << TooManyAts; // Too few @'s QTest::newRow("2") << "mattfruitsalad.org" << TooFewAts; // An empty string QTest::newRow("3") << QString() << AddressEmpty; // email address starting with a @ QTest::newRow("4") << "@mattfruitsalad.org" << MissingLocalPart; // make sure that starting @ and an additional @ in the same email address don't conflict // trap the starting @ first and break QTest::newRow("5") << "@matt@fruitsalad.org" << MissingLocalPart; // email address ending with a @ QTest::newRow("6") << "mattfruitsalad.org@" << MissingDomainPart; // make sure that ending with@ and an additional @ in the email address don't conflict QTest::newRow("7") << "matt@fruitsalad.org@" << MissingDomainPart; // unbalanced Parens QTest::newRow("8") << "mattjongel)@fruitsalad.org" << UnbalancedParens; // unbalanced Parens the other way around QTest::newRow("9") << "mattjongel(@fruitsalad.org" << UnbalancedParens; // Correct parens just to make sure it works QTest::newRow("10") << "matt(jongel)@fruitsalad.org" << AddressOk; // Check that anglebrackets are closed QTest::newRow("11") << "matt douhanmatt@fruitsalad.org" << UnopenedAngleAddr; // Check that angle brackets are closed the other way around, and anglebrackets in domainpart // instead of local part QTest::newRow("13") << "matt douhan matt@" << AddressOk; // a full email address with comments angle brackets and the works should be valid too QTest::newRow("15") << "Matt (jongel) Douhan " << AddressOk; // Double quotes QTest::newRow("16") << "\"Matt Douhan\" " << AddressOk; // Double quotes inside parens QTest::newRow("17") << "Matt (\"jongel\") Douhan " << AddressOk; // DOuble quotes not closed QTest::newRow("18") << "Matt \"jongel Douhan " << UnbalancedQuote; // Parens inside double quotes QTest::newRow("19") << "Matt \"(jongel)\" Douhan " << AddressOk; // Space in email QTest::newRow("20") << "Matt Douhan < matt@fruitsalad.org >" << AddressOk; // @ is allowed inisde doublequotes QTest::newRow("21") << "\"matt@jongel\" " << AddressOk; // anglebrackets inside dbl quotes QTest::newRow("22") << "\"matt\" " << AddressOk; // a , inside a double quoted string is OK, how do I know this? well Ingo says so // and it makes sense since it is also a separator of email addresses QTest::newRow("23") << "\"Douhan, Matt\" " << AddressOk; // Domains literals also need to work QTest::newRow("24") << "Matt Douhan " << AddressOk; // Typo in domain literal address QTest::newRow("25") << "Matt Douhan " << UnexpectedComma; // Some more insane tests but still valid so they must work QTest::newRow("26") << "Matt Douhan <\"m@att\"@jongel.com>" << AddressOk; // BUG 99657 QTest::newRow("27") << "matt@jongel.fibbel.com" << AddressOk; // BUG 98720 QTest::newRow("28") << "mailto:@mydomain" << DisallowedChar; // correct error msg when a comma is inside <> QTest::newRow("29") << "Matt Douhan " << UnexpectedComma; //several commentlevels QTest::newRow("30") << "Matt Douhan (hey(jongel)fibbel) " << AddressOk; // several comment levels and one (the outer) being unbalanced QTest::newRow("31") << "Matt Douhan (hey(jongel)fibbel " << UnbalancedParens; // several comment levels and one (the inner) being unbalanced QTest::newRow("32") << "Matt Douhan (hey(jongelfibbel) " << UnbalancedParens; // an error inside a double quote is no error QTest::newRow("33") << "Matt Douhan \"(jongel\" " << AddressOk; // inside a quoted string double quotes are only allowed in pairs as per rfc2822 QTest::newRow("34") << "Matt Douhan \"jongel\"fibbel\" " << UnbalancedQuote; // a questionmark is valid in an atom QTest::newRow("35") << "Matt? " << AddressOk; // weird but OK QTest::newRow("36") << "\"testing, \\\"testing\" " << AddressOk; // escape a quote to many to see if it makes it invalid QTest::newRow("37") << "\"testing, \\\"testing\\\" " << UnbalancedQuote; // escape a parens and thus make a comma appear QTest::newRow("38") << "Matt (jongel, fibbel\\) " << UnbalancedParens; // several errors inside doublequotes QTest::newRow("39") << "Matt \"(jongel,\\\" < fibbel\\)\" " << AddressOk; // BUG 105705 QTest::newRow("40") << "matt-@fruitsalad.org" << AddressOk; // underscore at the end of local part QTest::newRow("41") << "matt_@fruitsalad.org" << AddressOk; // how about ( comment ) in the domain part QTest::newRow("42") << "matt_@(this is a cool host)fruitsalad.org" << AddressOk; // To quote rfc2822 the test below is aesthetically displeasing, but perfectly legal. QTest::newRow("43") << "Pete(A wonderful \\) chap) " << AddressOk; // quoted pair or not quoted pair QTest::newRow("44") << "\"jongel '\\\" fibbel\" " << AddressOk; QTest::newRow("45") << "\"jongel '\" fibbel\" " << UnbalancedQuote; // full atext support according to rfc2822 QTest::newRow("46") << "!matt@fruitsalad.org" << AddressOk; QTest::newRow("47") << "#matt@fruitsalad.org" << AddressOk; QTest::newRow("48") << "$matt@fruitsalad.org" << AddressOk; QTest::newRow("49") << "%matt@fruitsalad.org" << AddressOk; QTest::newRow("50") << "&matt@fruitsalad.org" << AddressOk; QTest::newRow("51") << "'matt@fruitsalad.org" << AddressOk; QTest::newRow("52") << "*matt@fruitsalad.org" << AddressOk; QTest::newRow("53") << "+matt@fruitsalad.org" << AddressOk; QTest::newRow("54") << "/matt@fruitsalad.org" << AddressOk; QTest::newRow("55") << "=matt@fruitsalad.org" << AddressOk; QTest::newRow("56") << "?matt@fruitsalad.org" << AddressOk; QTest::newRow("57") << "^matt@fruitsalad.org" << AddressOk; QTest::newRow("58") << "_matt@fruitsalad.org" << AddressOk; QTest::newRow("59") << "-matt@fruitsalad.org" << AddressOk; QTest::newRow("60") << "`matt@fruitsalad.org" << AddressOk; QTest::newRow("61") << "{matt@fruitsalad.org" << AddressOk; QTest::newRow("62") << "|matt@fruitsalad.org" << AddressOk; QTest::newRow("63") << "}matt@fruitsalad.org" << AddressOk; QTest::newRow("64") << "~matt@fruitsalad.org" << AddressOk; QTest::newRow("65") << "matt%matt@fruitsalad.org" << AddressOk; //bug 105405 QTest::newRow("66") << "[foobar] " << InvalidDisplayName; QTest::newRow("67") << "matt \"[foobar]\" Douhan " << AddressOk; QTest::newRow("68") << "Matt Douhan " << TooFewAts; QTest::newRow("# in domain") << "dm3tt@db0zdf.#rpl.deu.eu" << AddressOk; QTest::newRow("dot at the end") << "msadmin@guug.de." << AddressOk; QTest::newRow("dot at the end with brackets") << "Martin Schulte " << AddressOk; //TODO this should be a valid email address, but the checking for missing dots broke it. // QTest::newRow( "valid email address without dots" ) << "user@localhost" << AddressOk; } void KEmailAddressTest::testIsValidAddressList() { QFETCH(QString, list); QFETCH(EmailParseResult, expErrorCode); QString badAddress; QCOMPARE(isValidAddressList(list, badAddress), expErrorCode); } void KEmailAddressTest::testIsValidAddressList_data() { QTest::addColumn("list"); QTest::addColumn("expErrorCode"); //bug 139477 QTest::newRow("1") << "martin.schulte@guug.de, msadmin@guug.de," " msnewsletter@guug.de" << AddressOk; QTest::newRow("2") << "martin.schulte@guug.de; msadmin@guug.de;" " msnewsletter@guug.de" << AddressOk; QTest::newRow("3") << "martin.schulte@guug.de, msadmin@guug.de.," " msnewsletter@guug.de" << AddressOk; QTest::newRow("4") << "Martin Schulte ," " MS Admin , MS News " << AddressOk; QTest::newRow("5") << "Martin Schulte ;" " MS Admin ; MS News " << AddressOk; QTest::newRow("6") << "Martin Schulte ," " MS Admin , MS News " << AddressOk; } void KEmailAddressTest::testIsValidSimpleEmailAddress() { QFETCH(QString, input); QFETCH(bool, expResult); QCOMPARE(isValidSimpleAddress(input), expResult); } void KEmailAddressTest::testIsValidSimpleEmailAddress_data() { QTest::addColumn("input"); QTest::addColumn("expResult"); // checks for "pure" email addresses in the form of xxx@yyy.tld QTest::newRow("") << "matt@fruitsalad.org" << true; QTest::newRow("") << QStringLiteral("test@täst.invalid") << true; // non-ASCII char as first char of IDN QTest::newRow("") << QStringLiteral("i_want@øl.invalid") << true; QTest::newRow("") << "matt@[123.123.123.123]" << true; QTest::newRow("") << "matt@[3.3.3.3]" << true; QTest::newRow("") << "matt@[4.4.4.4]" << true; QTest::newRow("") << "matt@[192.168.254.254]" << true; QTest::newRow("") << "\"matt\"@fruitsalad.org" << true; QTest::newRow("") << "-matt@fruitsalad.org" << true; QTest::newRow("") << "\"-matt\"@fruitsalad.org" << true; QTest::newRow("") << "matt@jongel.fibbel.com" << true; QTest::newRow("") << "Matt Douhan " << false; // BUG 105705 QTest::newRow("") << "matt-@fibbel.com" << true; QTest::newRow("") << "matt@fibbel-is-a-geek.com" << true; QTest::newRow("") << "matt_@fibbel.com" << true; // Check the defined chars for atext according to rfc2822 QTest::newRow("") << "!matt@fruitsalad.org" << true; QTest::newRow("") << "#matt@fruitsalad.org" << true; QTest::newRow("") << "$matt@fruitsalad.org" << true; QTest::newRow("") << "%matt@fruitsalad.org" << true; QTest::newRow("") << "&matt@fruitsalad.org" << true; QTest::newRow("") << "'matt@fruitsalad.org" << true; QTest::newRow("") << "*matt@fruitsalad.org" << true; QTest::newRow("") << "+matt@fruitsalad.org" << true; QTest::newRow("") << "/matt@fruitsalad.org" << true; QTest::newRow("") << "=matt@fruitsalad.org" << true; QTest::newRow("") << "?matt@fruitsalad.org" << true; QTest::newRow("") << "^matt@fruitsalad.org" << true; QTest::newRow("") << "_matt@fruitsalad.org" << true; QTest::newRow("") << "-matt@fruitsalad.org" << true; QTest::newRow("") << "`matt@fruitsalad.org" << true; QTest::newRow("") << "{matt@fruitsalad.org" << true; QTest::newRow("") << "|matt@fruitsalad.org" << true; QTest::newRow("") << "}matt@fruitsalad.org" << true; QTest::newRow("") << "~matt@fruitsalad.org" << true; // BUG 108476 QTest::newRow("") << "foo+matt@fruitsalad.org" << true; QTest::newRow("") << "bar=matt@fruitsalad.org" << true; QTest::newRow("") << "jongel-matt@fruitsalad.org" << true; QTest::newRow("") << "matt-@fruitsalad.org" << true; // check if the pure email address is wrong QTest::newRow("") << "mattfruitsalad.org" << false; QTest::newRow("") << "matt@[123.123.123.123" << false; QTest::newRow("") << "matt@123.123.123.123]" << false; QTest::newRow("") << "matt@[.123.123.123]" << false; QTest::newRow("") << "matt@[123.123.123]" << false; QTest::newRow("") << "\"matt@fruitsalad.org" << false; QTest::newRow("") << "matt\"@fruitsalad.org" << false; QTest::newRow("") << QString() << false; // BUG 203881 QTest::newRow("") << "2advance@my-site.com" << true; // and here some insane but still valid cases QTest::newRow("") << "\"m@tt\"@fruitsalad.org" << true; QTest::newRow("") << "matt\"@@\"fruitsalad.org" << false; QTest::newRow("# in domain") << "dm3tt@db0zdf.#rpl.deu.eu" << true; // add tests for missing local/domain parts QTest::newRow("") << "@mattfruitsalad.org" << false; QTest::newRow("") << "matt@" << false; QTest::newRow("") << "@" << false; } void KEmailAddressTest::testGetEmailAddress() { QFETCH(QString, input); QFETCH(QString, expResult); QCOMPARE(extractEmailAddress(input), expResult); } void KEmailAddressTest::testGetEmailAddress_data() { QTest::addColumn("input"); QTest::addColumn("expResult"); QTest::newRow("1") << "matt@fruitsalad.org" << "matt@fruitsalad.org"; QTest::newRow("2") << "Matt Douhan " << "matt@fruitsalad.org"; QTest::newRow("3") << "\"Matt Douhan \" " << "matt@fruitsalad.org"; QTest::newRow("4") << "\"Matt \" " << "matt@fruitsalad.org"; QTest::newRow("5") << "Matt Douhan (jongel) " << "matt@fruitsalad.org"; QTest::newRow("7") << "\"Douhan, Matt\" " << "matt@fruitsalad.org"; QTest::newRow("8") << "\"Matt Douhan (m@tt)\" " << "matt@fruitsalad.org"; QTest::newRow("9") << "\"Matt Douhan\" (matt " << QString(); QTest::newRow("10") << "Matt Douhan " << "matt@[123.123.123.123]"; QTest::newRow("11") << "dm3tt@db0zdf.#rpl.deu.eu" << "dm3tt@db0zdf.#rpl.deu.eu"; } void KEmailAddressTest::testCheckSplitEmailAddrList() { QFETCH(QString, input); QFETCH(QStringList, expResult); QCOMPARE(splitAddressList(input), expResult); } void KEmailAddressTest::testCheckSplitEmailAddrList_data() { QTest::addColumn("input"); QTest::addColumn("expResult"); QTest::newRow("") << "kloecker@kde.org (Kloecker, Ingo)" << (QStringList() << QStringLiteral("kloecker@kde.org (Kloecker, Ingo)")); QTest::newRow("") << "Matt Douhan , Foo Bar " << (QStringList() << QStringLiteral("Matt Douhan ") << QStringLiteral("Foo Bar ")); QTest::newRow("") << "\"Matt, Douhan\" , Foo Bar " << (QStringList() << QStringLiteral("\"Matt, Douhan\" ") << QStringLiteral("Foo Bar ")); QTest::newRow("") << "\"Lastname\\, Firstname\" " << (QStringList() << QStringLiteral("\"Lastname\\, Firstname\" ")); } void KEmailAddressTest::testNormalizeAddressesAndEncodeIDNs() { QFETCH(QString, input); QFETCH(QString, expResult); QCOMPARE(normalizeAddressesAndEncodeIdn(input), expResult); } void KEmailAddressTest::testNormalizeAddressesAndEncodeIDNs_data() { QTest::addColumn("input"); QTest::addColumn("expResult"); QTest::newRow("") << "matt@fruitsalad.org" << "matt@fruitsalad.org"; QTest::newRow("") << "Matt Douhan " << "Matt Douhan "; QTest::newRow("") << "Matt Douhan (jongel) " << "Matt Douhan (jongel) "; QTest::newRow("") << "Matt Douhan (jongel,fibbel) " << "Matt Douhan (jongel,fibbel) "; QTest::newRow("") << "matt@fruitsalad.org (jongel,fibbel)" << "\"jongel,fibbel\" "; QTest::newRow("") << "matt@fruitsalad.org (\"jongel,fibbel\")" << "\"jongel,fibbel\" "; } void KEmailAddressTest::testNormalizeAddressesAndDecodeIDNs() { QFETCH(QString, input); QFETCH(QString, expResult); QCOMPARE(normalizeAddressesAndDecodeIdn(input), expResult); } void KEmailAddressTest::testNormalizeAddressesAndDecodeIDNs_data() { QTest::addColumn("input"); QTest::addColumn("expResult"); QTest::newRow("") << "=?us-ascii?Q?Surname=2C=20Name?= " << "\"Surname, Name\" "; QTest::newRow("") << "=?iso-8859-1?B?5Hf8b2xmLPZBbmRyZWFz?= " << QStringLiteral("\"äwüolf,öAndreas\" "); QTest::newRow("") << QStringLiteral("\"Andreas Straß\" ") << QStringLiteral("\"Andreas Straß\" "); QTest::newRow("") << QStringLiteral("\"András\" \"ManÅ£ia\" ") << QStringLiteral("\"András\" \"ManÅ£ia\" "); } void KEmailAddressTest::testQuoteIfNecessary() { QFETCH(QString, input); QFETCH(QString, expResult); QCOMPARE(quoteNameIfNecessary(input), expResult); } void KEmailAddressTest::testQuoteIfNecessary_data() { QTest::addColumn("input"); QTest::addColumn("expResult"); QTest::newRow("") << "Matt Douhan" << "Matt Douhan"; QTest::newRow("") << "Douhan, Matt" << "\"Douhan, Matt\""; QTest::newRow("") << "Matt \"jongel\" Douhan" << "\"Matt \\\"jongel\\\" Douhan\""; QTest::newRow("") << "Matt \\\"jongel\\\" Douhan" << "\"Matt \\\"jongel\\\" Douhan\""; QTest::newRow("") << "trailing '\\\\' should never occur \\" << "\"trailing '\\\\' should never occur \\\""; QTest::newRow("") << "\"don't quote again\"" << "\"don't quote again\""; QTest::newRow("") << "\"leading double quote" << "\"\\\"leading double quote\""; QTest::newRow("") << "trailing double quote\"" << "\"trailing double quote\\\"\""; } void KEmailAddressTest::testMailtoUrls() { QFETCH(QString, input); const QUrl url = encodeMailtoUrl(input); qDebug() << url; QCOMPARE(url.scheme().toLatin1().data(), "mailto"); QCOMPARE(decodeMailtoUrl(url), input); qDebug() << decodeMailtoUrl(url); } void KEmailAddressTest::testMailtoUrls_data() { QTest::addColumn("input"); QTest::newRow("") << "tokoe@domain.com"; QTest::newRow("") << QStringLiteral("\"Tobias König\" "); QTest::newRow("") << QStringLiteral("\"Alberto Simões\" - Copyright (C) 2009 Thomas McGuire + This file is part of the KDE project - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. + SPDX-FileCopyrightText: 2004 David Faure + SPDX-FileCopyrightText: 2009 Thomas McGuire - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-License-Identifier: LGPL-2.0-only */ #ifndef TESTEMAIL_H #define TESTEMAIL_H #include class KEmailAddressTest : public QObject { Q_OBJECT private Q_SLOTS: void testGetNameAndEmail(); void testGetNameAndEmail_data(); void testIsValidEmailAddress(); void testIsValidEmailAddress_data(); void testIsValidAddressList(); void testIsValidAddressList_data(); void testIsValidSimpleEmailAddress(); void testIsValidSimpleEmailAddress_data(); void testGetEmailAddress(); void testGetEmailAddress_data(); void testCheckSplitEmailAddrList(); void testCheckSplitEmailAddrList_data(); void testNormalizeAddressesAndEncodeIDNs(); void testNormalizeAddressesAndEncodeIDNs_data(); void testNormalizeAddressesAndDecodeIDNs(); void testNormalizeAddressesAndDecodeIDNs_data(); void testQuoteIfNecessary(); void testQuoteIfNecessary_data(); void testMailtoUrls(); void testMailtoUrls_data(); }; #endif diff --git a/autotests/kencodingprobertest.cpp b/autotests/kencodingprobertest.cpp index 3b193c8..1679128 100644 --- a/autotests/kencodingprobertest.cpp +++ b/autotests/kencodingprobertest.cpp @@ -1,88 +1,77 @@ /* - * Copyright 2012 Ni Hui - * - * 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 2 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 . - */ + SPDX-FileCopyrightText: 2012 Ni Hui + + SPDX-License-Identifier: GPL-2.0-or-later +*/ #include "kencodingprobertest.h" #include #include #include static KEncodingProber *ep = nullptr; void KEncodingProberTest::initTestCase() { ep = new KEncodingProber; } void KEncodingProberTest::cleanupTestCase() { delete ep; ep = nullptr; } void KEncodingProberTest::cleanup() { ep->reset(); } void KEncodingProberTest::testReset() { ep->feed(QByteArray("some random data @*@#&jd")); ep->reset(); QCOMPARE(ep->state(), KEncodingProber::Probing); QCOMPARE(ep->encoding().toLower(), QByteArray("utf-8")); } void KEncodingProberTest::testProbe() { // utf-8 ep->setProberType(KEncodingProber::Universal); ep->feed(QByteArray::fromHex("e998bfe5b094e58d91e696afe5b1b1e88489")); QCOMPARE(ep->encoding().toLower(), QByteArray("utf-8")); ep->reset(); // gb18030 ep->setProberType(KEncodingProber::ChineseSimplified); ep->feed(QByteArray::fromHex("d7d4d3c9b5c4b0d9bfc6c8abcae9")); QCOMPARE(ep->encoding().toLower(), QByteArray("gb18030")); ep->reset(); // shift_jis ep->setProberType(KEncodingProber::Japanese); ep->feed(QByteArray::fromHex("8374838a815b955389c88e969354")); QCOMPARE(ep->encoding().toLower(), QByteArray("shift_jis")); ep->reset(); // big5 ep->setProberType(KEncodingProber::ChineseTraditional); ep->feed(QByteArray::fromHex("aefcafc7a6caa474a141a6b3ae65a444a46a")); QCOMPARE(ep->encoding().toLower(), QByteArray("big5")); ep->reset(); // binary data, just make sure we do not crash (cf. crash in bug #357341) const QDir dataDir(QFINDTESTDATA("data")); const QString binaryFile = dataDir.filePath(QStringLiteral("binary_data")); QFile file(binaryFile); QVERIFY(file.open(QIODevice::ReadOnly)); QByteArray binaryData(file.readAll()); ep->setProberType(KEncodingProber::Universal); ep->feed(binaryData); QCOMPARE(ep->encoding().toLower(), QByteArray("utf-8")); ep->reset(); } QTEST_MAIN(KEncodingProberTest) diff --git a/autotests/kencodingprobertest.h b/autotests/kencodingprobertest.h index 3948308..68c40b5 100644 --- a/autotests/kencodingprobertest.h +++ b/autotests/kencodingprobertest.h @@ -1,34 +1,23 @@ /* - * Copyright 2012 Ni Hui - * - * 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 2 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 . - */ + SPDX-FileCopyrightText: 2012 Ni Hui + + SPDX-License-Identifier: GPL-2.0-or-later +*/ #ifndef KENCODINGPROBERTEST_H #define KENCODINGPROBERTEST_H #include class KEncodingProberTest: public QObject { Q_OBJECT private Q_SLOTS: void initTestCase(); void cleanupTestCase(); void cleanup(); void testReset(); void testProbe(); }; #endif // KENCODINGPROBERTEST_H diff --git a/autotests/rfc2047test.cpp b/autotests/rfc2047test.cpp index 006e5a1..caf1df6 100644 --- a/autotests/rfc2047test.cpp +++ b/autotests/rfc2047test.cpp @@ -1,180 +1,168 @@ /* - Copyright (c) 2006 Volker Krause + SPDX-FileCopyrightText: 2006 Volker Krause - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-License-Identifier: LGPL-2.0-only */ #include #include "rfc2047test.h" #include "../src/kcodecs.h" using namespace KCodecs; QTEST_MAIN(RFC2047Test) void RFC2047Test::testRFC2047decode_data() { QTest::addColumn("input"); QTest::addColumn("expectedCharset"); QTest::addColumn("defaultCharset"); QTest::addColumn("forceCharset"); QTest::addColumn("expectedResult"); QTest::newRow("empty") << QByteArray() << QByteArray() << QByteArray("utf-8") << false << QString(); QTest::newRow("identity") << QByteArray("bla") << QByteArray() << QByteArray("utf-8") << false << QString::fromLatin1("bla"); QTest::newRow("utf-8") << QByteArray("=?utf-8?q?Ingo=20Kl=C3=B6cker?= ") << QByteArray("UTF-8") << QByteArray("utf-8") << false << QString::fromUtf8("Ingo Klöcker "); QTest::newRow("utf-8") << QByteArray("=?utf-8?q?Ingo=20Kl=C3=B6cker?= ") << QByteArray("UTF-8") << QByteArray("iso8859-1") << false << QString::fromUtf8("Ingo Klöcker "); QTest::newRow("utf-8") << QByteArray("=?utf-8?q?Ingo=20Kl=C3=B6cker?=") << QByteArray("UTF-8") << QByteArray("utf-8") << false << QString::fromUtf8("Ingo Klöcker"); QTest::newRow("whitespaces") << QByteArray("=?utf-8?q?Ingo=20Kl=C3=B6cker?= =?utf-8?q?Ingo=20Kl=C3=B6cker?=") << QByteArray("UTF-8") << QByteArray("utf-8") << false << QString::fromUtf8("Ingo KlöckerIngo Klöcker"); QTest::newRow("whitespaces") << QByteArray("=?utf-8?q?Ingo=20Kl=C3=B6cker?= foo =?utf-8?q?Ingo=20Kl=C3=B6cker?=") << QByteArray("UTF-8") << QByteArray("utf-8") << false << QString::fromUtf8("Ingo Klöcker foo Ingo Klöcker"); QTest::newRow("iso-8859-1") << QByteArray("=?ISO-8859-1?Q?Andr=E9s_Ot=F3n?=") << QByteArray("ISO-8859-1") << QByteArray("utf-8") << false << QString::fromUtf8("Andrés Otón"); QTest::newRow("iso-8859-2") << QByteArray("=?iso-8859-2?q?Rafa=B3_Rzepecki?=") << QByteArray("ISO-8859-2") << QByteArray("utf-8") << false << QString::fromUtf8("RafaÅ‚ Rzepecki"); QTest::newRow("iso-8859-9") << QByteArray("=?iso-8859-9?Q?S=2E=C7a=F0lar?= Onur") << QByteArray("ISO-8859-9") << QByteArray("utf-8") << false << QString::fromUtf8("S.ÇaÄŸlar Onur"); QTest::newRow("iso-8859-15") << QByteArray("Rafael =?iso-8859-15?q?Rodr=EDguez?=") << QByteArray("ISO-8859-15") << QByteArray("utf-8") << false << QString::fromUtf8("Rafael Rodríguez"); QTest::newRow("wrong charset") << QByteArray("=?iso-8859-1?q?Ingo=20Kl=C3=B6cker?=") << QByteArray("UTF-8") << QByteArray("utf-8") << true << QString::fromUtf8("Ingo Klöcker"); // language parameter according to RFC 2231, section 5 QTest::newRow("RFC-2331") << QByteArray("From: =?US-ASCII*EN?Q?Keith_Moore?= ") << QByteArray("US-ASCII") << QByteArray("utf-8") << false << QString::fromUtf8("From: Keith Moore "); QTest::newRow("broken QP") << QByteArray("Subject: =?iso-8859-1?Q?Belangrijk=3a=20Verhuizing=20FTP=20server?=") << QByteArray("ISO-8859-1") << QByteArray("utf-8") << false << QString::fromUtf8("Subject: Belangrijk: Verhuizing FTP server"); // mixed charsets, based on bug 125542 but pasted from above instead since I'm unable to enter those asian symbols QTest::newRow("mixed charsets") << QByteArray("Subject: =?utf-8?q?Ingo=20Kl=C3=B6cker?= unencoded words =?iso-8859-9?Q?S=2E=C7a=F0lar?=") << QByteArray("ISO-8859-9") << QByteArray("utf-8") << false << QString::fromUtf8("Subject: Ingo Klöcker unencoded words S.ÇaÄŸlar"); // illegal characters which are already encoded in the given encoding but are not ASCII (bug 206417) QTest::newRow("illegal characters") << QByteArray("Subject: =?utf-8?Q?пиѿилл,=20=D0=B4=D0=BE=D0=B1=D1=80=D1=8B=D0=B9=20=D0=B4=D0=B5=D0=BD=D1=8C?=") << QByteArray("UTF-8") << QByteArray("utf-8") << false << QString::fromUtf8("Subject: пиѿилл, добрый день"); QTest::newRow("illegal characters") << QByteArray("Subject: =?iso-8859-1?Q?ÖÄÜöäü?=") << QByteArray("ISO-8859-1") << QByteArray("utf-8") << false << QString::fromLatin1("Subject: ÖÄÜöäü"); QTest::newRow("small data") << QByteArray("=?iso-8859-1?Q?c?=") << QByteArray("ISO-8859-1") << QByteArray("utf-8") << false << QString::fromUtf8("c"); } void RFC2047Test::testRFC2047decode() { QFETCH(QByteArray, input); QFETCH(QByteArray, expectedCharset); QFETCH(QByteArray, defaultCharset); QFETCH(bool, forceCharset); QFETCH(QString, expectedResult); QByteArray detectedCharset; const KCodecs::CharsetOption options = forceCharset ? KCodecs::ForceDefaultCharset : KCodecs::NoOption; const QString result = KCodecs::decodeRFC2047String(input, &detectedCharset, defaultCharset, options); QCOMPARE(result, expectedResult); QCOMPARE(detectedCharset, expectedCharset); } void RFC2047Test::testInvalidDecode_data() { QTest::addColumn("input"); QTest::addColumn("expectedResult"); QTest::newRow("") << QByteArray("=") << QString::fromUtf8("="); QTest::newRow("") << QByteArray("=?") << QString::fromUtf8("=?"); QTest::newRow("") << QByteArray("=?a?b?=") << QString::fromUtf8("=?a?b?="); QTest::newRow("") << QByteArray("=?a?b?c?") << QString::fromUtf8("=?a?b?c?"); QTest::newRow("") << QByteArray("=?a??c?=") << QString::fromUtf8("=?a??c?="); } void RFC2047Test::testInvalidDecode() { QFETCH(QByteArray, input); QFETCH(QString, expectedResult); QByteArray encCharset; const QString result = KCodecs::decodeRFC2047String(input, &encCharset); QCOMPARE(result, expectedResult); } void RFC2047Test::testRFC2047encode_data() { QTest::addColumn("input"); QTest::addColumn("encoding"); QTest::addColumn("expectedResult"); QTest::newRow("empty") << QString() << QByteArray("utf-8") << QByteArray(); QTest::newRow("identity") << QString::fromUtf8("bla") << QByteArray("utf-8") << QByteArray("bla"); QTest::newRow("QP") << QString::fromUtf8("Ingo Klöcker ") << QByteArray("utf-8") << QByteArray("=?utf-8?q?Ingo=20Kl=C3=B6cker?= "); QTest::newRow("utf-8 fallback") << QString::fromUtf8("æſðđŋħł") << QByteArray("latin1") << QByteArray("=?utf-8?B?w6bFv8OwxJHFi8SnxYI=?="); } void RFC2047Test::testRFC2047encode() { QFETCH(QString, input); QFETCH(QByteArray, encoding); QFETCH(QByteArray, expectedResult); const QByteArray result = KCodecs::encodeRFC2047String(input, encoding); // expected value is probably wrong, libkmime will chose 'B' instead of 'Q' encoding QEXPECT_FAIL("QP", "KCodecs will choose 'B' instead of 'Q' encoding", Continue); QCOMPARE(result, expectedResult); } diff --git a/autotests/rfc2047test.h b/autotests/rfc2047test.h index 6d1b56d..a45d037 100644 --- a/autotests/rfc2047test.h +++ b/autotests/rfc2047test.h @@ -1,39 +1,27 @@ /* - Copyright (c) 2006 Volker Krause + SPDX-FileCopyrightText: 2006 Volker Krause - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-License-Identifier: LGPL-2.0-only */ #ifndef RFC2047TEST_H #define RFC2047TEST_H #include class RFC2047Test : public QObject { Q_OBJECT private Q_SLOTS: void testRFC2047decode_data(); void testRFC2047decode(); void testInvalidDecode_data(); void testInvalidDecode(); void testRFC2047encode_data(); void testRFC2047encode(); }; #endif diff --git a/cmake/rules_PyKF5.py b/cmake/rules_PyKF5.py index bfff5ef..f031a52 100644 --- a/cmake/rules_PyKF5.py +++ b/cmake/rules_PyKF5.py @@ -1,64 +1,41 @@ +# SPDX-FileCopyrightText: 2016 Stephen Kelly # -# Copyright 2016 Stephen Kelly -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. The name of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - +# SPDX-License-Identifier: BSD-3-Clause import os, sys import rules_engine sys.path.append(os.path.dirname(os.path.dirname(rules_engine.__file__))) import Qt5Ruleset def local_container_rules(): return [ ["KCodecs", "Encoder", ".*", ".*", ".*", rules_engine.container_mark_abstract], ["KCodecs", "Decoder", ".*", ".*", ".*", rules_engine.container_mark_abstract], ["KCodecs", "Codec", ".*", ".*", ".*", rules_engine.container_mark_abstract], ] def local_function_rules(): return [ ["KCodecs::Codec", "encode", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCodecs::Codec", "decode", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCodecs::Encoder", "encode", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCodecs::Encoder", "finish", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCodecs::Encoder", "write", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCodecs::Encoder", "writeCRLF", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCodecs::Encoder", "flushOutputBuffer", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCodecs::Decoder", "decode", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCodecs::Decoder", "finish", ".*", ".*", ".*char.*&.*", rules_engine.function_discard], ["KCharsets", "codecForName", ".*", ".*", ".*bool &.*", rules_engine.function_discard], ["KCharsets", "fromEntity", ".*", ".*", ".*int &.*", rules_engine.function_discard], ] class RuleSet(Qt5Ruleset.RuleSet): def __init__(self): Qt5Ruleset.RuleSet.__init__(self) self._fn_db = rules_engine.FunctionRuleDb(lambda: local_function_rules() + Qt5Ruleset.function_rules()) self._container_db = rules_engine.ContainerRuleDb(lambda: local_container_rules() + Qt5Ruleset.container_rules()) diff --git a/src/kcharsets.cpp b/src/kcharsets.cpp index a6033c3..0c4b80b 100644 --- a/src/kcharsets.cpp +++ b/src/kcharsets.cpp @@ -1,849 +1,838 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Lars Knoll (knoll@kde.org) - Copyright (C) 2001, 2003, 2004, 2005, 2006 Nicolas GOUTTE - Copyright (C) 2007 Nick Shaforostoff - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. +/* + This file is part of the KDE libraries + + SPDX-FileCopyrightText: 1999 Lars Knoll + SPDX-FileCopyrightText: 2001, 2003, 2004, 2005, 2006 Nicolas GOUTTE + SPDX-FileCopyrightText: 2007 Nick Shaforostoff + + SPDX-License-Identifier: LGPL-2.0-or-later */ #include "kcharsets.h" #include "kcodecs_debug.h" #include #include #include #include #include /* * The encoding names (like "ISO 8859-1") in this list are user-visible, * and should be mostly uppercase. * Generate with generate_string_table.pl (located in kde-dev-scripts), * input data: ISO 8859-1 i18n:Western European ISO 8859-15 i18n:Western European ISO 8859-14 i18n:Western European cp 1252 i18n:Western European IBM850 i18n:Western European ISO 8859-2 i18n:Central European ISO 8859-3 i18n:Central European ISO 8859-4 i18n:Baltic ISO 8859-13 i18n:Baltic ISO 8859-16 i18n:South-Eastern Europe cp 1250 i18n:Central European cp 1254 i18n:Turkish cp 1257 i18n:Baltic KOI8-R i18n:Cyrillic ISO 8859-5 i18n:Cyrillic cp 1251 i18n:Cyrillic KOI8-U i18n:Cyrillic IBM866 i18n:Cyrillic Big5 i18n:Chinese Traditional Big5-HKSCS i18n:Chinese Traditional GB18030 i18n:Chinese Simplified GBK i18n:Chinese Simplified GB2312 i18n:Chinese Simplified EUC-KR i18n:Korean cp 949 i18n:Korean sjis i18n:Japanese jis7 i18n:Japanese EUC-JP i18n:Japanese ISO 8859-7 i18n:Greek cp 1253 i18n:Greek ISO 8859-6 i18n:Arabic cp 1256 i18n:Arabic ISO 8859-8 i18n:Hebrew ISO 8859-8-I i18n:Hebrew cp 1255 i18n:Hebrew ISO 8859-9 i18n:Turkish TIS620 i18n:Thai ISO 8859-11 i18n:Thai UTF-8 i18n:Unicode UTF-16 i18n:Unicode utf7 i18n:Unicode ucs2 i18n:Unicode ISO 10646-UCS-2 i18n:Unicode winsami2 i18n:Northern Saami windows-1258 i18n:Other IBM874 i18n:Other TSCII i18n:Other */ /* * Notes about the table: * * - The following entries were disabled and removed from the table: ibm852 i18n:Central European pt 154 i18n:Cyrillic // ### TODO "PT 154" seems to have been removed from Qt * * - ISO 8559-11 is the deprecated name of TIS-620 * - utf7 is not in Qt * - UTF-16 is duplicated as "ucs2" and "ISO 10646-UCS-2" * - windows-1258: TODO * - IBM874: TODO * - TSCII: TODO */ /* * This redefines the QT_TRANSLATE_NOOP3 macro provided by Qt to indicate that * statically initialised text should be translated so that it expands to just * the string that should be translated, making it possible to use it in the * single string construct below. */ #undef QT_TRANSLATE_NOOP3 #define QT_TRANSLATE_NOOP3(a, b, c) b /* * THE FOLLOWING CODE IS GENERATED. PLEASE DO NOT EDIT BY HAND. * The script used was generate_string_table.pl which can be found in kde-dev-scripts. * It was then edited to use QT_TRANSLATE_NOOP3 instead of I18N_NOOP. */ static const char language_for_encoding_string[] = "ISO 8859-1\0" QT_TRANSLATE_NOOP3("KCharsets", "Western European", "@item Text character set")"\0" "ISO 8859-15\0" "ISO 8859-14\0" "cp 1252\0" "IBM850\0" "ISO 8859-2\0" QT_TRANSLATE_NOOP3("KCharsets", "Central European", "@item Text character set")"\0" "ISO 8859-3\0" "ISO 8859-4\0" QT_TRANSLATE_NOOP3("KCharsets", "Baltic", "@item Text character set")"\0" "ISO 8859-13\0" "ISO 8859-16\0" QT_TRANSLATE_NOOP3("KCharsets", "South-Eastern Europe", "@item Text character set")"\0" "cp 1250\0" "cp 1254\0" QT_TRANSLATE_NOOP3("KCharsets", "Turkish", "@item Text character set")"\0" "cp 1257\0" "KOI8-R\0" QT_TRANSLATE_NOOP3("KCharsets", "Cyrillic", "@item Text character set")"\0" "ISO 8859-5\0" "cp 1251\0" "KOI8-U\0" "IBM866\0" "Big5\0" QT_TRANSLATE_NOOP3("KCharsets", "Chinese Traditional", "@item Text character set")"\0" "Big5-HKSCS\0" "GB18030\0" QT_TRANSLATE_NOOP3("KCharsets", "Chinese Simplified", "@item Text character set")"\0" "GBK\0" "GB2312\0" "EUC-KR\0" QT_TRANSLATE_NOOP3("KCharsets", "Korean", "@item Text character set")"\0" "cp 949\0" "sjis\0" QT_TRANSLATE_NOOP3("KCharsets", "Japanese", "@item Text character set")"\0" "jis7\0" "EUC-JP\0" "ISO 8859-7\0" QT_TRANSLATE_NOOP3("KCharsets", "Greek", "@item Text character set")"\0" "cp 1253\0" "ISO 8859-6\0" QT_TRANSLATE_NOOP3("KCharsets", "Arabic", "@item Text character set")"\0" "cp 1256\0" "ISO 8859-8\0" QT_TRANSLATE_NOOP3("KCharsets", "Hebrew", "@item Text character set")"\0" "ISO 8859-8-I\0" "cp 1255\0" "ISO 8859-9\0" "TIS620\0" QT_TRANSLATE_NOOP3("KCharsets", "Thai", "@item Text character set")"\0" "ISO 8859-11\0" "UTF-8\0" QT_TRANSLATE_NOOP3("KCharsets", "Unicode", "@item Text character set")"\0" "UTF-16\0" "utf7\0" "ucs2\0" "ISO 10646-UCS-2\0" "winsami2\0" QT_TRANSLATE_NOOP3("KCharsets", "Northern Saami", "@item Text character set")"\0" "windows-1258\0" QT_TRANSLATE_NOOP3("KCharsets", "Other", "@item Text character set")"\0" "IBM874\0" "TSCII\0" "\0"; static const int language_for_encoding_indices[] = { 0, 11, 28, 11, 40, 11, 52, 11, 60, 11, 67, 78, 95, 78, 106, 117, 124, 117, 136, 148, 169, 78, 177, 185, 193, 117, 201, 208, 217, 208, 228, 208, 236, 208, 243, 208, 250, 255, 275, 255, 286, 294, 313, 294, 317, 294, 324, 331, 338, 331, 345, 350, 359, 350, 364, 350, 371, 382, 388, 382, 396, 407, 414, 407, 422, 433, 440, 433, 453, 433, 461, 185, 472, 479, 484, 479, 496, 502, 510, 502, 517, 502, 522, 502, 527, 502, 543, 552, 567, 580, 586, 580, 593, 580, -1 }; /* * GENERATED CODE ENDS HERE */ /* * defines some different names for codecs that are built into Qt. * The names in this list must be lower-case. * input data for generate_string_table.pl: iso-ir-111 koi8-r koi unified koi8-r us-ascii iso 8859-1 usascii iso 8859-1 ascii iso 8859-1 unicode-1-1-utf-7 utf-7 ucs2 iso-10646-ucs-2 iso10646-1 iso-10646-ucs-2 gb18030.2000-1 gb18030 gb18030.2000-0 gb18030 gbk-0 gbk gb2312 gbk gb2312.1980-0 gbk big5-0 big5 euc-kr euckr cp 949 windows-949 euc-jp eucjp jisx0201.1976-0 eucjp jisx0208.1983-0 eucjp jisx0208.1990-0 eucjp jisx0208.1997-0 eucjp jisx0212.1990-0 eucjp jisx0213.2000-1 eucjp jisx0213.2000-2 eucjp shift_jis sjis shift-jis sjis sjis sjis iso-2022-jp jis7 windows850 ibm850 windows866 ibm866 windows-850 ibm850 windows-866 ibm866 cp-10000 apple roman thai-tis620 iso 8859-11 windows-874 ibm874 windows874 ibm874 cp-874 ibm874 ksc5601.1987-0 euckr ks_c_5601-1987 euckr mac-roman apple roman macintosh apple roman mac apple roman csiso2022jp iso-2022-jp */ /* * Notes about the table: * - using ISO-8859-1 for ASCII is only an approximation (as you cannot test if a character is part of the set) * - utf7 is not in Qt * - UTF-16 is duplicated as "ucs2" and "ISO 10646-UCS-2" * - sjis: appears on the table for x-sjis * - jis7: ISO-2022-JP is now the default name in Qt4 * - cp-874: is it really needed? * - mac-roman: appears on the table for x-mac-roman * - csiso2022jp: See bug #77243 */ /* * THE FOLLOWING CODE IS GENERATED. PLEASE DO NOT EDIT BY HAND. * The script used was generate_string_table.pl which can be found in kde-dev-scripts. */ static const char builtin_string[] = "iso-ir-111\0" "koi8-r\0" "koi unified\0" "us-ascii\0" "iso 8859-1\0" "usascii\0" "ascii\0" "unicode-1-1-utf-7\0" "utf-7\0" "ucs2\0" "iso-10646-ucs-2\0" "iso10646-1\0" "gb18030.2000-1\0" "gb18030\0" "gb18030.2000-0\0" "gbk-0\0" "gbk\0" "gb2312\0" "gb2312.1980-0\0" "big5-0\0" "big5\0" "euc-kr\0" "euckr\0" "cp 949\0" "windows-949\0" "euc-jp\0" "eucjp\0" "jisx0201.1976-0\0" "jisx0208.1983-0\0" "jisx0208.1990-0\0" "jisx0208.1997-0\0" "jisx0212.1990-0\0" "jisx0213.2000-1\0" "jisx0213.2000-2\0" "shift_jis\0" "sjis\0" "shift-jis\0" "iso-2022-jp\0" "jis7\0" "windows850\0" "ibm850\0" "windows866\0" "ibm866\0" "windows-850\0" "windows-866\0" "cp-10000\0" "apple roman\0" "thai-tis620\0" "iso 8859-11\0" "windows-874\0" "ibm874\0" "windows874\0" "cp-874\0" "ksc5601.1987-0\0" "ks_c_5601-1987\0" "mac-roman\0" "macintosh\0" "mac\0" "csiso2022jp\0" "\0"; static const int builtin_indices[] = { 0, 11, 18, 11, 30, 39, 50, 39, 58, 39, 64, 82, 88, 93, 109, 93, 120, 135, 143, 135, 158, 164, 168, 164, 175, 164, 189, 196, 201, 208, 214, 221, 233, 240, 246, 240, 262, 240, 278, 240, 294, 240, 310, 240, 326, 240, 342, 240, 358, 368, 373, 368, 368, 368, 383, 395, 400, 411, 418, 429, 436, 411, 448, 429, 460, 469, 481, 493, 505, 517, 524, 517, 535, 517, 542, 208, 557, 208, 572, 469, 582, 469, 592, 469, 596, 383, -1 }; /* * GENERATED CODE ENDS HERE */ /* * some last resort hints in case the charmap file couldn't be found. * This gives at least a partial conversion and helps making things readable. * * the name used as input here is already converted to the more canonical * name as defined in the aliases array. * * Input data: cp1250 iso-8859-2 koi8-r iso-8859-5 koi8-u koi8-r pt 154 windows-1251 paratype-154 windows-1251 pt-154 windows-1251 */ /* Notes: * - KDE had always "CP 1251" as best fallback to PT 154. As Qt does not offer this encoding anymore, the codepage 1251 is used as fallback. */ /* * THE FOLLOWING CODE IS GENERATED. PLEASE DO NOT EDIT BY HAND. * The script used was generate_string_table.pl which can be found in kde-dev-scripts. */ static const char conversion_hints_string[] = "cp1250\0" "iso-8859-2\0" "koi8-r\0" "iso-8859-5\0" "koi8-u\0" "pt 154\0" "windows-1251\0" "paratype-154\0" "pt-154\0" "\0"; static const int conversion_hints_indices[] = { 0, 7, 18, 25, 36, 18, 43, 50, 63, 50, 76, 50, -1 }; /* * GENERATED CODE ENDS HERE */ struct KCharsetsSingletonPrivate { KCharsets instance; }; Q_GLOBAL_STATIC(KCharsetsSingletonPrivate, globalCharsets) // search an array of items index/data, find first matching index // and return data, or return 0 static inline const char *kcharsets_array_search(const char *start, const int *indices, const char *entry) { for (int i = 0; indices[i] != -1; i += 2) if (qstrcmp(start + indices[i], entry) == 0) { return start + indices[i + 1]; } return nullptr; } class KCharsetsPrivate { public: KCharsetsPrivate(KCharsets *_kc) { kc = _kc; codecForNameDict.reserve(43); } // Hash for the encoding names (sensitive case) QHash codecForNameDict; KCharsets *kc; //Cache list so QStrings can be implicitly shared QList encodingsByScript; }; // -------------------------------------------------------------------------- KCharsets::KCharsets() : d(new KCharsetsPrivate(this)) { } KCharsets::~KCharsets() { delete d; } QChar KCharsets::fromEntity(const QString &str) { QChar res = QChar::Null; if (str.isEmpty()) { return QChar::Null; } int pos = 0; if (str[pos] == QLatin1Char('&')) { pos++; } // Check for '�' or '�' sequence if (str[pos] == QLatin1Char('#') && str.length() - pos > 1) { bool ok; pos++; if (str[pos] == QLatin1Char('x') || str[pos] == QLatin1Char('X')) { pos++; // '�', hexadecimal character reference const QString tmp(str.mid(pos)); res = tmp.toInt(&ok, 16); } else { // '�', decimal character reference const QString tmp(str.mid(pos)); res = tmp.toInt(&ok, 10); } if (ok) { return res; } else { return QChar::Null; } } const QByteArray raw(str.toLatin1()); const entity *e = KCodecsEntities::kde_findEntity(raw.data(), raw.length()); if (!e) { //qCDebug(KCODECS_LOG) << "unknown entity " << str <<", len = " << str.length(); return QChar::Null; } //qCDebug(KCODECS_LOG) << "got entity " << str << " = " << e->code; return QChar(e->code); } QChar KCharsets::fromEntity(const QString &str, int &len) { // entities are never longer than 8 chars... we start from // that length and work backwards... len = 8; while (len > 0) { QString tmp = str.left(len); QChar res = fromEntity(tmp); if (res != QChar::Null) { return res; } len--; } return QChar::Null; } QString KCharsets::toEntity(const QChar &ch) { return QString::asprintf("�x%x;", ch.unicode()); } QString KCharsets::resolveEntities(const QString &input) { QString text = input; const QChar *p = text.unicode(); const QChar *end = p + text.length(); const QChar *ampersand = nullptr; bool scanForSemicolon = false; for (; p < end; ++p) { const QChar ch = *p; if (ch == QLatin1Char('&')) { ampersand = p; scanForSemicolon = true; continue; } if (ch != QLatin1Char(';') || scanForSemicolon == false) { continue; } assert(ampersand); scanForSemicolon = false; const QChar *entityBegin = ampersand + 1; const uint entityLength = p - entityBegin; if (entityLength == 0) { continue; } const QChar entityValue = KCharsets::fromEntity(QString(entityBegin, entityLength)); if (entityValue.isNull()) { continue; } const uint ampersandPos = ampersand - text.unicode(); text[(int)ampersandPos ] = entityValue; text.remove(ampersandPos + 1, entityLength + 1); p = text.unicode() + ampersandPos; end = text.unicode() + text.length(); ampersand = nullptr; } return text; } QStringList KCharsets::availableEncodingNames() const { QStringList available; for (const int *p = language_for_encoding_indices; *p != -1; p += 2) { available.append(QString::fromUtf8(language_for_encoding_string + *p)); } available.sort(); return available; } QString KCharsets::descriptionForEncoding(const QString &encoding) const { const char *lang = kcharsets_array_search(language_for_encoding_string, language_for_encoding_indices, encoding.toUtf8().data()); if (lang) return tr("%1 ( %2 )", "@item %1 character set, %2 encoding") .arg(tr(lang, "@item Text character set"), encoding); else { return tr("Other encoding (%1)", "@item").arg(encoding); } } QString KCharsets::encodingForName(const QString &descriptiveName) const { const int left = descriptiveName.lastIndexOf(QLatin1Char('(')); if (left < 0) { // No parenthesis, so assume it is a normal encoding name return descriptiveName.trimmed(); } QString name(descriptiveName.mid(left + 1)); const int right = name.lastIndexOf(QLatin1Char(')')); if (right < 0) { return name; } return name.left(right).trimmed(); } QStringList KCharsets::descriptiveEncodingNames() const { QStringList encodings; for (const int *p = language_for_encoding_indices; *p != -1; p += 2) { const QString name = QString::fromUtf8(language_for_encoding_string + p[0]); const QString description = tr(language_for_encoding_string + p[1], "@item Text character set"); encodings.append(tr("%1 ( %2 )", "@item Text encoding: %1 character set, %2 encoding").arg(description, name)); } encodings.sort(); return encodings; } QList KCharsets::encodingsByScript() const { if (!d->encodingsByScript.isEmpty()) { return d->encodingsByScript; } int i; for (const int *p = language_for_encoding_indices; *p != -1; p += 2) { const QString name = QString::fromUtf8(language_for_encoding_string + p[0]); const QString description = tr(language_for_encoding_string + p[1], "@item Text character set"); for (i = 0; i < d->encodingsByScript.size(); ++i) { if (d->encodingsByScript.at(i).at(0) == description) { d->encodingsByScript[i].append(name); break; } } if (i == d->encodingsByScript.size()) { d->encodingsByScript.append(QStringList() << description << name); } } return d->encodingsByScript; } QTextCodec *KCharsets::codecForName(const QString &n) const { if (n == QLatin1String("gb2312") || n == QLatin1String("gbk")) { return QTextCodec::codecForName("gb18030"); } const QByteArray name(n.toLatin1()); QTextCodec *codec = codecForNameOrNull(name); if (codec) { return codec; } else { return QTextCodec::codecForName("iso-8859-1"); } } QTextCodec *KCharsets::codecForName(const QString &n, bool &ok) const { if (n == QLatin1String("gb2312") || n == QLatin1String("gbk")) { ok = true; return QTextCodec::codecForName("gb18030"); } const QByteArray name(n.toLatin1()); QTextCodec *codec = codecForNameOrNull(name); if (codec) { ok = true; return codec; } else { ok = false; return QTextCodec::codecForName("iso-8859-1"); } } QTextCodec *KCharsets::codecForNameOrNull(const QByteArray &n) const { QTextCodec *codec = nullptr; if (n.isEmpty()) { #pragma message("KDE5 TODO: Any better ideas ?") // No name, assume system locale const QByteArray locale = "->locale<-"; if (d->codecForNameDict.contains(locale)) { return d->codecForNameDict.value(locale); } codec = QTextCodec::codecForLocale(); d->codecForNameDict.insert("->locale<-", codec); return codec; } // For a non-empty name, lookup the "dictionnary", in a case-sensitive way. else if (d->codecForNameDict.contains(n)) { return d->codecForNameDict.value(n); } // If the name is not in the hash table, call directly QTextCoded::codecForName. // We assume that QTextCodec is smarter and more maintained than this code. codec = QTextCodec::codecForName(n); if (codec) { d->codecForNameDict.insert(n, codec); return codec; } // We have had no luck with QTextCodec::codecForName, so we must now process the name, so that QTextCodec::codecForName could work with it. QByteArray name = n.toLower(); bool changed = false; if (name.endsWith("_charset")) { // krazy:exclude=strings name.chop(8); changed = true; } if (name.startsWith("x-")) { // krazy:exclude=strings name.remove(0, 2); // remove x- at start changed = true; } if (name.isEmpty()) { // We have no name anymore, therefore the name is invalid. return nullptr; } // We only need to check changed names. if (changed) { codec = QTextCodec::codecForName(name); if (codec) { d->codecForNameDict.insert(n, codec); return codec; } changed = false; } // these codecs are built into Qt, but the name given for the codec is different, // so QTextCodec did not recognize it. QByteArray cname = kcharsets_array_search(builtin_string, builtin_indices, name.data()); if (!cname.isEmpty()) { codec = QTextCodec::codecForName(cname); } if (codec) { d->codecForNameDict.insert(n, codec); return codec; } // this also failed, the last resort is now to take some compatibility charmap // ### TODO: while emergency conversions might be useful at read, it is not sure if they should be done if the application plans to write. cname = kcharsets_array_search(conversion_hints_string, conversion_hints_indices, name.data()); if (!cname.isEmpty()) { codec = QTextCodec::codecForName(cname); if (codec) { d->codecForNameDict.insert(n, codec); return codec; } } // we could not assign a codec, therefore return NULL return nullptr; } KCharsets *KCharsets::charsets() { return &globalCharsets()->instance; } diff --git a/src/kcharsets.h b/src/kcharsets.h index f629dab..cd71b64 100644 --- a/src/kcharsets.h +++ b/src/kcharsets.h @@ -1,175 +1,163 @@ -/* This file is part of the KDE libraries - Copyright (C) 1999 Lars Knoll (knoll@kde.org) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. +/* + This file is part of the KDE libraries + SPDX-FileCopyrightText: 1999 Lars Knoll + + SPDX-License-Identifier: LGPL-2.0-or-later */ #ifndef KCHARSETS_H #define KCHARSETS_H #include #include #include class KCharsets; class KCharsetsPrivate; class QChar; class QString; class QStringList; class QTextCodec; /** * @class KCharsets kcharsets.h KCharsets * * Charset font and encoder/decoder handling. * * This is needed, because Qt's encoding name matching in * QTextCodec::codecForName matches only closely-related encoded names * but not alternate names, e.g. found in the reality of the Internet. */ class KCODECS_EXPORT KCharsets { Q_DECLARE_TR_FUNCTIONS(KCharsets) protected: /** Protected constructor. If you need the kcharsets object, use KCharsets::charsets() instead. */ KCharsets(); public: /** * Destructor. */ virtual ~KCharsets(); /** * Provided for compatibility. * @param name the name of the codec * @return the QTextCodec. If the desired codec could not be found, * it returns a default (ISO 8859-1) codec */ QTextCodec *codecForName(const QString &name) const; /** * Tries to find a QTextCodec to convert the given encoding from and to * Unicode. * * If no codec could be found, the ISO 8859-1 codec will be returned an * and @p ok will be set to false. * * @param n the name of the codec * @param ok true if a matching codec has been found, false if not * @return the QTextCodec. If the desired codec could not be found, * it returns a default (ISO 8859-1) codec */ QTextCodec *codecForName(const QString &n, bool &ok) const; /** * The global charset manager. * @return the global charset manager */ static KCharsets *charsets(); /** * @brief Converts an entity to a character. * * The string must contain only the * entity without the trailing ';'. * @param str the entity * @return QChar::Null if the entity could not be decoded. */ static QChar fromEntity(const QString &str); /** * Overloaded member function. Tries to find an entity in the * QString str. * @param str the string containing entified * @param len is a return value, that gives the length of the decoded * entity. * @return a decoded entity if one could be found, QChar::null * otherwise */ static QChar fromEntity(const QString &str, int &len); /** * Converts a QChar to an entity. The returned string does already * contain the leading '&' and the trailing ';'. * @param ch the char to convert * @return the entity */ static QString toEntity(const QChar &ch); /** * Scans the given string for entities (like &amp;) and resolves them * using fromEntity. * @param text the string containing the entities * @return the clean string */ static QString resolveEntities(const QString &text); /** * Lists all available encodings as names. * @return the list of all encodings */ QStringList availableEncodingNames() const; /** * Lists the available encoding names together with a more descriptive language. * @return the list of descriptive encoding names */ QStringList descriptiveEncodingNames() const; /** * Lists the available encoding names grouped by script (or language that uses them). * @returns the list of lists consisting of description followed by encoding names (i.e. encodingsByScript().at(i).at(0) is a description for encodingsByScript().at(i).at(k), k>0) */ QList encodingsByScript() const; /** * @brief Returns a long description for an encoding name. * @param encoding the encoding for the language * @return the long description for the encoding */ QString descriptionForEncoding(const QString &encoding) const; /** * Returns the encoding for a string obtained with descriptiveEncodingNames(). * @param descriptiveName the descriptive name for the encoding * @return the name of the encoding */ QString encodingForName(const QString &descriptiveName) const; private: KCharsetsPrivate *const d; friend struct KCharsetsSingletonPrivate; /** * @brief Get the QTextCodec for the name or return NULL * * This function is similar to KCharsets::codecForName except that it * can return a NULL value when the name was not found. * * @param n name of the text codec * @return pointer to the QTextCodec or NULL * @todo Make this function public when it is clear what API is needed. */ QTextCodec *codecForNameOrNull(const QByteArray &n) const; }; #endif diff --git a/src/kcodecs.cpp b/src/kcodecs.cpp index ebd8423..0ccaaf9 100644 --- a/src/kcodecs.cpp +++ b/src/kcodecs.cpp @@ -1,780 +1,769 @@ /* - Copyright (C) 2000-2001 Dawit Alemayehu - Copyright (C) 2001 Rik Hemsley (rikkus) - Copyright (c) 2001-2002 Marc Mutz + SPDX-FileCopyrightText: 2000-2001 Dawit Alemayehu + SPDX-FileCopyrightText: 2001 Rik Hemsley (rikkus) + SPDX-FileCopyrightText: 2001-2002 Marc Mutz - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License (LGPL) - version 2 as published by the Free Software Foundation. + SPDX-License-Identifier: LGPL-2.0-only - 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 Lesser General Public License for more details. + RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992. // krazy:exclude=copyright + RSA Data Security, Inc. Created 1991. All rights reserved. - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + The KMD5 class is based on a C++ implementation of + "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by + Mordechai T. Abzug, Copyright (c) 1995. This implementation // krazy:exclude=copyright + passes the test-suite as defined in RFC 1321. - RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992. // krazy:exclude=copyright - RSA Data Security, Inc. Created 1991. All rights reserved. + The encoding and decoding utilities in KCodecs with the exception of + quoted-printable are based on the java implementation in HTTPClient + package by Ronald Tschalär Copyright (C) 1996-1999. // krazy:exclude=copyright - The KMD5 class is based on a C++ implementation of - "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by - Mordechai T. Abzug, Copyright (c) 1995. This implementation // krazy:exclude=copyright - passes the test-suite as defined in RFC 1321. - - The encoding and decoding utilities in KCodecs with the exception of - quoted-printable are based on the java implementation in HTTPClient - package by Ronald Tschalär Copyright (C) 1996-1999. // krazy:exclude=copyright - - The quoted-printable codec as described in RFC 2045, section 6.7. is by - Rik Hemsley (C) 2001. + The quoted-printable codec as described in RFC 2045, section 6.7. is by + Rik Hemsley (C) 2001. */ #include "kcodecs.h" #include "kcodecs_p.h" #include "kcodecsbase64.h" #include "kcodecsidentity.h" #include "kcodecsqp.h" #include "kcodecsuuencode.h" #include "kcharsets.h" #include "kcodecs_debug.h" #include #include #include #include #include #include #include #include #include #if defined(Q_OS_WIN) #define strncasecmp _strnicmp #endif namespace KCodecs { static QList charsetCache; QByteArray cachedCharset(const QByteArray &name) { for (const QByteArray &charset : qAsConst(charsetCache)) { if (qstricmp(name.data(), charset.data()) == 0) { return charset; } } charsetCache.append(name.toUpper()); return charsetCache.last(); } } // namespace KCodecs /******************************** KCodecs ********************************/ QByteArray KCodecs::quotedPrintableEncode(const QByteArray &in, bool useCRLF) { Codec *codec = Codec::codecForName("quoted-printable"); return codec->encode(in, useCRLF ? Codec::NewlineCRLF : Codec::NewlineLF); } void KCodecs::quotedPrintableEncode(const QByteArray &in, QByteArray &out, bool useCRLF) { out = quotedPrintableEncode(in, useCRLF ? Codec::NewlineCRLF : Codec::NewlineLF); } QByteArray KCodecs::quotedPrintableDecode(const QByteArray &in) { Codec *codec = Codec::codecForName("quoted-printable"); return codec->decode(in); } void KCodecs::quotedPrintableDecode(const QByteArray &in, QByteArray &out) { out = quotedPrintableDecode(in); } QByteArray KCodecs::base64Encode(const QByteArray &in) { Codec *codec = Codec::codecForName("base64"); return codec->encode(in); } #if KCODECS_BUILD_DEPRECATED_SINCE(5, 5) QByteArray KCodecs::base64Encode(const QByteArray &in, bool insertLFs) { Q_UNUSED(insertLFs); return base64Encode(in); } #endif void KCodecs::base64Encode(const QByteArray &in, QByteArray &out, bool insertLFs) { Q_UNUSED(insertLFs); out = base64Encode(in); } QByteArray KCodecs::base64Decode(const QByteArray &in) { Codec *codec = Codec::codecForName("base64"); return codec->decode(in); } void KCodecs::base64Decode(const QByteArray &in, QByteArray &out) { out = base64Decode(in); } #if KCODECS_BUILD_DEPRECATED_SINCE(5, 56) QByteArray KCodecs::uuencode(const QByteArray &in) { Codec *codec = Codec::codecForName("x-uuencode"); return codec->encode(in); } #endif #if KCODECS_BUILD_DEPRECATED_SINCE(5, 56) void KCodecs::uuencode(const QByteArray &in, QByteArray &out) { out = uuencode(in); } #endif QByteArray KCodecs::uudecode(const QByteArray &in) { Codec *codec = Codec::codecForName("x-uuencode"); return codec->decode(in); } void KCodecs::uudecode(const QByteArray &in, QByteArray &out) { out = uudecode(in); } //@cond PRIVATE namespace KCodecs { // parse the encoded-word (scursor points to after the initial '=') bool parseEncodedWord(const char *&scursor, const char *const send, QString *result, QByteArray *language, QByteArray *usedCS, const QByteArray &defaultCS, CharsetOption charsetOption) { assert(result); assert(language); // make sure the caller already did a bit of the work. assert(*(scursor - 1) == '='); // // STEP 1: // scan for the charset/language portion of the encoded-word // char ch = *scursor++; if (ch != '?') { // qCDebug(KCODECS_LOG) << "first"; // qCDebug(KCODECS_LOG) << "Premature end of encoded word"; return false; } // remember start of charset (ie. just after the initial "=?") and // language (just after the first '*') fields: const char *charsetStart = scursor; const char *languageStart = nullptr; // find delimiting '?' (and the '*' separating charset and language // tags, if any): for (; scursor != send ; scursor++) { if (*scursor == '?') { break; } else if (*scursor == '*' && languageStart == nullptr) { languageStart = scursor + 1; } } // not found? can't be an encoded-word! if (scursor == send || *scursor != '?') { // qCDebug(KCODECS_LOG) << "second"; // qCDebug(KCODECS_LOG) << "Premature end of encoded word"; return false; } // extract the language information, if any (if languageStart is 0, // language will be null, too): QByteArray maybeLanguage(languageStart, scursor - languageStart); // extract charset information (keep in mind: the size given to the // ctor is one off due to the \0 terminator): QByteArray maybeCharset(charsetStart, (languageStart ? languageStart - 1 : scursor) - charsetStart); // // STEP 2: // scan for the encoding portion of the encoded-word // // remember start of encoding (just _after_ the second '?'): scursor++; const char *encodingStart = scursor; // find next '?' (ending the encoding tag): for (; scursor != send ; scursor++) { if (*scursor == '?') { break; } } // not found? Can't be an encoded-word! if (scursor == send || *scursor != '?') { // qCDebug(KCODECS_LOG) << "third"; // qCDebug(KCODECS_LOG) << "Premature end of encoded word"; return false; } // extract the encoding information: QByteArray maybeEncoding(encodingStart, scursor - encodingStart); // qCDebug(KCODECS_LOG) << "parseEncodedWord: found charset == \"" << maybeCharset // << "\"; language == \"" << maybeLanguage // << "\"; encoding == \"" << maybeEncoding << "\""; // // STEP 3: // scan for encoded-text portion of encoded-word // // remember start of encoded-text (just after the third '?'): scursor++; const char *encodedTextStart = scursor; // find the '?=' sequence (ending the encoded-text): for (; scursor != send ; scursor++) { if (*scursor == '?') { if (scursor + 1 != send) { if (*(scursor + 1) != '=') { // We expect a '=' after the '?', but we got something else; ignore // qCDebug(KCODECS_LOG) << "Stray '?' in q-encoded word, ignoring this."; continue; } else { // yep, found a '?=' sequence scursor += 2; break; } } else { // The '?' is the last char, but we need a '=' after it! // qCDebug(KCODECS_LOG) << "Premature end of encoded word"; return false; } } } if (*(scursor - 2) != '?' || *(scursor - 1) != '=' || scursor < encodedTextStart + 2) { // qCDebug(KCODECS_LOG) << "Premature end of encoded word"; return false; } // set end sentinel for encoded-text: const char *const encodedTextEnd = scursor - 2; // // STEP 4: // setup decoders for the transfer encoding and the charset // // try if there's a codec for the encoding found: Codec *codec = Codec::codecForName(maybeEncoding); if (!codec) { // qCDebug(KCODECS_LOG) << "Unknown encoding" << maybeEncoding; return false; } // get an instance of a corresponding decoder: Decoder *dec = codec->makeDecoder(); assert(dec); // try if there's a (text)codec for the charset found: bool matchOK = false; QByteArray cs; QTextCodec *textCodec = nullptr; if (charsetOption == KCodecs::ForceDefaultCharset || maybeCharset.isEmpty()) { textCodec = KCharsets::charsets()->codecForName(QLatin1String(defaultCS), matchOK); cs = cachedCharset(defaultCS); } else { textCodec = KCharsets::charsets()->codecForName(QLatin1String(maybeCharset), matchOK); if (!matchOK) { //no suitable codec found => use default charset textCodec = KCharsets::charsets()->codecForName(QLatin1String(defaultCS), matchOK); cs = cachedCharset(defaultCS); } else { cs = cachedCharset(maybeCharset); } } if (usedCS) { *usedCS = cs; } if (!matchOK || !textCodec) { // qCDebug(KCODECS_LOG) << "Unknown charset" << maybeCharset; delete dec; return false; }; // qCDebug(KCODECS_LOG) << "mimeName(): \"" << textCodec->name() << "\""; // allocate a temporary buffer to store the 8bit text: int encodedTextLength = encodedTextEnd - encodedTextStart; QByteArray buffer; buffer.resize(codec->maxDecodedSizeFor(encodedTextLength)); char *bbegin = buffer.data(); char *bend = bbegin + buffer.length(); // // STEP 5: // do the actual decoding // if (!dec->decode(encodedTextStart, encodedTextEnd, bbegin, bend)) { qWarning() << codec->name() << "codec lies about its maxDecodedSizeFor(" << encodedTextLength << ")\nresult may be truncated"; } *result = textCodec->toUnicode(buffer.data(), bbegin - buffer.data()); // qCDebug(KCODECS_LOG) << "result now: \"" << result << "\""; // cleanup: delete dec; *language = maybeLanguage; return true; } } // namespace KCodecs //@endcond QString KCodecs::decodeRFC2047String(const QString &msg) { QByteArray usedCS; return decodeRFC2047String(msg.toUtf8(), &usedCS, "utf-8", NoOption); } QString KCodecs::decodeRFC2047String(const QByteArray &src, QByteArray *usedCS, const QByteArray &defaultCS, CharsetOption charsetOption) { QByteArray result; QByteArray spaceBuffer; const char *scursor = src.constData(); const char *send = scursor + src.length(); bool onlySpacesSinceLastWord = false; while (scursor != send) { // space if (isspace(*scursor) && onlySpacesSinceLastWord) { spaceBuffer += *scursor++; continue; } // possible start of an encoded word if (*scursor == '=') { QByteArray language; QString decoded; ++scursor; const char *start = scursor; if (parseEncodedWord(scursor, send, &decoded, &language, usedCS, defaultCS, charsetOption)) { result += decoded.toUtf8(); onlySpacesSinceLastWord = true; spaceBuffer.clear(); } else { if (onlySpacesSinceLastWord) { result += spaceBuffer; onlySpacesSinceLastWord = false; } result += '='; scursor = start; // reset cursor after parsing failure } continue; } else { // unencoded data if (onlySpacesSinceLastWord) { result += spaceBuffer; onlySpacesSinceLastWord = false; } result += *scursor; ++scursor; } } // If there are any chars that couldn't be decoded in UTF-8, // fallback to local codec const QString tryUtf8 = QString::fromUtf8(result); if (tryUtf8.contains(0xFFFD)) { QTextCodec *codec = QTextCodec::codecForLocale(); return codec->toUnicode(result); } else { return tryUtf8; } } QByteArray KCodecs::encodeRFC2047String(const QString &src, const QByteArray &charset) { QByteArray result; int start = 0, end = 0; bool nonAscii = false, ok = true, useQEncoding = false; // fromLatin1() is safe here, codecForName() uses toLatin1() internally const QTextCodec *codec = KCharsets::charsets()->codecForName(QString::fromLatin1(charset), ok); QByteArray usedCS; if (!ok) { //no codec available => try local8Bit and hope the best ;-) codec = QTextCodec::codecForLocale(); usedCS = codec->name(); } else { Q_ASSERT(codec); if (charset.isEmpty()) { usedCS = codec->name(); } else { usedCS = charset; } } QTextCodec::ConverterState converterState(QTextCodec::IgnoreHeader); QByteArray encoded8Bit = codec->fromUnicode(src.constData(), src.length(), &converterState); if (converterState.invalidChars > 0) { usedCS = "utf-8"; codec = QTextCodec::codecForName(usedCS); encoded8Bit = codec->fromUnicode(src); } if (usedCS.contains("8859-")) { // use "B"-Encoding for non iso-8859-x charsets useQEncoding = true; } uint encoded8BitLength = encoded8Bit.length(); for (unsigned int i = 0; i < encoded8BitLength; i++) { if (encoded8Bit[i] == ' ') { // encoding starts at word boundaries start = i + 1; } // encode escape character, for japanese encodings... if (((signed char)encoded8Bit[i] < 0) || (encoded8Bit[i] == '\033')) { end = start; // non us-ascii char found, now we determine where to stop encoding nonAscii = true; break; } } if (nonAscii) { while ((end < encoded8Bit.length()) && (encoded8Bit[end] != ' ')) { // we encode complete words end++; } for (int x = end; x < encoded8Bit.length(); x++) { if (((signed char)encoded8Bit[x] < 0) || (encoded8Bit[x] == '\033')) { end = x; // we found another non-ascii word while ((end < encoded8Bit.length()) && (encoded8Bit[end] != ' ')) { // we encode complete words end++; } } } result = encoded8Bit.left(start) + "=?" + usedCS; if (useQEncoding) { result += "?Q?"; char c, hexcode;// "Q"-encoding implementation described in RFC 2047 for (int i = start; i < end; i++) { c = encoded8Bit[i]; if (c == ' ') { // make the result readable with not MIME-capable readers result += '_'; } else { if (((c >= 'a') && (c <= 'z')) || // paranoid mode, encode *all* special chars to avoid problems ((c >= 'A') && (c <= 'Z')) || // with "From" & "To" headers ((c >= '0') && (c <= '9'))) { result += c; } else { result += '='; // "stolen" from KMail ;-) hexcode = ((c & 0xF0) >> 4) + 48; if (hexcode >= 58) { hexcode += 7; } result += hexcode; hexcode = (c & 0x0F) + 48; if (hexcode >= 58) { hexcode += 7; } result += hexcode; } } } } else { result += "?B?" + encoded8Bit.mid(start, end - start).toBase64(); } result += "?="; result += encoded8Bit.right(encoded8Bit.length() - end); } else { result = encoded8Bit; } return result; } /******************************************************************************/ /* KCodecs::Codec */ // global list of KCodecs::Codec's //@cond PRIVATE namespace { static QHash *allCodecs = nullptr; Q_GLOBAL_STATIC(QMutex, dictLock) static void createCodecs() { //all->insert( "7bit", new KCodecs::SevenBitCodec() ); //all->insert( "8bit", new KCodecs::EightBitCodec() ); allCodecs->insert("base64", new KCodecs::Base64Codec()); allCodecs->insert("quoted-printable", new KCodecs::QuotedPrintableCodec()); allCodecs->insert("b", new KCodecs::Rfc2047BEncodingCodec()); allCodecs->insert("q", new KCodecs::Rfc2047QEncodingCodec()); allCodecs->insert("x-kmime-rfc2231", new KCodecs::Rfc2231EncodingCodec()); allCodecs->insert("x-uuencode", new KCodecs::UUCodec()); //all->insert( "binary", new KCodecs::BinaryCodec() ); } static void cleanupCodecs() { for (auto iter = allCodecs->begin(); iter != allCodecs->end(); ++iter) { delete (*iter); } delete allCodecs; allCodecs = nullptr; } } //@endcond KCodecs::Codec *KCodecs::Codec::codecForName(const char *name) { const QByteArray ba(name); return codecForName(ba); } KCodecs::Codec *KCodecs::Codec::codecForName(const QByteArray &name) { QMutexLocker locker(dictLock); // protect "allCodecs" if (!allCodecs) { allCodecs = new QHash(); qAddPostRoutine(cleanupCodecs); createCodecs(); } QByteArray lowerName = name.toLower(); Codec *codec = (*allCodecs).value(lowerName); if (!codec) { qWarning() << "Unknown codec \"" << name << "\" requested!"; } return codec; } bool KCodecs::Codec::encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline) const { // get an encoder: QScopedPointer enc(makeEncoder(newline)); if (enc.isNull()) { qWarning() << "makeEncoder failed for" << name(); return false; } // encode and check for output buffer overflow: while (!enc->encode(scursor, send, dcursor, dend)) { if (dcursor == dend) { return false; // not enough space in output buffer } } // finish and check for output buffer overflow: while (!enc->finish(dcursor, dend)) { if (dcursor == dend) { return false; // not enough space in output buffer } } return true; // successfully encoded. } QByteArray KCodecs::Codec::encode(const QByteArray &src, NewlineType newline) const { // allocate buffer for the worst case: QByteArray result; result.resize(maxEncodedSizeFor(src.size(), newline)); // set up iterators: QByteArray::ConstIterator iit = src.begin(); QByteArray::ConstIterator iend = src.end(); QByteArray::Iterator oit = result.begin(); QByteArray::ConstIterator oend = result.end(); // encode if (!encode(iit, iend, oit, oend, newline)) { qCritical() << name() << "codec lies about it's mEncodedSizeFor()"; } // shrink result to actual size: result.truncate(oit - result.begin()); return result; } QByteArray KCodecs::Codec::decode(const QByteArray &src, NewlineType newline) const { // allocate buffer for the worst case: QByteArray result; result.resize(maxDecodedSizeFor(src.size(), newline)); // set up iterators: QByteArray::ConstIterator iit = src.begin(); QByteArray::ConstIterator iend = src.end(); QByteArray::Iterator oit = result.begin(); QByteArray::ConstIterator oend = result.end(); // decode if (!decode(iit, iend, oit, oend, newline)) { qCritical() << name() << "codec lies about it's maxDecodedSizeFor()"; } // shrink result to actual size: result.truncate(oit - result.begin()); return result; } bool KCodecs::Codec::decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline) const { // get a decoder: QScopedPointer dec(makeDecoder(newline)); assert(!dec.isNull()); // decode and check for output buffer overflow: while (!dec->decode(scursor, send, dcursor, dend)) { if (dcursor == dend) { return false; // not enough space in output buffer } } // finish and check for output buffer overflow: while (!dec->finish(dcursor, dend)) { if (dcursor == dend) { return false; // not enough space in output buffer } } return true; // successfully encoded. } /******************************************************************************/ /* KCodecs::Encoder */ KCodecs::EncoderPrivate::EncoderPrivate(Codec::NewlineType newline) : outputBufferCursor(0) , newline(newline) { } KCodecs::Encoder::Encoder(Codec::NewlineType newline) : d(new KCodecs::EncoderPrivate(newline)) { } KCodecs::Encoder::~Encoder() { delete d; } bool KCodecs::Encoder::write(char ch, char*& dcursor, const char*const dend) { if (dcursor != dend) { // if there's space in the output stream, write there: *dcursor++ = ch; return true; } else { // else buffer the output: if (d->outputBufferCursor >= maxBufferedChars) { qCritical() << "KCodecs::Encoder: internal buffer overflow!"; } else { d->outputBuffer[ d->outputBufferCursor++ ] = ch; } return false; } } // write as much as possible off the output buffer. Return true if // flushing was complete, false if some chars could not be flushed. bool KCodecs::Encoder::flushOutputBuffer(char *&dcursor, const char *const dend) { int i; // copy output buffer to output stream: for (i = 0 ; dcursor != dend && i < d->outputBufferCursor ; ++i) { *dcursor++ = d->outputBuffer[i]; } // calculate the number of missing chars: int numCharsLeft = d->outputBufferCursor - i; // push the remaining chars to the begin of the buffer: if (numCharsLeft) { ::memmove(d->outputBuffer, d->outputBuffer + i, numCharsLeft); } // adjust cursor: d->outputBufferCursor = numCharsLeft; return !numCharsLeft; } bool KCodecs::Encoder::writeCRLF(char*& dcursor, const char*const dend) { if (d->newline == Codec::NewlineCRLF) { write('\r', dcursor, dend); } return write('\n', dcursor, dend); } /******************************************************************************/ /* KCodecs::Decoder */ KCodecs::DecoderPrivate::DecoderPrivate(Codec::NewlineType newline) : newline(newline) { } KCodecs::Decoder::Decoder(Codec::NewlineType newline) : d(new KCodecs::DecoderPrivate(newline)) { } KCodecs::Decoder::~Decoder() { delete d; } diff --git a/src/kcodecs.h b/src/kcodecs.h index 4fe4ef9..a5606dd 100644 --- a/src/kcodecs.h +++ b/src/kcodecs.h @@ -1,790 +1,779 @@ /* - Copyright (C) 2000-2001 Dawit Alemayehu - Copyright (C) 2001 Rik Hemsley (rikkus) - Copyright (c) 2001-2002 Marc Mutz + SPDX-FileCopyrightText: 2000-2001 Dawit Alemayehu + SPDX-FileCopyrightText: 2001 Rik Hemsley (rikkus) + SPDX-FileCopyrightText: 2001-2002 Marc Mutz - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License (LGPL) - version 2 as published by the Free Software Foundation. + SPDX-License-Identifier: LGPL-2.0-only - 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - The quoted-printable codec as described in RFC 2045, section 6.7. is by - Rik Hemsley (C) 2001. + The quoted-printable codec as described in RFC 2045, section 6.7. is by + Rik Hemsley (C) 2001. */ #ifndef KCODECS_H #define KCODECS_H #define KBase64 KCodecs #include #include template class QHash; class QByteArray; class QIODevice; /** * A wrapper class for the most commonly used encoding and * decoding algorithms. Currently there is support for encoding * and decoding input using base64, uu and the quoted-printable * specifications. * * \b Usage: * * \code * QByteArray input = "Aladdin:open sesame"; * QByteArray result = KCodecs::base64Encode(input); * cout << "Result: " << result.data() << endl; * \endcode * *
  * Output should be
  * Result: QWxhZGRpbjpvcGVuIHNlc2FtZQ==
  * 
* * The above example makes use of the convenience functions * (ones that accept/return null-terminated strings) to encode/decode * a string. If what you need is to encode or decode binary data, then * it is highly recommended that you use the functions that take an input * and output QByteArray as arguments. These functions are specifically * tailored for encoding and decoding binary data. * * @short A collection of commonly used encoding and decoding algorithms. * @author Dawit Alemayehu * @author Rik Hemsley */ namespace KCodecs { /** * Encodes the given data using the quoted-printable algorithm. * * @param in data to be encoded. * @param useCRLF if true the input data is expected to have * CRLF line breaks and the output will have CRLF line * breaks, too. * @return quoted-printable encoded string. */ KCODECS_EXPORT QByteArray quotedPrintableEncode(const QByteArray &in, bool useCRLF = true); /** * Encodes the given data using the quoted-printable algorithm. * * Use this function if you want the result of the encoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is also the preferred method for encoding binary data. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be encoded. * @param out encoded data. * @param useCRLF if true the input data is expected to have * CRLF line breaks and the output will have CRLF line * breaks, too. */ KCODECS_EXPORT void quotedPrintableEncode(const QByteArray &in, QByteArray &out, bool useCRLF); /** * Decodes a quoted-printable encoded data. * * Accepts data with CRLF or standard unix line breaks. * * @param in data to be decoded. * @return decoded string. * @since 5.5 */ KCODECS_EXPORT QByteArray quotedPrintableDecode(const QByteArray &in); /** * Decodes a quoted-printable encoded data. * * Accepts data with CRLF or standard unix line breaks. * Use this function if you want the result of the decoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is also the preferred method for decoding an encoded * binary data. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be decoded. * @param out decoded data. */ KCODECS_EXPORT void quotedPrintableDecode(const QByteArray &in, QByteArray &out); #if KCODECS_ENABLE_DEPRECATED_SINCE(5, 56) /** * Encodes the given data using the uuencode algorithm. * * The output is split into lines starting with the number of * encoded octets in the line and ending with a newline. No * line is longer than 45 octets (60 characters), excluding the * line terminator. * * @param in data to be uuencoded * @return uuencoded string. * @deprecated Not implemented, always returns an empty bytearray. */ KCODECS_DEPRECATED_VERSION(5, 56, "Not implemented") KCODECS_EXPORT QByteArray uuencode(const QByteArray &in); #endif #if KCODECS_ENABLE_DEPRECATED_SINCE(5, 56) /** * Encodes the given data using the uuencode algorithm. * * Use this function if you want the result of the encoding * to be placed in another array and cut down the number of * copy operation that have to be performed in the process. * This is the preffered method for encoding binary data. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be uuencoded. * @param out an empty byte array * @deprecated Not implemented, always set @p out to an empty bytearray. */ KCODECS_DEPRECATED_VERSION(5, 56, "Not implemented") KCODECS_EXPORT void uuencode(const QByteArray &in, QByteArray &out); #endif /** * Decodes the given data using the uudecode algorithm. * * Any 'begin' and 'end' lines like those generated by * the utilities in unix and unix-like OS will be * automatically ignored. * * @param in data to be decoded. * @return decoded string. */ KCODECS_EXPORT QByteArray uudecode(const QByteArray &in); /** * Decodes the given data using the uudecode algorithm. * * Use this function if you want the result of the decoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is the preferred method for decoding binary data. * * Any 'begin' and 'end' lines like those generated by * the utilities in unix and unix-like OS will be * automatically ignored. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be decoded. * @param out uudecoded data. */ KCODECS_EXPORT void uudecode(const QByteArray &in, QByteArray &out); /** * Encodes the given data using the base64 algorithm. * * The boolean argument determines if the encoded data is * going to be restricted to 76 characters or less per line * as specified by RFC 2045. If @p insertLFs is true, then * there will be 76 characters or less per line. * * @param in data to be encoded. * @param insertLFs limit the number of characters per line. * * @return base64 encoded string. * @since 5.5 */ KCODECS_EXPORT QByteArray base64Encode(const QByteArray &in); #if KCODECS_ENABLE_DEPRECATED_SINCE(5, 5) /** * @copydoc * KCodecs::base64Encode(QByteArray) * @deprecated Since 5.5, use KCodecs::base64Encode(QByteArray) instead. */ KCODECS_DEPRECATED_VERSION(5, 5, "Use QByteArray base64Encode(const QByteArray &)") KCODECS_EXPORT QByteArray base64Encode(const QByteArray &in, bool insertLFs); #endif /** * Encodes the given data using the base64 algorithm. * * Use this function if you want the result of the encoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is also the preferred method for encoding binary data. * * The boolean argument determines if the encoded data is going * to be restricted to 76 characters or less per line as specified * by RFC 2045. If @p insertLFs is true, then there will be 76 * characters or less per line. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be encoded. * @param out encoded data. * @param insertLFs limit the number of characters per line. */ KCODECS_EXPORT void base64Encode(const QByteArray &in, QByteArray &out, bool insertLFs = false); /** * Decodes the given data that was encoded using the * base64 algorithm. * * @param in data to be decoded. * @return decoded string. */ KCODECS_EXPORT QByteArray base64Decode(const QByteArray &in); /** * Decodes the given data that was encoded with the base64 * algorithm. * * Use this function if you want the result of the decoding * to be placed in another array which cuts down the number * of copy operation that have to be performed in the process. * This is also the preferred method for decoding an encoded * binary data. * * NOTE: the output array is first reset and then resized * appropriately before use, hence, all data stored in the * output array will be lost. * * @param in data to be decoded. * @param out decoded data. */ KCODECS_EXPORT void base64Decode(const QByteArray &in, QByteArray &out); /** * Decodes string @p text according to RFC2047, * i.e., the construct =?charset?[qb]?encoded?= * * @param text source string * @returns the decoded string */ KCODECS_EXPORT QString decodeRFC2047String(const QString &text); /** * Charset options for RFC2047 encoder * @since 5.5 */ enum CharsetOption { NoOption = 0, /// No special option ForceDefaultCharset = 1 /// Force use of the default charset }; /** * Decodes string @p src according to RFC2047, i.e. the construct * =?charset?[qb]?encoded?= * * @param src source string. * @param usedCS the detected charset is returned here * @param defaultCS the charset to use in case the detected * one isn't known to us. * @param option options for the encoder * * @return the decoded string. * @since 5.5 */ KCODECS_EXPORT QString decodeRFC2047String(const QByteArray &src, QByteArray *usedCS, const QByteArray &defaultCS = QByteArray(), CharsetOption option = NoOption); /** * Encodes string @p src according to RFC2047 using charset @p charset. * * This function also makes commas, quotes and other characters part of the encoded name, for example * the string "Jöhn Döe" would be encoded as , * i.e. the opening and closing quote mark would be part of the encoded word. * Therefore don't use this function for input strings that contain semantically meaningful characters, * like the quoting marks in this example. * * @param src source string. * @param charset charset to use. If it can't encode the string, UTF-8 will be used instead. * @return the encoded string. * @since 5.5 */ KCODECS_EXPORT QByteArray encodeRFC2047String(const QString &src, const QByteArray &charset); class Encoder; class EncoderPrivate; class Decoder; class DecoderPrivate; /** @class KCodecs::Codec kcodecs.h KCodecs @glossary @anchor MIME @anchor mime @b MIME: Multipurpose Internet Mail Extensions or @acronym MIME is an Internet Standard that extends the format of e-mail to support text in character sets other than US-ASCII, non-text attachments, multi-part message bodies, and header information in non-ASCII character sets. Virtually all human-written Internet e-mail and a fairly large proportion of automated e-mail is transmitted via @acronym SMTP in MIME format. Internet e-mail is so closely associated with the SMTP and MIME standards that it is sometimes called SMTP/MIME e-mail. The content types defined by MIME standards are also of growing importance outside of e-mail, such as in communication protocols like @acronym HTTP for the World Wide Web. MIME is also a fundamental component of communication protocols such as HTTP, which requires that data be transmitted in the context of e-mail-like messages, even though the data may not actually be e-mail. @glossary @anchor codec @anchor codecs @anchor Codec @anchor Codecs @b codec: a program capable of performing encoding and decoding on a digital data stream. Codecs encode data for storage or encryption and decode it for viewing or editing. @glossary @anchor CRLF @b CRLF: a "Carriage Return (0x0D)" followed by a "Line Feed (0x0A)", two ASCII control characters used to represent a newline on some operating systems, notably DOS and Microsoft Windows. @glossary @anchor LF @b LF: a "Line Feed (0x0A)" ASCII control character used to represent a newline on some operating systems, notably Unix, Unix-like, and Linux. @brief An abstract base class of @ref codecs for common mail transfer encodings. Provides an abstract base class of @ref codecs like base64 and quoted-printable. Implemented as a singleton. @authors Marc Mutz \ @since 5.5 */ class KCODECS_EXPORT Codec { public: enum NewlineType { NewlineLF, NewlineCRLF }; /** Returns a codec associated with the specified @p name. @param name points to a character string containing a valid codec name. */ static Codec *codecForName(const char *name); /** Returns a codec associated with the specified @p name. @param name is a QByteArray containing a valid codec name. */ static Codec *codecForName(const QByteArray &name); /** Computes the maximum size, in characters, needed for the encoding. @param insize is the number of input characters to be encoded. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). @return the maximum number of characters in the encoding. */ virtual int maxEncodedSizeFor(int insize, NewlineType newline = NewlineLF) const = 0; /** Computes the maximum size, in characters, needed for the deccoding. @param insize is the number of input characters to be decoded. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). @return the maximum number of characters in the decoding. */ virtual int maxDecodedSizeFor(int insize, NewlineType newline = NewlineLF) const = 0; /** Creates the encoder for the codec. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). @return a pointer to an instance of the codec's encoder. */ virtual Encoder *makeEncoder(NewlineType newline = NewlineLF) const = 0; /** Creates the decoder for the codec. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). @return a pointer to an instance of the codec's decoder. */ virtual Decoder *makeDecoder(NewlineType newline = NewlineLF) const = 0; /** Convenience wrapper that can be used for small chunks of data when you can provide a large enough buffer. The default implementation creates an Encoder and uses it. Encodes a chunk of bytes starting at @p scursor and extending to @p send into the buffer described by @p dcursor and @p dend. This function doesn't support chaining of blocks. The returned block cannot be added to, but you don't need to finalize it, too. Example usage (@p in contains the input data):
       KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
       if (!codec) {
           qFatal() << "no base64 codec found!?";
       }
       QByteArray out(in.size() * 1.4); // crude maximal size of b64 encoding
       QByteArray::Iterator iit = in.begin();
       QByteArray::Iterator oit = out.begin();
       if (!codec->encode(iit, in.end(), oit, out.end())) {
           qDebug() << "output buffer too small";
           return;
       }
       qDebug() << "Size of encoded data:" << oit - out.begin();
       
@param scursor is a pointer to the start of the input buffer. @param send is a pointer to the end of the input buffer. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). @return false if the encoded data didn't fit into the output buffer; true otherwise. */ virtual bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline = NewlineLF) const; /** Convenience wrapper that can be used for small chunks of data when you can provide a large enough buffer. The default implementation creates a Decoder and uses it. Decodes a chunk of bytes starting at @p scursor and extending to @p send into the buffer described by @p dcursor and @p dend. This function doesn't support chaining of blocks. The returned block cannot be added to, but you don't need to finalize it, too. Example usage (@p in contains the input data):
       KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
       if (!codec) {
           qFatal() << "no base64 codec found!?";
       }
       QByteArray out(in.size()); // good guess for any encoding...
       QByteArray::Iterator iit = in.begin();
       QByteArray::Iterator oit = out.begin();
       if (!codec->decode(iit, in.end(), oit, out.end())) {
           qDebug() << "output buffer too small";
           return;
       }
       qDebug() << "Size of decoded data:" << oit - out.begin();
       
@param scursor is a pointer to the start of the input buffer. @param send is a pointer to the end of the input buffer. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). @return false if the decoded data didn't fit into the output buffer; true otherwise. */ virtual bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend, NewlineType newline = NewlineLF) const; /** Even more convenient, but also a bit slower and more memory intensive, since it allocates storage for the worst case and then shrinks the result QByteArray to the actual size again. For use with small @p src. @param src is a QByteArray containing the data to encode. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). */ virtual QByteArray encode(const QByteArray &src, NewlineType newline = NewlineLF) const; /** Even more convenient, but also a bit slower and more memory intensive, since it allocates storage for the worst case and then shrinks the result QByteArray to the actual size again. For use with small @p src. @param src is a QByteArray containing the data to decode. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). */ virtual QByteArray decode(const QByteArray &src, NewlineType newline = NewlineLF) const; /** Returns the name of the encoding. Guaranteed to be lowercase. */ virtual const char *name() const = 0; /** Destroys the codec. */ virtual ~Codec() {} protected: /** Constructs the codec. */ Codec() {} }; /** @class KCodecs::Decoder kcodecs.h KCodecs @brief Stateful CTE decoder class Stateful decoder class, modelled after QTextDecoder. @section Overview KCodecs decoders are designed to be able to process encoded data in chunks of arbitrary size and to work with output buffers of also arbitrary size. They maintain any state necessary to go on where the previous call left off. The class consists of only two methods of interest: see decode, which decodes an input block and finalize, which flushes any remaining data to the output stream. Typically, you will create a decoder instance, call decode as often as necessary, then call finalize (most often a single call suffices, but it might be that during that call the output buffer is filled, so you should be prepared to call finalize as often as necessary, ie. until it returns @p true). @section Return Values Both methods return @p true to indicate that they've finished their job. For decode, a return value of @p true means that the current input block has been finished (@p false most often means that the output buffer is full, but that isn't required behavior. The decode call is free to return at arbitrary times during processing). For finalize, a return value of @p true means that all data implicitly or explicitly stored in the decoder instance has been flushed to the output buffer. A @p false return value should be interpreted as "check if the output buffer is full and call me again", just as with decode. @section Usage Pattern Since the decoder maintains state, you can only use it once. After a sequence of input blocks has been processed, you finalize the output and then delete the decoder instance. If you want to process another input block sequence, you create a new instance. Typical usage (@p in contains the (base64-encoded) input data), taking into account all the conventions detailed above:
   KCodecs::Codec *codec = KCodecs::Codec::codecForName("base64");
   if (!codec) {
       qFatal() << "No codec found for base64!";
   }
   KCodecs::Decoder *dec = codec->makeDecoder();
   Q_ASSERT(dec); // should not happen
   QByteArray out(256); // small buffer is enough ;-)
   QByteArray::Iterator iit = in.begin();
   QByteArray::Iterator oit = out.begin();
   // decode the chunk
   while (!dec->decode(iit, in.end(), oit, out.end()))
     if (oit == out.end()) { // output buffer full, process contents
       do_something_with(out);
       oit = out.begin();
     }
   // repeat while loop for each input block
   // ...
   // finish (flush remaining data from decoder):
   while (!dec->finish(oit, out.end()))
     if (oit == out.end()) { // output buffer full, process contents
       do_something_with(out);
       oit = out.begin();
     }
   // now process last chunk:
   out.resize(oit - out.begin());
   do_something_with(out);
   // _delete_ the decoder, but not the codec:
   delete dec;
   
@since 5.5 */ class KCODECS_EXPORT Decoder { protected: friend class Codec; friend class DecoderPrivate; /** Protected constructor. Use KCodecs::Codec::makeDecoder to create an instance. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). */ Decoder(Codec::NewlineType newline = Codec::NewlineLF); public: /** Destroys the decoder. */ virtual ~Decoder(); /** Decodes a chunk of data, maintaining state information between calls. See class decumentation for calling conventions. @param scursor is a pointer to the start of the input buffer. @param send is a pointer to the end of the input buffer. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. */ virtual bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) = 0; /** Call this method to finalize the output stream. Writes all remaining data and resets the decoder. See KCodecs::Codec for calling conventions. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. */ virtual bool finish(char *&dcursor, const char *const dend) = 0; protected: //@cond PRIVATE DecoderPrivate * const d; //@endcond }; /** @class KCodecs::Encoder kcodecs.h KCodecs @brief Stateful encoder class. Stateful encoder class, modeled after QTextEncoder. @since 5.5 */ class KCODECS_EXPORT Encoder { protected: friend class Codec; friend class EncoderPrivate; /** Protected constructor. Use KCodecs::Codec::makeEncoder if you want one. @param newline whether make new lines using @ref CRLF, or @ref LF (default is @ref LF). */ explicit Encoder(Codec::NewlineType newline = Codec::NewlineLF); public: /** Destroys the encoder. */ virtual ~Encoder(); /** Encodes a chunk of data, maintaining state information between calls. See KCodecs::Codec for calling conventions. @param scursor is a pointer to the start of the input buffer. @param send is a pointer to the end of the input buffer. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. */ virtual bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) = 0; /** Call this method to finalize the output stream. Writes all remaining data and resets the encoder. See KCodecs::Codec for calling conventions. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. */ virtual bool finish(char *&dcursor, const char *const dend) = 0; protected: /** The maximum number of characters permitted in the output buffer. */ enum { maxBufferedChars = 8 /**< Eight */ }; /** Writes character @p ch to the output stream or the output buffer, depending on whether or not the output stream has space left. @param ch is the character to write. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. @return true if written to the output stream; else false if buffered. */ bool write(char ch, char *&dcursor, const char *const dend); /** Writes characters from the output buffer to the output stream. Implementations of encode and finish should call this at the very beginning and for each iteration of the while loop. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. @return true if all chars could be written, false otherwise */ bool flushOutputBuffer(char *&dcursor, const char *const dend); /** Convenience function. Outputs @ref LF or @ref CRLF, based on the state of mWithCRLF. @param dcursor is a pointer to the start of the output buffer. @param dend is a pointer to the end of the output buffer. */ bool writeCRLF(char *&dcursor, const char *const dend); protected: //@cond PRIVATE EncoderPrivate * const d; //@endcond }; } // namespace KCodecs #endif // KCODECS_H diff --git a/src/kcodecs_p.h b/src/kcodecs_p.h index 81294cc..8f04fdc 100644 --- a/src/kcodecs_p.h +++ b/src/kcodecs_p.h @@ -1,52 +1,41 @@ /* - Copyright (C) 2014 Daniel Vrátil + SPDX-FileCopyrightText: 2014 Daniel Vrátil - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License (LGPL) - version 2 as published by the Free Software Foundation. - - 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + SPDX-License-Identifier: LGPL-2.0-only */ #ifndef KCODECS_P_H #define KCODECS_P_H #include "kcodecs.h" namespace KCodecs { class EncoderPrivate { public: EncoderPrivate(Codec::NewlineType newline); /** An output buffer to simplify some codecs. Used with write() and flushOutputBuffer(). */ char outputBuffer[ Encoder::maxBufferedChars ]; uchar outputBufferCursor; const Codec::NewlineType newline; }; class DecoderPrivate { public: DecoderPrivate(Codec::NewlineType newline); const Codec::NewlineType newline; }; } #endif // KCODECS_P_H diff --git a/src/kcodecsbase64.cpp b/src/kcodecsbase64.cpp index edb8546..dc0d7ab 100644 --- a/src/kcodecsbase64.cpp +++ b/src/kcodecsbase64.cpp @@ -1,433 +1,420 @@ /* -*- c++ -*- - Copyright (c) 2001 Marc Mutz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2001 Marc Mutz + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file is part of the API for handling @ref MIME data and defines the @ref Base64 and @ref RFC2047B @ref Codec classes. @brief Defines the Base64Codec and Rfc2047BEncodingCodec classes. @authors Marc Mutz \ */ #include "kcodecsbase64.h" #include "kcodecs_p.h" #include #include using namespace KCodecs; namespace KCodecs { // codec for base64 as specified in RFC 2045 //class Base64Codec; //class Base64Decoder; //class Base64Encoder; // codec for the B encoding as specified in RFC 2047 //class Rfc2047BEncodingCodec; //class Rfc2047BEncodingEncoder; //class Rfc2047BEncodingDecoder; //@cond PRIVATE static const uchar base64DecodeMap[128] = { 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64 }; static const char base64EncodeMap[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; //@endcond class Base64Decoder : public Decoder { uint mStepNo; uchar mOutbits; bool mSawPadding : 1; protected: friend class Base64Codec; Base64Decoder(Codec::NewlineType newline = Codec::NewlineLF) : Decoder(newline) , mStepNo(0) , mOutbits(0) , mSawPadding(false) { } public: virtual ~Base64Decoder() {} bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override; // ### really needs no finishing??? bool finish(char *&dcursor, const char *const dend) override { Q_UNUSED(dcursor); Q_UNUSED(dend); return true; } }; class Base64Encoder : public Encoder { uint mStepNo; /** number of already written base64-quartets on current line */ uint mWrittenPacketsOnThisLine; uchar mNextbits; bool mInsideFinishing : 1; protected: friend class Rfc2047BEncodingCodec; friend class Rfc2047BEncodingEncoder; friend class Base64Codec; Base64Encoder(Codec::NewlineType newline = Codec::NewlineLF) : Encoder(newline) , mStepNo(0) , mWrittenPacketsOnThisLine(0) , mNextbits(0) , mInsideFinishing(false) { } bool generic_finish(char *&dcursor, const char *const dend, bool withLFatEnd); public: virtual ~Base64Encoder() {} bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override; bool finish(char *&dcursor, const char *const dend) override; protected: bool writeBase64(uchar ch, char *&dcursor, const char *const dend) { return write(base64EncodeMap[ ch ], dcursor, dend); } }; class Rfc2047BEncodingEncoder : public Base64Encoder { protected: friend class Rfc2047BEncodingCodec; Rfc2047BEncodingEncoder(Codec::NewlineType newline = Codec::NewlineLF) : Base64Encoder(newline) { } public: bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override; bool finish(char *&dcursor, const char *const dend) override; }; Encoder *Base64Codec::makeEncoder(Codec::NewlineType newline) const { return new Base64Encoder(newline); } Decoder *Base64Codec::makeDecoder(Codec::NewlineType newline) const { return new Base64Decoder(newline); } Encoder *Rfc2047BEncodingCodec::makeEncoder(Codec::NewlineType newline) const { return new Rfc2047BEncodingEncoder(newline); } /********************************************************/ /********************************************************/ /********************************************************/ bool Base64Decoder::decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) { while (dcursor != dend && scursor != send) { uchar ch = *scursor++; uchar value; // try converting ch to a 6-bit value: if (ch < 128) { value = base64DecodeMap[ ch ]; } else { value = 64; } // ch isn't of the base64 alphabet, check for other significant chars: if (value >= 64) { if (ch == '=') { // padding: if (mStepNo == 0 || mStepNo == 1) { if (!mSawPadding) { // malformed //qWarning() << "Base64Decoder: unexpected padding" // "character in input stream"; } mSawPadding = true; break; } else if (mStepNo == 2) { // ok, there should be another one } else if (mStepNo == 3) { // ok, end of encoded stream mSawPadding = true; break; } mSawPadding = true; mStepNo = (mStepNo + 1) % 4; continue; } else { // non-base64 alphabet continue; } } if (mSawPadding) { //qWarning() << "Base64Decoder: Embedded padding character" // "encountered!"; return true; } // add the new bits to the output stream and flush full octets: switch (mStepNo) { case 0: mOutbits = value << 2; break; case 1: *dcursor++ = (char)(mOutbits | value >> 4); mOutbits = value << 4; break; case 2: *dcursor++ = (char)(mOutbits | value >> 2); mOutbits = value << 6; break; case 3: *dcursor++ = (char)(mOutbits | value); mOutbits = 0; break; default: assert(0); } mStepNo = (mStepNo + 1) % 4; } // return false when caller should call us again: return scursor == send; } // Base64Decoder::decode() bool Base64Encoder::encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) { const uint maxPacketsPerLine = 76 / 4; // detect when the caller doesn't adhere to our rules: if (mInsideFinishing) { return true; } while (scursor != send && dcursor != dend) { // properly empty the output buffer before starting something new: // ### fixme: we can optimize this away, since the buffer isn't // written to anyway (most of the time) if (d->outputBufferCursor && !flushOutputBuffer(dcursor, dend)) { return scursor == send; } uchar ch = *scursor++; // mNextbits // (part of) value of next sextet // check for line length; if (mStepNo == 0 && mWrittenPacketsOnThisLine >= maxPacketsPerLine) { writeCRLF(dcursor, dend); mWrittenPacketsOnThisLine = 0; } // depending on mStepNo, extract value and mNextbits from the // octet stream: switch (mStepNo) { case 0: assert(mNextbits == 0); writeBase64(ch >> 2, dcursor, dend); // top-most 6 bits -> output mNextbits = (ch & 0x3) << 4; // 0..1 bits -> 4..5 in mNextbits break; case 1: assert((mNextbits & ~0x30) == 0); writeBase64(mNextbits | ch >> 4, dcursor, dend); // 4..7 bits -> 0..3 in value mNextbits = (ch & 0xf) << 2; // 0..3 bits -> 2..5 in mNextbits break; case 2: assert((mNextbits & ~0x3C) == 0); writeBase64(mNextbits | ch >> 6, dcursor, dend); // 6..7 bits -> 0..1 in value writeBase64(ch & 0x3F, dcursor, dend); // 0..5 bits -> output mNextbits = 0; mWrittenPacketsOnThisLine++; break; default: assert(0); } mStepNo = (mStepNo + 1) % 3; } if (d->outputBufferCursor) { flushOutputBuffer(dcursor, dend); } return scursor == send; } bool Rfc2047BEncodingEncoder::encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) { // detect when the caller doesn't adhere to our rules: if (mInsideFinishing) { return true; } while (scursor != send && dcursor != dend) { // properly empty the output buffer before starting something new: // ### fixme: we can optimize this away, since the buffer isn't // written to anyway (most of the time) if (d->outputBufferCursor && !flushOutputBuffer(dcursor, dend)) { return scursor == send; } uchar ch = *scursor++; // mNextbits // (part of) value of next sextet // depending on mStepNo, extract value and mNextbits from the // octet stream: switch (mStepNo) { case 0: assert(mNextbits == 0); writeBase64(ch >> 2, dcursor, dend); // top-most 6 bits -> output mNextbits = (ch & 0x3) << 4; // 0..1 bits -> 4..5 in mNextbits break; case 1: assert((mNextbits & ~0x30) == 0); writeBase64(mNextbits | ch >> 4, dcursor, dend); // 4..7 bits -> 0..3 in value mNextbits = (ch & 0xf) << 2; // 0..3 bits -> 2..5 in mNextbits break; case 2: assert((mNextbits & ~0x3C) == 0); writeBase64(mNextbits | ch >> 6, dcursor, dend); // 6..7 bits -> 0..1 in value writeBase64(ch & 0x3F, dcursor, dend); // 0..5 bits -> output mNextbits = 0; break; default: assert(0); } mStepNo = (mStepNo + 1) % 3; } if (d->outputBufferCursor) { flushOutputBuffer(dcursor, dend); } return scursor == send; } bool Base64Encoder::finish(char *&dcursor, const char *const dend) { return generic_finish(dcursor, dend, true); } bool Rfc2047BEncodingEncoder::finish(char *&dcursor, const char *const dend) { return generic_finish(dcursor, dend, false); } bool Base64Encoder::generic_finish(char *&dcursor, const char *const dend, bool withLFatEnd) { if (mInsideFinishing) { return flushOutputBuffer(dcursor, dend); } if (d->outputBufferCursor && !flushOutputBuffer(dcursor, dend)) { return false; } mInsideFinishing = true; // // writing out the last mNextbits... // switch (mStepNo) { case 1: // 2 mNextbits waiting to be written. Needs two padding chars: case 2: // 4 or 6 mNextbits waiting to be written. Completes a block writeBase64(mNextbits, dcursor, dend); mNextbits = 0; break; case 0: // no padding, nothing to be written, except possibly the CRLF assert(mNextbits == 0); break; default: assert(0); } // // adding padding... // switch (mStepNo) { case 1: write('=', dcursor, dend); Q_FALLTHROUGH(); // fall through: case 2: write('=', dcursor, dend); Q_FALLTHROUGH(); // fall through: case 0: // completed an quartet - add CRLF if (withLFatEnd) { writeCRLF(dcursor, dend); } return flushOutputBuffer(dcursor, dend); default: assert(0); } return true; // asserts get compiled out } } // namespace KCodecs diff --git a/src/kcodecsbase64.h b/src/kcodecsbase64.h index d3acf83..f626912 100644 --- a/src/kcodecsbase64.h +++ b/src/kcodecsbase64.h @@ -1,196 +1,183 @@ /* -*- c++ -*- - Copyright (c) 2001-2002 Marc Mutz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2001-2002 Marc Mutz + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file is part of the API for handling @ref MIME data and defines the @ref Base64 and @ref RFC2047B @ref Codec classes. @brief Defines the Base64Codec and Rfc2047BEncodingCodec classes. @authors Marc Mutz \ @glossary @anchor Base64 @anchor base64 @b base64: a binary to text encoding scheme based on @ref RFC1421. @glossary @anchor RFC1421 @anchor rfc1421 @b RFC @b 1421: RFC that defines the Privacy Enhancement for Internet Electronic Mail: Part I: Message Encryption and Authentication Procedures. @glossary @anchor RFC2045 @anchor rfc2045 @b RFC @b 2045: RFC that defines the MIME Part One: Format of Internet Message Bodies. @glossary @anchor RFC2047 @anchor rfc2047 @b RFC @b 2047: RFC that defines the MIME Part Three: Message Header Extensions for Non-ASCII Text. @glossary @anchor RFC2047B @anchor rfc2047b @b RFC @b 2047B: Section 4.1 of @ref RFC2047. */ #ifndef KCODECS_BASE64_H #define KCODECS_BASE64_H #include "kcodecs.h" namespace KCodecs { /** @brief A class representing the @ref codec for @ref Base64 as specified in @ref RFC2045 */ class Base64Codec : public Codec { public: /** Constructs a Base64 codec. */ Base64Codec() : Codec() {} /** Destroys the codec. */ ~Base64Codec() override {} /** @copydoc Codec::name() */ const char *name() const override { return "base64"; } /** @copydoc Codec::maxEncodedSizeFor() */ int maxEncodedSizeFor(int insize, NewlineType newline) const override { // first, the total number of 4-char packets will be: int totalNumPackets = (insize + 2) / 3; // now, after every 76/4'th packet there needs to be a linebreak: int numLineBreaks = totalNumPackets / (76 / 4); // and at the very end, too: ++numLineBreaks; // putting it all together, we have: return 4 * totalNumPackets + (newline == Codec::NewlineCRLF ? 2 : 1) * numLineBreaks; } /** @copydoc Codec::maxDecodedSizeFor() */ int maxDecodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override { // assuming all characters are part of the base64 stream (which // does almost never hold due to required linebreaking; but // additional non-base64 chars don't affect the output size), each // 4-tupel of them becomes a 3-tupel in the decoded octet // stream. So: int result = ((insize + 3) / 4) * 3; // but all of them may be \n, so if (newline == Codec::NewlineCRLF) { result *= 2; // :-o } return result; } /** @copydoc Codec::makeEncoder() */ Encoder *makeEncoder(NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::makeDecoder() */ Decoder *makeDecoder(NewlineType newline = Codec::NewlineLF) const override; }; /** @brief A class representing the @ref codec for the B encoding as specified in @ref RFC2047B. */ class Rfc2047BEncodingCodec : public Base64Codec { public: /** Constructs a RFC2047B codec. */ Rfc2047BEncodingCodec() : Base64Codec() {} /** Destroys the codec. */ virtual ~Rfc2047BEncodingCodec() {} /** @copydoc Codec::name() */ const char *name() const override { return "b"; } /** @copydoc Codec::maxEncodedSizeFor() */ int maxEncodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override { Q_UNUSED(newline); // Each (begun) 3-octet triple becomes a 4 char quartet, so: return ((insize + 2) / 3) * 4; } /** @copydoc Codec::maxDecodedSizeFor() */ int maxDecodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override { Q_UNUSED(newline); // Each 4-char quartet becomes a 3-octet triple, the last one // possibly even less. So: return ((insize + 3) / 4) * 3; } /** @copydoc Codec::makeEncoder() */ Encoder *makeEncoder(NewlineType newline = Codec::NewlineLF) const override; }; } // namespace KCodecs #endif // KCODECS_BASE64_H diff --git a/src/kcodecsidentity.cpp b/src/kcodecsidentity.cpp index cf70fbb..6dfc85b 100644 --- a/src/kcodecsidentity.cpp +++ b/src/kcodecsidentity.cpp @@ -1,114 +1,101 @@ /* -*- c++ -*- - Copyright (c) 2004 Marc Mutz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2004 Marc Mutz + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file is part of the API for handling @ref MIME data and defines the Identity, @ref seven-bit-text, @ref eight-bit-text, and @ref eight-bit-binary @ref Codec classes. @brief Defines the classes IdentityCodec, SevenBitCodec, EightBitCodec, and BinaryCodec. @authors Marc Mutz \ */ #include "kcodecsidentity.h" #include #include #include using namespace KCodecs; class IdentityEnDecoder : public Encoder, public Decoder { protected: friend class KCodecs::IdentityCodec; IdentityEnDecoder(Codec::NewlineType newline) : Encoder(Codec::NewlineLF) { if (newline == Codec::NewlineCRLF) { qWarning() << "IdentityEnDecoder: CRLF isn't yet supported!"; } } public: ~IdentityEnDecoder() {} bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override { return decode(scursor, send, dcursor, dend); } bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override; bool finish(char *&dcursor, const char *const dend) override { Q_UNUSED(dcursor); Q_UNUSED(dend); return true; } }; Encoder *IdentityCodec::makeEncoder(Codec::NewlineType newline) const { return new IdentityEnDecoder(newline); } Decoder *IdentityCodec::makeDecoder(Codec::NewlineType newline) const { return new IdentityEnDecoder(newline); } /********************************************************/ /********************************************************/ /********************************************************/ bool IdentityEnDecoder::decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) { const int size = qMin(send - scursor, dcursor - dend); if (size > 0) { std::memmove(dcursor, scursor, size); dcursor += size; scursor += size; } return scursor == send; } QByteArray IdentityCodec::encode(const QByteArray &src, Codec::NewlineType newline) const { if (newline == Codec::NewlineCRLF) { qWarning() << "IdentityCodec::encode(): CRLF not yet supported!"; } return src; } QByteArray IdentityCodec::decode(const QByteArray &src, Codec::NewlineType newline) const { if (newline == Codec::NewlineCRLF) { qWarning() << "IdentityCodec::decode(): CRLF not yet supported!"; } return src; } diff --git a/src/kcodecsidentity.h b/src/kcodecsidentity.h index 81e8cc5..7c94a50 100644 --- a/src/kcodecsidentity.h +++ b/src/kcodecsidentity.h @@ -1,224 +1,211 @@ /* -*- c++ -*- - Copyright (c) 2004 Marc Mutz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2004 Marc Mutz + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file is part of the API for handling @ref MIME data and defines the Identity, @ref seven-bit-text, @ref eight-bit-text, and @ref eight-bit-binary @ref Codec classes. @brief Defines the classes IdentityCodec, SevenBitCodec, EightBitCodec, and BinaryCodec. @authors Marc Mutz \ */ #ifndef KCODECS_IDENTITY_H #define KCODECS_IDENTITY_H #include "kcodecs.h" class QByteArray; namespace KCodecs { /** @brief A class representing the Identify @ref codec. */ class IdentityCodec : public Codec { public: /** Constructs the Identity codec. */ IdentityCodec() : Codec() {} /** Destroys the codec. */ ~IdentityCodec() override {} using Codec::encode; using Codec::decode; /** @copydoc QByteArray Codec::encode() */ QByteArray encode(const QByteArray &src, Codec::NewlineType newline = Codec::NewlineLF) const override; /** @copydoc QByteArray Codec::decode() */ QByteArray decode(const QByteArray &src, Codec::NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::maxEncodedSizeFor() */ int maxEncodedSizeFor(int insize, Codec::NewlineType newline = Codec::NewlineLF) const override { if (newline == Codec::NewlineCRLF) { return 2 * insize; } else { return insize; } } /** @copydoc Codec::maxDecodedSizeFor() */ int maxDecodedSizeFor(int insize, Codec::NewlineType newline) const override { if (newline == Codec::NewlineCRLF) { return 2 * insize; } else { return insize; } } /** @copydoc Codec::makeEncoder() */ Encoder *makeEncoder(Codec::NewlineType newline = Codec::NewlineCRLF) const override; /** @copydoc Codec::makeDecoder() */ Decoder *makeDecoder(Codec::NewlineType newline = Codec::NewlineCRLF) const override; }; /** @brief A class representing the @ref codec for @ref seven-bit-text. */ class SevenBitCodec : public IdentityCodec { public: /** Constructs the 7-bit codec. */ SevenBitCodec() : IdentityCodec() {} /** Destroys the codec. */ ~SevenBitCodec() override {} /** @copydoc Codec::name() */ const char *name() const override { return "7bit"; } }; /** @brief A class representing the @ref codec for @ref eight-bit-text. */ class EightBitCodec : public IdentityCodec { public: /** Constructs the 8-bit codec. */ EightBitCodec() : IdentityCodec() {} /** Destroys the codec. */ ~EightBitCodec() override {} /** @copydoc Codec::name() */ const char *name() const override { return "8bit"; } }; /** @brief A class representing the @ref codec for @ref eight-bit-binary. */ class BinaryCodec : public IdentityCodec { public: /** Constructs the 8-bit-binary codec. */ BinaryCodec() : IdentityCodec() {} /** Destroys the codec. */ ~BinaryCodec() override {} /** @copydoc Codec::name() */ const char *name() const override { return "binary"; } /** @copydoc Codec::maxEncodedSizeFor() */ int maxEncodedSizeFor(int insize, Codec::NewlineType newline = Codec::NewlineLF) const override { Q_UNUSED(newline); return insize; } /** @copydoc Codec::maxDecodedSizeFor() */ int maxDecodedSizeFor(int insize, Codec::NewlineType newline = Codec::NewlineLF) const override { Q_UNUSED(newline); return insize; } }; } // namespace KCodecs #endif // KCODECS_IDENTITY_H diff --git a/src/kcodecsqp.cpp b/src/kcodecsqp.cpp index b1af576..1301d43 100644 --- a/src/kcodecsqp.cpp +++ b/src/kcodecsqp.cpp @@ -1,771 +1,758 @@ /* -*- c++ -*- - Copyright (c) 2002 Marc Mutz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2002 Marc Mutz + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file is part of the API for handling @ref MIME data and defines the @ref QuotedPrintable, @ref RFC2047Q, and @ref RFC2231 @ref Codec classes. @brief Defines the classes QuotedPrintableCodec, Rfc2047QEncodingCodec, and Rfc2231EncodingCodec. @authors Marc Mutz \ */ #include "kcodecsqp.h" #include "kcodecs_p.h" #include #include using namespace KCodecs; namespace KCodecs { // none except a-zA-Z0-9!*+-/ const uchar eTextMap[16] = { 0x00, 0x00, 0x00, 0x00, 0x40, 0x35, 0xFF, 0xC0, 0x7F, 0xFF, 0xFF, 0xE0, 0x7F, 0xFF, 0xFF, 0xE0 }; // some helpful functions: /** Converts a 4-bit @p value into its hexadecimal characater representation. So input of value [0,15] returns ['0','1',... 'F']. Input values greater than 15 will produce undesired results. @param value is an unsigned character containing the 4-bit input value. */ static inline char binToHex(uchar value) { if (value > 9) { return value + 'A' - 10; } else { return value + '0'; } } /** Returns the high-order 4 bits of an 8-bit value in another 8-bit value. @param ch is an unsigned character containing the 8-bit input value. */ static inline uchar highNibble(uchar ch) { return ch >> 4; } /** Returns the low-order 4 bits of an 8-bit value in another 8-bit value. @param ch is an unsigned character containing the 8-bit input value. */ static inline uchar lowNibble(uchar ch) { return ch & 0xF; } /** Returns true if the specified value is a not Control character or question mark; else true. @param ch is an unsigned character containing the 8-bit input value. */ static inline bool keep(uchar ch) { // no CTLs, except HT and not '?' return !((ch < ' ' && ch != '\t') || ch == '?'); } // // QuotedPrintableCodec // class QuotedPrintableEncoder : public Encoder { char mInputBuffer[16]; uchar mCurrentLineLength; // 0..76 uchar mAccu; uint mInputBufferReadCursor : 4; // 0..15 uint mInputBufferWriteCursor : 4; // 0..15 enum { Never, AtBOL, Definitely } mAccuNeedsEncoding : 2; bool mSawLineEnd : 1; bool mSawCR : 1; bool mFinishing : 1; bool mFinished : 1; protected: friend class QuotedPrintableCodec; QuotedPrintableEncoder(Codec::NewlineType newline = Codec::NewlineLF) : Encoder(newline) , mCurrentLineLength(0) , mAccu(0) , mInputBufferReadCursor(0) , mInputBufferWriteCursor(0) , mAccuNeedsEncoding(Never) , mSawLineEnd(false) , mSawCR(false) , mFinishing(false) , mFinished(false) {} bool needsEncoding(uchar ch) { return ch > '~' || (ch < ' ' && ch != '\t') || ch == '='; } bool needsEncodingAtEOL(uchar ch) { return ch == ' ' || ch == '\t'; } bool needsEncodingAtBOL(uchar ch) { return ch == 'F' || ch == '.' || ch == '-'; } bool fillInputBuffer(const char *&scursor, const char *const send); bool processNextChar(); void createOutputBuffer(char *&dcursor, const char *const dend); public: virtual ~QuotedPrintableEncoder() {} bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override; bool finish(char *&dcursor, const char *const dend) override; }; class QuotedPrintableDecoder : public Decoder { const char mEscapeChar; char mBadChar; /** @p accu holds the msb nibble of the hexchar or zero. */ uchar mAccu; /** @p insideHexChar is true iff we're inside an hexchar (=XY). Together with @ref mAccu, we can build this states: @li @p insideHexChar == @p false: normal text @li @p insideHexChar == @p true, @p mAccu == 0: saw the leading '=' @li @p insideHexChar == @p true, @p mAccu != 0: saw the first nibble '=X' */ const bool mQEncoding; bool mInsideHexChar; bool mFlushing; bool mExpectLF; bool mHaveAccu; /** @p mLastChar holds the first char of an encoded char, so that we are able to keep the first char if the second char is invalid. */ char mLastChar; protected: friend class QuotedPrintableCodec; friend class Rfc2047QEncodingCodec; friend class Rfc2231EncodingCodec; QuotedPrintableDecoder(Codec::NewlineType newline = Codec::NewlineLF, bool aQEncoding = false, char aEscapeChar = '=') : Decoder(newline) , mEscapeChar(aEscapeChar) , mBadChar(0) , mAccu(0) , mQEncoding(aQEncoding) , mInsideHexChar(false) , mFlushing(false) , mExpectLF(false) , mHaveAccu(false) , mLastChar(0) {} public: virtual ~QuotedPrintableDecoder() {} bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override; bool finish(char *&dcursor, const char *const dend) override; }; class Rfc2047QEncodingEncoder : public Encoder { uchar mAccu; uchar mStepNo; const char mEscapeChar; bool mInsideFinishing : 1; protected: friend class Rfc2047QEncodingCodec; friend class Rfc2231EncodingCodec; Rfc2047QEncodingEncoder(Codec::NewlineType newline = Codec::NewlineLF, char aEscapeChar = '=') : Encoder(newline) , mAccu(0) , mStepNo(0) , mEscapeChar(aEscapeChar) , mInsideFinishing(false) { // else an optimization in ::encode might break. assert(aEscapeChar == '=' || aEscapeChar == '%'); } bool isEText(uchar ch) { return (ch < 128) && (eTextMap[ ch / 8 ] & 0x80 >> ch % 8); } // this code assumes that isEText( mEscapeChar ) == false! bool needsEncoding(uchar ch) { if (ch > 'z') { return true; // {|}~ DEL and 8bit chars need } if (!isEText(ch)) { return true; // all but a-zA-Z0-9!/*+- need, too } if (mEscapeChar == '%' && (ch == '*' || ch == '/')) { return true; // not allowed in rfc2231 encoding } return false; } public: virtual ~Rfc2047QEncodingEncoder() {} bool encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override; bool finish(char *&dcursor, const char *const dend) override; }; // this doesn't access any member variables, so it can be defined static // but then we can't call it from virtual functions static int QuotedPrintableDecoder_maxDecodedSizeFor(int insize, Codec::NewlineType newline) { // all chars unencoded: int result = insize; // but maybe all of them are \n and we need to make them \r\n :-o if (newline == Codec::NewlineCRLF) { result += insize; } // there might be an accu plus escape result += 2; return result; } Encoder *QuotedPrintableCodec::makeEncoder(Codec::NewlineType newline) const { return new QuotedPrintableEncoder(newline); } Decoder *QuotedPrintableCodec::makeDecoder(Codec::NewlineType newline) const { return new QuotedPrintableDecoder(newline); } int QuotedPrintableCodec::maxDecodedSizeFor(int insize, Codec::NewlineType newline) const { return QuotedPrintableDecoder_maxDecodedSizeFor(insize, newline); } Encoder *Rfc2047QEncodingCodec::makeEncoder(Codec::NewlineType newline) const { return new Rfc2047QEncodingEncoder(newline); } Decoder *Rfc2047QEncodingCodec::makeDecoder(Codec::NewlineType newline) const { return new QuotedPrintableDecoder(newline, true); } int Rfc2047QEncodingCodec::maxDecodedSizeFor(int insize, Codec::NewlineType newline) const { return QuotedPrintableDecoder_maxDecodedSizeFor(insize, newline); } Encoder *Rfc2231EncodingCodec::makeEncoder(Codec::NewlineType newline) const { return new Rfc2047QEncodingEncoder(newline, '%'); } Decoder *Rfc2231EncodingCodec::makeDecoder(Codec::NewlineType newline) const { return new QuotedPrintableDecoder(newline, true, '%'); } int Rfc2231EncodingCodec::maxDecodedSizeFor(int insize, Codec::NewlineType newline) const { return QuotedPrintableDecoder_maxDecodedSizeFor(insize, newline); } /********************************************************/ /********************************************************/ /********************************************************/ bool QuotedPrintableDecoder::decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) { if (d->newline == Codec::NewlineCRLF) { qWarning() << "CRLF output for decoders isn't yet supported!"; } while (scursor != send && dcursor != dend) { if (mFlushing) { // we have to flush chars in the aftermath of an decoding // error. The way to request a flush is to // - store the offending character in mBadChar and // - set mFlushing to true. // The supported cases are (H: hexchar, X: bad char): // =X, =HX, CR // mBadChar is only written out if it is not by itself illegal in // quoted-printable (e.g. CTLs, 8Bits). // A fast way to suppress mBadChar output is to set it to NUL. if (mInsideHexChar) { // output '=' *dcursor++ = mEscapeChar; mInsideHexChar = false; } else if (mHaveAccu) { // output the high nibble of the accumulator: *dcursor++ = mLastChar; mHaveAccu = false; mAccu = 0; } else { // output mBadChar assert(mAccu == 0); if (mBadChar) { if (mBadChar == '=') { mInsideHexChar = true; } else { *dcursor++ = mBadChar; } mBadChar = 0; } mFlushing = false; } continue; } assert(mBadChar == 0); uchar ch = *scursor++; uchar value = 255; if (mExpectLF && ch != '\n') { //qWarning() << "QuotedPrintableDecoder:" // "illegally formed soft linebreak or lonely CR!"; mInsideHexChar = false; mExpectLF = false; if (mAccu != 0) return false; } if (mInsideHexChar) { // next char(s) represent nibble instead of itself: if (ch <= '9') { if (ch >= '0') { value = ch - '0'; } else { switch (ch) { case '\r': mExpectLF = true; break; case '\n': // soft line break, but only if mAccu is NUL. if (!mHaveAccu) { mExpectLF = false; mInsideHexChar = false; break; } // else fall through default: //qWarning() << "QuotedPrintableDecoder:" // "illegally formed hex char! Outputting verbatim."; mBadChar = ch; mFlushing = true; } continue; } } else { // ch > '9' if (ch <= 'F') { if (ch >= 'A') { value = 10 + ch - 'A'; } else { // [:-@] mBadChar = ch; mFlushing = true; continue; } } else { // ch > 'F' if (ch <= 'f' && ch >= 'a') { value = 10 + ch - 'a'; } else { mBadChar = ch; mFlushing = true; continue; } } } assert(value < 16); assert(mBadChar == 0); assert(!mExpectLF); if (mHaveAccu) { *dcursor++ = char(mAccu | value); mAccu = 0; mHaveAccu = false; mInsideHexChar = false; } else { mHaveAccu = true; mAccu = value << 4; mLastChar = ch; } } else { // not mInsideHexChar if ((ch <= '~' && ch >= ' ') || ch == '\t') { if (ch == mEscapeChar) { mInsideHexChar = true; } else if (mQEncoding && ch == '_') { *dcursor++ = char(0x20); } else { *dcursor++ = char(ch); } } else if (ch == '\n') { *dcursor++ = '\n'; mExpectLF = false; } else if (ch == '\r') { mExpectLF = true; } else { //qWarning() << "QuotedPrintableDecoder:" << ch << // "illegal character in input stream!"; *dcursor++ = char(ch); } } } return scursor == send; } bool QuotedPrintableDecoder::finish(char *&dcursor, const char *const dend) { while ((mInsideHexChar || mHaveAccu || mFlushing) && dcursor != dend) { // we have to flush chars if (mInsideHexChar) { // output '=' *dcursor++ = mEscapeChar; mInsideHexChar = false; } else if (mHaveAccu) { // output the high nibble of the accumulator: *dcursor++ = mLastChar; mHaveAccu = false; mAccu = 0; } else { // output mBadChar assert(mAccu == 0); if (mBadChar) { *dcursor++ = mBadChar; mBadChar = 0; } mFlushing = false; } } // return false if we are not finished yet; note that mInsideHexChar is always false return !(mHaveAccu || mFlushing); } bool QuotedPrintableEncoder::fillInputBuffer(const char *&scursor, const char *const send) { // Don't read more if there's still a tail of a line in the buffer: if (mSawLineEnd) { return true; } // Read until the buffer is full or we have found CRLF or LF (which // don't end up in the input buffer): for (; (mInputBufferWriteCursor + 1) % 16 != mInputBufferReadCursor && scursor != send ; mInputBufferWriteCursor++) { char ch = *scursor++; if (ch == '\r') { mSawCR = true; } else if (ch == '\n') { // remove the CR from the input buffer (if any) and return that // we found a line ending: if (mSawCR) { mSawCR = false; assert(mInputBufferWriteCursor != mInputBufferReadCursor); mInputBufferWriteCursor--; } mSawLineEnd = true; return true; // saw CRLF or LF } else { mSawCR = false; } mInputBuffer[ mInputBufferWriteCursor ] = ch; } mSawLineEnd = false; return false; // didn't see a line ending... } bool QuotedPrintableEncoder::processNextChar() { // If we process a buffer which doesn't end in a line break, we // can't process all of it, since the next chars that will be read // could be a line break. So we empty the buffer only until a fixed // number of chars is left (except when mFinishing, which means that // the data doesn't end in newline): const int minBufferFillWithoutLineEnd = 4; assert(d->outputBufferCursor == 0); int bufferFill = int(mInputBufferWriteCursor) - int(mInputBufferReadCursor) ; if (bufferFill < 0) { bufferFill += 16; } assert(bufferFill >= 0 && bufferFill <= 15); if (!mFinishing && !mSawLineEnd && bufferFill < minBufferFillWithoutLineEnd) { return false; } // buffer is empty, return false: if (mInputBufferReadCursor == mInputBufferWriteCursor) { return false; } // Real processing goes here: mAccu = mInputBuffer[ mInputBufferReadCursor++ ]; if (needsEncoding(mAccu)) { // always needs encoding or mAccuNeedsEncoding = Definitely; } else if ((mSawLineEnd || mFinishing) && // needs encoding at end of line bufferFill == 1 && // or end of buffer needsEncodingAtEOL(mAccu)) { mAccuNeedsEncoding = Definitely; } else if (needsEncodingAtBOL(mAccu)) { mAccuNeedsEncoding = AtBOL; } else { // never needs encoding mAccuNeedsEncoding = Never; } return true; } // Outputs processed (verbatim or hex-encoded) chars and inserts soft // line breaks as necessary. Depends on processNextChar's directions // on whether or not to encode the current char, and whether or not // the current char is the last one in it's input line: void QuotedPrintableEncoder::createOutputBuffer(char *&dcursor, const char *const dend) { const int maxLineLength = 76; // rfc 2045 assert(d->outputBufferCursor == 0); bool lastOneOnThisLine = mSawLineEnd && mInputBufferReadCursor == mInputBufferWriteCursor; int neededSpace = 1; if (mAccuNeedsEncoding == Definitely) { neededSpace = 3; } // reserve space for the soft hyphen (=) if (!lastOneOnThisLine) { neededSpace++; } if (mCurrentLineLength > maxLineLength - neededSpace) { // current line too short, insert soft line break: write('=', dcursor, dend); writeCRLF(dcursor, dend); mCurrentLineLength = 0; } if (Never == mAccuNeedsEncoding || (AtBOL == mAccuNeedsEncoding && mCurrentLineLength != 0)) { write(mAccu, dcursor, dend); mCurrentLineLength++; } else { write('=', dcursor, dend); write(binToHex(highNibble(mAccu)), dcursor, dend); write(binToHex(lowNibble(mAccu)), dcursor, dend); mCurrentLineLength += 3; } } bool QuotedPrintableEncoder::encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) { // support probing by the caller: if (mFinishing) { return true; } while (scursor != send && dcursor != dend) { if (d->outputBufferCursor && !flushOutputBuffer(dcursor, dend)) { return scursor == send; } assert(d->outputBufferCursor == 0); // fill input buffer until eol has been reached or until the // buffer is full, whatever comes first: fillInputBuffer(scursor, send); if (processNextChar()) { // there was one... createOutputBuffer(dcursor, dend); } else if (mSawLineEnd && mInputBufferWriteCursor == mInputBufferReadCursor) { // load a hard line break into output buffer: writeCRLF(dcursor, dend); // signal fillInputBuffer() we are ready for the next line: mSawLineEnd = false; mCurrentLineLength = 0; } else { // we are supposedly finished with this input block: break; } } // make sure we write as much as possible and don't stop _writing_ // just because we have no more _input_: if (d->outputBufferCursor) { flushOutputBuffer(dcursor, dend); } return scursor == send; } // encode bool QuotedPrintableEncoder::finish(char *&dcursor, const char *const dend) { mFinishing = true; if (mFinished) { return flushOutputBuffer(dcursor, dend); } while (dcursor != dend) { if (d->outputBufferCursor && !flushOutputBuffer(dcursor, dend)) { return false; } assert(d->outputBufferCursor == 0); if (processNextChar()) { // there was one... createOutputBuffer(dcursor, dend); } else if (mSawLineEnd && mInputBufferWriteCursor == mInputBufferReadCursor) { // load a hard line break into output buffer: writeCRLF(dcursor, dend); mSawLineEnd = false; mCurrentLineLength = 0; } else { mFinished = true; return flushOutputBuffer(dcursor, dend); } } return mFinished && !d->outputBufferCursor; } // finish bool Rfc2047QEncodingEncoder::encode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) { if (mInsideFinishing) { return true; } while (scursor != send && dcursor != dend) { uchar value = 0; switch (mStepNo) { case 0: // read the next char and decide if and how do encode: mAccu = *scursor++; if (!needsEncoding(mAccu)) { *dcursor++ = char(mAccu); } else if (mEscapeChar == '=' && mAccu == 0x20) { // shortcut encoding for 0x20 (latin-1/us-ascii SPACE) // (not for rfc2231 encoding) *dcursor++ = '_'; } else { // needs =XY encoding - write escape char: *dcursor++ = mEscapeChar; mStepNo = 1; } continue; case 1: // extract hi-nibble: value = highNibble(mAccu); mStepNo = 2; break; case 2: // extract lo-nibble: value = lowNibble(mAccu); mStepNo = 0; break; default: assert(0); } // and write: *dcursor++ = binToHex(value); } return scursor == send; } // encode bool Rfc2047QEncodingEncoder::finish(char *&dcursor, const char *const dend) { mInsideFinishing = true; // write the last bits of mAccu, if any: while (mStepNo != 0 && dcursor != dend) { uchar value = 0; switch (mStepNo) { case 1: // extract hi-nibble: value = highNibble(mAccu); mStepNo = 2; break; case 2: // extract lo-nibble: value = lowNibble(mAccu); mStepNo = 0; break; default: assert(0); } // and write: *dcursor++ = binToHex(value); } return mStepNo == 0; } } // namespace KCodecs diff --git a/src/kcodecsqp.h b/src/kcodecsqp.h index 40bf3c7..d46ef4e 100644 --- a/src/kcodecsqp.h +++ b/src/kcodecsqp.h @@ -1,233 +1,220 @@ /* -*- c++ -*- - Copyright (c) 2001-2002 Marc Mutz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2001-2002 Marc Mutz + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file is part of the API for handling @ref MIME data and defines the @ref QuotedPrintable, @ref RFC2047Q, and @ref RFC2231 @ref Codec classes. @brief Defines the classes QuotedPrintableCodec, Rfc2047QEncodingCodec, and Rfc2231EncodingCodec. @authors Marc Mutz \ @glossary @anchor QuotedPrintable @anchor quotedprintable @b quoted-printable: a binary to text encoding scheme based on Section 6.7 of @ref RFC2045. @glossary @anchor RFC2047Q @anchor rfc2047q @b RFC @b 2047Q: Section 4.2 of @ref RFC2047. @glossary @anchor RFC2231 @anchor rfc2231 @b RFC @b 2231: RFC that defines the MIME Parameter Value and Encoded Word Extensions: Character Sets, Languages, and Continuations. */ #ifndef KCODECS_QP_H #define KCODECS_QP_H #include "kcodecs.h" namespace KCodecs { /** @brief A class representing the @ref codec for @ref QuotedPrintable as specified in @ref RFC2045 (section 6.7). */ class QuotedPrintableCodec : public Codec { public: /** Constructs a QuotedPrintable codec. */ QuotedPrintableCodec() : Codec() {} /** Destroys the codec. */ ~QuotedPrintableCodec() override {} /** @copydoc Codec::name() */ const char *name() const override { return "quoted-printable"; } /** @copydoc Codec::maxEncodedSizeFor() */ int maxEncodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override { // all chars encoded: int result = 3 * insize; // then after 25 hexchars comes a soft linebreak: =(\r)\n result += (newline == Codec::NewlineCRLF ? 3 : 2) * (insize / 25); return result; } /** @copydoc Codec::maxDecodedSizeFor() */ int maxDecodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::makeEncoder() */ Encoder *makeEncoder(NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::makeDecoder() */ Decoder *makeDecoder(NewlineType newline = Codec::NewlineLF) const override; }; /** @brief A class representing the @ref codec for the Q encoding as specified in @ref RFC2047Q. */ class Rfc2047QEncodingCodec : public Codec { public: /** Constructs a RFC2047Q codec. */ Rfc2047QEncodingCodec() : Codec() {} /** Destroys the codec. */ ~Rfc2047QEncodingCodec() override {} /** @copydoc Codec::name() */ const char *name() const override { return "q"; } /** @copydoc Codec::maxEncodedSizeFor() */ int maxEncodedSizeFor(int insize, Codec::NewlineType newline = Codec::NewlineLF) const override { Q_UNUSED(newline); // this one is simple: We don't do linebreaking, so all that can // happen is that every char needs encoding, so: return 3 * insize; } /** @copydoc Codec::maxDecodedSizeFor() */ int maxDecodedSizeFor(int insize, Codec::NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::makeEncoder() */ Encoder *makeEncoder(Codec::NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::makeDecoder() */ Decoder *makeDecoder(Codec::NewlineType newline = Codec::NewlineLF) const override; }; /** @brief A class representing the @ref codec for @ref RFC2231. */ class Rfc2231EncodingCodec : public Codec { public: /** Constructs a RFC2231 codec. */ Rfc2231EncodingCodec() : Codec() {} /** Destroys the codec. */ ~Rfc2231EncodingCodec() override {} /** @copydoc Codec::name() */ const char *name() const override { return "x-kmime-rfc2231"; } /** @copydoc Codec::maxEncodedSizeFor() */ int maxEncodedSizeFor(int insize, Codec::NewlineType newline = Codec::NewlineLF) const override { Q_UNUSED(newline); // same as for "q" encoding: return 3 * insize; } /** @copydoc Codec::maxDecodedSizeFor() */ int maxDecodedSizeFor(int insize, Codec::NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::makeEncoder() */ Encoder *makeEncoder(Codec::NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::makeDecoder() */ Decoder *makeDecoder(Codec::NewlineType newline = Codec::NewlineLF) const override; }; } // namespace KCodecs #endif // KCODECS_QP_H diff --git a/src/kcodecsuuencode.cpp b/src/kcodecsuuencode.cpp index 16285ff..960b733 100644 --- a/src/kcodecsuuencode.cpp +++ b/src/kcodecsuuencode.cpp @@ -1,255 +1,242 @@ /* -*- c++ -*- - Copyright (c) 2002 Marc Mutz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2002 Marc Mutz + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file is part of the API for handling @ref MIME data and defines a @ref uuencode @ref Codec class. @brief Defines the UUCodec class. @authors Marc Mutz \ */ #include "kcodecsuuencode.h" #include #include using namespace KCodecs; namespace KCodecs { class UUDecoder : public Decoder { uint mStepNo; uchar mAnnouncedOctetCount; // (on current line) uchar mCurrentOctetCount; // (on current line) uchar mOutbits; bool mLastWasCRLF : 1; bool mSawBegin : 1; // whether we already saw ^begin... uint mIntoBeginLine : 3; // count #chars we compared against "begin" 0..5 bool mSawEnd : 1; // whether we already saw ^end... uint mIntoEndLine : 2; // count #chars we compared against "end" 0..3 void searchForBegin(const char *&scursor, const char *const send); protected: friend class UUCodec; UUDecoder(Codec::NewlineType newline = Codec::NewlineLF) : Decoder(newline) , mStepNo(0) , mAnnouncedOctetCount(0) , mCurrentOctetCount(0) , mOutbits(0) , mLastWasCRLF(true) , mSawBegin(false) , mIntoBeginLine(0) , mSawEnd(false) , mIntoEndLine(0) {} public: virtual ~UUDecoder() {} bool decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) override; // ### really needs no finishing??? bool finish(char *&dcursor, const char *const dend) override { Q_UNUSED(dcursor); Q_UNUSED(dend); return true; } }; Encoder *UUCodec::makeEncoder(NewlineType newline) const { Q_UNUSED(newline) return nullptr; // encoding not supported } Decoder *UUCodec::makeDecoder(NewlineType newline) const { return new UUDecoder(newline); } /********************************************************/ /********************************************************/ /********************************************************/ void UUDecoder::searchForBegin(const char *&scursor, const char *const send) { static const char begin[] = "begin\n"; static const uint beginLength = 5; // sic! assert(!mSawBegin || mIntoBeginLine > 0); while (scursor != send) { uchar ch = *scursor++; if (ch == begin[mIntoBeginLine]) { if (mIntoBeginLine < beginLength) { // found another char ++mIntoBeginLine; if (mIntoBeginLine == beginLength) { mSawBegin = true; // "begin" complete, now search the next \n... } } else { // mIntoBeginLine == beginLength // found '\n': begin line complete mLastWasCRLF = true; mIntoBeginLine = 0; return; } } else if (mSawBegin) { // OK, skip stuff until the next \n } else { //qWarning() << "UUDecoder: garbage before \"begin\", resetting parser"; mIntoBeginLine = 0; } } } // uuencoding just shifts all 6-bit octets by 32 (SP/' '), except NUL, // which gets mapped to 0x60 static inline uchar uuDecode(uchar c) { return (c - ' ') // undo shift and & 0x3F; // map 0x40 (0x60-' ') to 0... } bool UUDecoder::decode(const char *&scursor, const char *const send, char *&dcursor, const char *const dend) { // First, check whether we still need to find the "begin" line: if (!mSawBegin || mIntoBeginLine != 0) { searchForBegin(scursor, send); } else if (mSawEnd) { // or if we are past the end line: scursor = send; // do nothing anymore... return true; } while (dcursor != dend && scursor != send) { uchar ch = *scursor++; uchar value; // Check whether we need to look for the "end" line: if (mIntoEndLine > 0) { static const char end[] = "end"; static const uint endLength = 3; if (ch == end[mIntoEndLine]) { ++mIntoEndLine; if (mIntoEndLine == endLength) { mSawEnd = true; scursor = send; // shortcut to the end return true; } continue; } else { //qWarning() << "UUDecoder: invalid line octet count looks like \"end\" (mIntoEndLine =" // << mIntoEndLine << ")!"; mIntoEndLine = 0; // fall through... } } // Normal parsing: // The first char of a line is an encoding of the length of the // current line. We simply ignore it: if (mLastWasCRLF) { // reset char-per-line counter: mLastWasCRLF = false; mCurrentOctetCount = 0; // try to decode the chars-on-this-line announcement: if (ch == 'e') { // maybe the beginning of the "end"? ;-) mIntoEndLine = 1; } else if (ch > 0x60) { // ### invalid line length char: what shall we do?? } else if (ch > ' ') { mAnnouncedOctetCount = uuDecode(ch); } else if (ch == '\n') { mLastWasCRLF = true; // oops, empty line } continue; } // try converting ch to a 6-bit value: if (ch > 0x60) { continue; // invalid char } else if (ch > ' ') { value = uuDecode(ch); } else if (ch == '\n') { // line end mLastWasCRLF = true; continue; } else { continue; } // add the new bits to the output stream and flush full octets: switch (mStepNo) { case 0: mOutbits = value << 2; break; case 1: if (mCurrentOctetCount < mAnnouncedOctetCount) { *dcursor++ = (char)(mOutbits | value >> 4); } ++mCurrentOctetCount; mOutbits = value << 4; break; case 2: if (mCurrentOctetCount < mAnnouncedOctetCount) { *dcursor++ = (char)(mOutbits | value >> 2); } ++mCurrentOctetCount; mOutbits = value << 6; break; case 3: if (mCurrentOctetCount < mAnnouncedOctetCount) { *dcursor++ = (char)(mOutbits | value); } ++mCurrentOctetCount; mOutbits = 0; break; default: assert(0); } mStepNo = (mStepNo + 1) % 4; // check whether we ran over the announced octet count for this line: if (mCurrentOctetCount == mAnnouncedOctetCount + 1) { // qWarning() // << "UUDecoder: mismatch between announced (" // << mAnnouncedOctetCount << ") and actual line octet count!"; } } // return false when caller should call us again: return scursor == send; } // UUDecoder::decode() } // namespace KCodecs diff --git a/src/kcodecsuuencode.h b/src/kcodecsuuencode.h index 23aafd0..c5e764b 100644 --- a/src/kcodecsuuencode.h +++ b/src/kcodecsuuencode.h @@ -1,114 +1,101 @@ /* -*- c++ -*- - Copyright (c) 2002 Marc Mutz - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2002 Marc Mutz + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file is part of the API for handling @ref MIME data and defines a @ref uuencode @ref Codec class. @brief Defines the UUCodec class. @authors Marc Mutz \ @glossary @anchor UUEncode @anchor uuencode @b uuencode: a binary to text encoding scheme. For more information, see the Wikipedia Uuencode page. */ #ifndef KCODECS_UUENCODE_H #define KCODECS_UUENCODE_H #include "kcodecs.h" namespace KCodecs { /** @brief A class representing the @ref UUEncode @ref codec. */ class UUCodec : public Codec { public: /** Constructs a UUEncode codec. */ UUCodec() : Codec() {} /** Destroys the codec. */ ~UUCodec() override {} /** @copydoc Codec::name() */ const char *name() const override { return "x-uuencode"; } /** @copydoc Codec::maxEncodedSizeFor() */ int maxEncodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override { Q_UNUSED(newline); return insize; // we have no encoder! } /** @copydoc Codec::maxDecodedSizeFor() */ int maxDecodedSizeFor(int insize, NewlineType newline = Codec::NewlineLF) const override { // assuming all characters are part of the uuencode stream (which // does almost never hold due to required linebreaking; but // additional non-uu chars don't affect the output size), each // 4-tupel of them becomes a 3-tupel in the decoded octet // stream. So: int result = ((insize + 3) / 4) * 3; // but all of them may be \n, so if (newline == Codec::NewlineCRLF) { result *= 2; // :-o } return result; } /** @copydoc Codec::makeEncoder() */ Encoder *makeEncoder(NewlineType newline = Codec::NewlineLF) const override; /** @copydoc Codec::makeEncoder() */ Decoder *makeDecoder(NewlineType newline = Codec::NewlineLF) const override; }; } // namespace KCodecs #endif // KCODECS_UUENCODE_H diff --git a/src/kemailaddress.cpp b/src/kemailaddress.cpp index ccde17a..fce8b2a 100644 --- a/src/kemailaddress.cpp +++ b/src/kemailaddress.cpp @@ -1,1137 +1,1124 @@ /* - Copyright (c) 2004 Matt Douhan - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2004 Matt Douhan + + SPDX-License-Identifier: LGPL-2.0-or-later */ #include "kemailaddress.h" #include "kcodecs.h" #include "kcodecs_debug.h" #include #include #include using namespace KEmailAddress; //----------------------------------------------------------------------------- QStringList KEmailAddress::splitAddressList(const QString &aStr) { // Features: // - always ignores quoted characters // - ignores everything (including parentheses and commas) // inside quoted strings // - supports nested comments // - ignores everything (including double quotes and commas) // inside comments QStringList list; if (aStr.isEmpty()) { return list; } QString addr; uint addrstart = 0; int commentlevel = 0; bool insidequote = false; for (int index = 0; index < aStr.length(); index++) { // the following conversion to latin1 is o.k. because // we can safely ignore all non-latin1 characters switch (aStr[index].toLatin1()) { case '"' : // start or end of quoted string if (commentlevel == 0) { insidequote = !insidequote; } break; case '(' : // start of comment if (!insidequote) { ++commentlevel; } break; case ')' : // end of comment if (!insidequote) { if (commentlevel > 0) { --commentlevel; } else { return list; } } break; case '\\' : // quoted character index++; // ignore the quoted character break; case ',' : case ';' : if (!insidequote && (commentlevel == 0)) { addr = aStr.mid(addrstart, index - addrstart); if (!addr.isEmpty()) { list += addr.simplified(); } addrstart = index + 1; } break; } } // append the last address to the list if (!insidequote && (commentlevel == 0)) { addr = aStr.mid(addrstart, aStr.length() - addrstart); if (!addr.isEmpty()) { list += addr.simplified(); } } return list; } //----------------------------------------------------------------------------- // Used by KEmailAddress::splitAddress(...) and KEmailAddress::firstEmailAddress(...). KEmailAddress::EmailParseResult splitAddressInternal(const QByteArray &address, QByteArray &displayName, QByteArray &addrSpec, QByteArray &comment, bool allowMultipleAddresses) { // qCDebug(KCODECS_LOG) << "address"; displayName = ""; addrSpec = ""; comment = ""; if (address.isEmpty()) { return AddressEmpty; } // The following is a primitive parser for a mailbox-list (cf. RFC 2822). // The purpose is to extract a displayable string from the mailboxes. // Comments in the addr-spec are not handled. No error checking is done. enum { TopLevel, InComment, InAngleAddress } context = TopLevel; bool inQuotedString = false; int commentLevel = 0; bool stop = false; for (const char *p = address.data(); *p && !stop; ++p) { switch (context) { case TopLevel : { switch (*p) { case '"' : inQuotedString = !inQuotedString; displayName += *p; break; case '(' : if (!inQuotedString) { context = InComment; commentLevel = 1; } else { displayName += *p; } break; case '<' : if (!inQuotedString) { context = InAngleAddress; } else { displayName += *p; } break; case '\\' : // quoted character displayName += *p; ++p; // skip the '\' if (*p) { displayName += *p; } else { return UnexpectedEnd; } break; case ',' : if (!inQuotedString) { if (allowMultipleAddresses) { stop = true; } else { return UnexpectedComma; } } else { displayName += *p; } break; default : displayName += *p; } break; } case InComment : { switch (*p) { case '(' : ++commentLevel; comment += *p; break; case ')' : --commentLevel; if (commentLevel == 0) { context = TopLevel; comment += ' '; // separate the text of several comments } else { comment += *p; } break; case '\\' : // quoted character comment += *p; ++p; // skip the '\' if (*p) { comment += *p; } else { return UnexpectedEnd; } break; default : comment += *p; } break; } case InAngleAddress : { switch (*p) { case '"' : inQuotedString = !inQuotedString; addrSpec += *p; break; case '>' : if (!inQuotedString) { context = TopLevel; } else { addrSpec += *p; } break; case '\\' : // quoted character addrSpec += *p; ++p; // skip the '\' if (*p) { addrSpec += *p; } else { return UnexpectedEnd; } break; default : addrSpec += *p; } break; } } // switch ( context ) } // check for errors if (inQuotedString) { return UnbalancedQuote; } if (context == InComment) { return UnbalancedParens; } if (context == InAngleAddress) { return UnclosedAngleAddr; } displayName = displayName.trimmed(); comment = comment.trimmed(); addrSpec = addrSpec.trimmed(); if (addrSpec.isEmpty()) { if (displayName.isEmpty()) { return NoAddressSpec; } else { addrSpec = displayName; displayName.truncate(0); } } /* qCDebug(KCODECS_LOG) << "display-name : \"" << displayName << "\""; qCDebug(KCODECS_LOG) << "comment : \"" << comment << "\""; qCDebug(KCODECS_LOG) << "addr-spec : \"" << addrSpec << "\""; */ return AddressOk; } //----------------------------------------------------------------------------- EmailParseResult KEmailAddress::splitAddress(const QByteArray &address, QByteArray &displayName, QByteArray &addrSpec, QByteArray &comment) { return splitAddressInternal(address, displayName, addrSpec, comment, false/* don't allow multiple addresses */); } //----------------------------------------------------------------------------- EmailParseResult KEmailAddress::splitAddress(const QString &address, QString &displayName, QString &addrSpec, QString &comment) { QByteArray d, a, c; // FIXME: toUtf8() is probably not safe here, what if the second byte of a multi-byte character // has the same code as one of the ASCII characters that splitAddress uses as delimiters? EmailParseResult result = splitAddress(address.toUtf8(), d, a, c); if (result == AddressOk) { displayName = QString::fromUtf8(d); addrSpec = QString::fromUtf8(a); comment = QString::fromUtf8(c); } return result; } //----------------------------------------------------------------------------- EmailParseResult KEmailAddress::isValidAddress(const QString &aStr) { // If we are passed an empty string bail right away no need to process // further and waste resources if (aStr.isEmpty()) { return AddressEmpty; } // count how many @'s are in the string that is passed to us // if 0 or > 1 take action // at this point to many @'s cannot bail out right away since // @ is allowed in qoutes, so we use a bool to keep track // and then make a judgment further down in the parser bool tooManyAtsFlag = false; int atCount = aStr.count(QLatin1Char('@')); if (atCount > 1) { tooManyAtsFlag = true; } else if (atCount == 0) { return TooFewAts; } int dotCount = aStr.count(QLatin1Char('.')); // The main parser, try and catch all weird and wonderful // mistakes users and/or machines can create enum { TopLevel, InComment, InAngleAddress } context = TopLevel; bool inQuotedString = false; int commentLevel = 0; unsigned int strlen = aStr.length(); for (unsigned int index = 0; index < strlen; index++) { switch (context) { case TopLevel : { switch (aStr[index].toLatin1()) { case '"' : inQuotedString = !inQuotedString; break; case '(' : if (!inQuotedString) { context = InComment; commentLevel = 1; } break; case '[' : if (!inQuotedString) { return InvalidDisplayName; } break; case ']' : if (!inQuotedString) { return InvalidDisplayName; } break; case ':' : if (!inQuotedString) { return DisallowedChar; } break; case '<' : if (!inQuotedString) { context = InAngleAddress; } break; case '\\' : // quoted character ++index; // skip the '\' if ((index + 1) > strlen) { return UnexpectedEnd; } break; case ',' : if (!inQuotedString) { return UnexpectedComma; } break; case ')' : if (!inQuotedString) { return UnbalancedParens; } break; case '>' : if (!inQuotedString) { return UnopenedAngleAddr; } break; case '@' : if (!inQuotedString) { if (index == 0) { // Missing local part return MissingLocalPart; } else if (index == strlen - 1) { return MissingDomainPart; } } else if (inQuotedString) { --atCount; if (atCount == 1) { tooManyAtsFlag = false; } } break; case '.' : if (inQuotedString) { --dotCount; } break; } break; } case InComment : { switch (aStr[index].toLatin1()) { case '(' : ++commentLevel; break; case ')' : --commentLevel; if (commentLevel == 0) { context = TopLevel; } break; case '\\' : // quoted character ++index; // skip the '\' if ((index + 1) > strlen) { return UnexpectedEnd; } break; } break; } case InAngleAddress : { switch (aStr[index].toLatin1()) { case ',' : if (!inQuotedString) { return UnexpectedComma; } break; case '"' : inQuotedString = !inQuotedString; break; case '@' : if (inQuotedString) { --atCount; } if (atCount == 1) { tooManyAtsFlag = false; } break; case '.' : if (inQuotedString) { --dotCount; } break; case '>' : if (!inQuotedString) { context = TopLevel; break; } break; case '\\' : // quoted character ++index; // skip the '\' if ((index + 1) > strlen) { return UnexpectedEnd; } break; } break; } } } if (dotCount == 0 && !inQuotedString) { return TooFewDots; } if (atCount == 0 && !inQuotedString) { return TooFewAts; } if (inQuotedString) { return UnbalancedQuote; } if (context == InComment) { return UnbalancedParens; } if (context == InAngleAddress) { return UnclosedAngleAddr; } if (tooManyAtsFlag) { return TooManyAts; } return AddressOk; } //----------------------------------------------------------------------------- KEmailAddress::EmailParseResult KEmailAddress::isValidAddressList(const QString &aStr, QString &badAddr) { if (aStr.isEmpty()) { return AddressEmpty; } const QStringList list = splitAddressList(aStr); QStringList::const_iterator it = list.begin(); EmailParseResult errorCode = AddressOk; for (it = list.begin(); it != list.end(); ++it) { qCDebug(KCODECS_LOG) << " *it" << (*it); errorCode = isValidAddress(*it); if (errorCode != AddressOk) { badAddr = (*it); break; } } return errorCode; } //----------------------------------------------------------------------------- QString KEmailAddress::emailParseResultToString(EmailParseResult errorCode) { switch (errorCode) { case TooManyAts : return QObject::tr("The email address you entered is not valid because it " "contains more than one @. " "You will not create valid messages if you do not " "change your address."); case TooFewAts : return QObject::tr("The email address you entered is not valid because it " "does not contain a @. " "You will not create valid messages if you do not " "change your address."); case AddressEmpty : return QObject::tr("You have to enter something in the email address field."); case MissingLocalPart : return QObject::tr("The email address you entered is not valid because it " "does not contain a local part."); case MissingDomainPart : return QObject::tr("The email address you entered is not valid because it " "does not contain a domain part."); case UnbalancedParens : return QObject::tr("The email address you entered is not valid because it " "contains unclosed comments/brackets."); case AddressOk : return QObject::tr("The email address you entered is valid."); case UnclosedAngleAddr : return QObject::tr("The email address you entered is not valid because it " "contains an unclosed angle bracket."); case UnopenedAngleAddr : return QObject::tr("The email address you entered is not valid because it " "contains too many closing angle brackets."); case UnexpectedComma : return QObject::tr("The email address you have entered is not valid because it " "contains an unexpected comma."); case UnexpectedEnd : return QObject::tr("The email address you entered is not valid because it ended " "unexpectedly. This probably means you have used an escaping " "type character like a '\\' as the last character in your " "email address."); case UnbalancedQuote : return QObject::tr("The email address you entered is not valid because it " "contains quoted text which does not end."); case NoAddressSpec : return QObject::tr("The email address you entered is not valid because it " "does not seem to contain an actual email address, i.e. " "something of the form joe@example.org."); case DisallowedChar : return QObject::tr("The email address you entered is not valid because it " "contains an illegal character."); case InvalidDisplayName : return QObject::tr("The email address you have entered is not valid because it " "contains an invalid display name."); case TooFewDots : return QObject::tr("The email address you entered is not valid because it " "does not contain a \'.\'. " "You will not create valid messages if you do not " "change your address."); } return QObject::tr("Unknown problem with email address"); } //----------------------------------------------------------------------------- bool KEmailAddress::isValidSimpleAddress(const QString &aStr) { // If we are passed an empty string bail right away no need to process further // and waste resources if (aStr.isEmpty()) { return false; } int atChar = aStr.lastIndexOf(QLatin1Char('@')); QString domainPart = aStr.mid(atChar + 1); QString localPart = aStr.left(atChar); // Both of these parts must be non empty // after all we cannot have emails like: // @kde.org, or foo@ if (localPart.isEmpty() || domainPart.isEmpty()) { return false; } bool inQuotedString = false; int atCount = localPart.count(QLatin1Char('@')); unsigned int strlen = localPart.length(); for (unsigned int index = 0; index < strlen; index++) { switch (localPart[ index ].toLatin1()) { case '"' : inQuotedString = !inQuotedString; break; case '@' : if (inQuotedString) { --atCount; } break; } } QString addrRx; if (localPart[ 0 ] == QLatin1Char('\"') || localPart[ localPart.length() - 1 ] == QLatin1Char('\"')) { addrRx = QStringLiteral("\"[a-zA-Z@]*[\\w.@-]*[a-zA-Z0-9@]\"@"); } else { addrRx = QStringLiteral("[a-zA-Z]*[~|{}`\\^?=/+*'&%$#!_\\w.-]*[~|{}`\\^?=/+*'&%$#!_a-zA-Z0-9-]@"); } if (domainPart[ 0 ] == QLatin1Char('[') || domainPart[ domainPart.length() - 1 ] == QLatin1Char(']')) { addrRx += QStringLiteral("\\[[0-9]{1,3}(\\.[0-9]{1,3}){3}\\]"); } else { addrRx += QStringLiteral("[\\w#-]+(\\.[\\w#-]+)*"); } const QRegularExpression rx(QRegularExpression::anchoredPattern(addrRx), QRegularExpression::UseUnicodePropertiesOption); return rx.match(aStr).hasMatch(); } //----------------------------------------------------------------------------- QString KEmailAddress::simpleEmailAddressErrorMsg() { return QObject::tr("The email address you entered is not valid because it " "does not seem to contain an actual email address, i.e. " "something of the form joe@example.org."); } //----------------------------------------------------------------------------- QByteArray KEmailAddress::extractEmailAddress(const QByteArray &address) { QString errorMessage; return extractEmailAddress(address, errorMessage); } QByteArray KEmailAddress::extractEmailAddress(const QByteArray &address, QString &errorMessage) { QByteArray dummy1, dummy2, addrSpec; const EmailParseResult result = splitAddressInternal(address, dummy1, addrSpec, dummy2, false/* don't allow multiple addresses */); if (result != AddressOk) { addrSpec = QByteArray(); if (result != AddressEmpty) { errorMessage = emailParseResultToString(result); qCDebug(KCODECS_LOG) << "Input:" << address << "\nError:" << errorMessage; } } else { errorMessage.clear(); } return addrSpec; } //----------------------------------------------------------------------------- QString KEmailAddress::extractEmailAddress(const QString &address) { QString errorMessage; return extractEmailAddress(address, errorMessage); } QString KEmailAddress::extractEmailAddress(const QString &address, QString &errorMessage) { return QString::fromUtf8(extractEmailAddress(address.toUtf8(), errorMessage)); } //----------------------------------------------------------------------------- QByteArray KEmailAddress::firstEmailAddress(const QByteArray &addresses) { QString errorMessage; return firstEmailAddress(addresses, errorMessage); } QByteArray KEmailAddress::firstEmailAddress(const QByteArray &addresses, QString &errorMessage) { QByteArray dummy1, dummy2, addrSpec; const EmailParseResult result = splitAddressInternal(addresses, dummy1, addrSpec, dummy2, true/* allow multiple addresses */); if (result != AddressOk) { addrSpec = QByteArray(); if (result != AddressEmpty) { errorMessage = emailParseResultToString(result); qCDebug(KCODECS_LOG) << "Input: aStr\nError:" << errorMessage; } } else { errorMessage.clear(); } return addrSpec; } //----------------------------------------------------------------------------- QString KEmailAddress::firstEmailAddress(const QString &addresses) { QString errorMessage; return firstEmailAddress(addresses, errorMessage); } QString KEmailAddress::firstEmailAddress(const QString &addresses, QString &errorMessage) { return QString::fromUtf8(firstEmailAddress(addresses.toUtf8(), errorMessage)); } //----------------------------------------------------------------------------- bool KEmailAddress::extractEmailAddressAndName(const QString &aStr, QString &mail, QString &name) { name.clear(); mail.clear(); const int len = aStr.length(); const char cQuotes = '"'; bool bInComment = false; bool bInQuotesOutsideOfEmail = false; int i = 0, iAd = 0, iMailStart = 0, iMailEnd = 0; QChar c; unsigned int commentstack = 0; // Find the '@' of the email address // skipping all '@' inside "(...)" comments: while (i < len) { c = aStr[i]; if (QLatin1Char('(') == c) { ++commentstack; } if (QLatin1Char(')') == c) { --commentstack; } bInComment = commentstack != 0; if (QLatin1Char('"') == c && !bInComment) { bInQuotesOutsideOfEmail = !bInQuotesOutsideOfEmail; } if (!bInComment && !bInQuotesOutsideOfEmail) { if (QLatin1Char('@') == c) { iAd = i; break; // found it } } ++i; } if (!iAd) { // We suppose the user is typing the string manually and just // has not finished typing the mail address part. // So we take everything that's left of the '<' as name and the rest as mail for (i = 0; len > i; ++i) { c = aStr[i]; if (QLatin1Char('<') != c) { name.append(c); } else { break; } } mail = aStr.mid(i + 1); if (mail.endsWith(QLatin1Char('>'))) { mail.truncate(mail.length() - 1); } } else { // Loop backwards until we find the start of the string // or a ',' that is outside of a comment // and outside of quoted text before the leading '<'. bInComment = false; bInQuotesOutsideOfEmail = false; for (i = iAd - 1; 0 <= i; --i) { c = aStr[i]; if (bInComment) { if (QLatin1Char('(') == c) { if (!name.isEmpty()) { name.prepend(QLatin1Char(' ')); } bInComment = false; } else { name.prepend(c); // all comment stuff is part of the name } } else if (bInQuotesOutsideOfEmail) { if (QLatin1Char(cQuotes) == c) { bInQuotesOutsideOfEmail = false; } else if (c != QLatin1Char('\\')) { name.prepend(c); } } else { // found the start of this addressee ? if (QLatin1Char(',') == c) { break; } // stuff is before the leading '<' ? if (iMailStart) { if (QLatin1Char(cQuotes) == c) { bInQuotesOutsideOfEmail = true; // end of quoted text found } else { name.prepend(c); } } else { switch (c.toLatin1()) { case '<': iMailStart = i; break; case ')': if (!name.isEmpty()) { name.prepend(QLatin1Char(' ')); } bInComment = true; break; default: if (QLatin1Char(' ') != c) { mail.prepend(c); } } } } } name = name.simplified(); mail = mail.simplified(); if (mail.isEmpty()) { return false; } mail.append(QLatin1Char('@')); // Loop forward until we find the end of the string // or a ',' that is outside of a comment // and outside of quoted text behind the trailing '>'. bInComment = false; bInQuotesOutsideOfEmail = false; int parenthesesNesting = 0; for (i = iAd + 1; len > i; ++i) { c = aStr[i]; if (bInComment) { if (QLatin1Char(')') == c) { if (--parenthesesNesting == 0) { bInComment = false; if (!name.isEmpty()) { name.append(QLatin1Char(' ')); } } else { // nested ")", add it name.append(QLatin1Char(')')); // name can't be empty here } } else { if (QLatin1Char('(') == c) { // nested "(" ++parenthesesNesting; } name.append(c); // all comment stuff is part of the name } } else if (bInQuotesOutsideOfEmail) { if (QLatin1Char(cQuotes) == c) { bInQuotesOutsideOfEmail = false; } else if (c != QLatin1Char('\\')) { name.append(c); } } else { // found the end of this addressee ? if (QLatin1Char(',') == c) { break; } // stuff is behind the trailing '>' ? if (iMailEnd) { if (QLatin1Char(cQuotes) == c) { bInQuotesOutsideOfEmail = true; // start of quoted text found } else { name.append(c); } } else { switch (c.toLatin1()) { case '>': iMailEnd = i; break; case '(': if (!name.isEmpty()) { name.append(QLatin1Char(' ')); } if (++parenthesesNesting > 0) { bInComment = true; } break; default: if (QLatin1Char(' ') != c) { mail.append(c); } } } } } } name = name.simplified(); mail = mail.simplified(); return !(name.isEmpty() || mail.isEmpty()); } //----------------------------------------------------------------------------- bool KEmailAddress::compareEmail(const QString &email1, const QString &email2, bool matchName) { QString e1Name, e1Email, e2Name, e2Email; extractEmailAddressAndName(email1, e1Email, e1Name); extractEmailAddressAndName(email2, e2Email, e2Name); return e1Email == e2Email && (!matchName || (e1Name == e2Name)); } //----------------------------------------------------------------------------- // Used internally by normalizedAddress() QString removeBidiControlChars(const QString &input) { const int LRO = 0x202D; const int RLO = 0x202E; const int LRE = 0x202A; const int RLE = 0x202B; QString result = input; result.remove(LRO); result.remove(RLO); result.remove(LRE); result.remove(RLE); return result; } QString KEmailAddress::normalizedAddress(const QString &displayName, const QString &addrSpec, const QString &comment) { const QString realDisplayName = removeBidiControlChars(displayName); if (realDisplayName.isEmpty() && comment.isEmpty()) { return addrSpec; } else if (comment.isEmpty()) { if (!realDisplayName.startsWith(QLatin1Char('\"'))) { return quoteNameIfNecessary(realDisplayName) + QLatin1String(" <") + addrSpec + QLatin1Char('>'); } else { return realDisplayName + QLatin1String(" <") + addrSpec + QLatin1Char('>'); } } else if (realDisplayName.isEmpty()) { return quoteNameIfNecessary(comment) + QLatin1String(" <") + addrSpec + QLatin1Char('>'); } else { return realDisplayName + QLatin1String(" (") + comment + QLatin1String(") <") + addrSpec + QLatin1Char('>'); } } //----------------------------------------------------------------------------- QString KEmailAddress::fromIdn(const QString &addrSpec) { const int atPos = addrSpec.lastIndexOf(QLatin1Char('@')); if (atPos == -1) { return addrSpec; } QString idn = QUrl::fromAce(addrSpec.mid(atPos + 1).toLatin1()); if (idn.isEmpty()) { return QString(); } return addrSpec.left(atPos + 1) + idn; } //----------------------------------------------------------------------------- QString KEmailAddress::toIdn(const QString &addrSpec) { const int atPos = addrSpec.lastIndexOf(QLatin1Char('@')); if (atPos == -1) { return addrSpec; } QString idn = QLatin1String(QUrl::toAce(addrSpec.mid(atPos + 1))); if (idn.isEmpty()) { return addrSpec; } return addrSpec.left(atPos + 1) + idn; } //----------------------------------------------------------------------------- QString KEmailAddress::normalizeAddressesAndDecodeIdn(const QString &str) { // qCDebug(KCODECS_LOG) << str; if (str.isEmpty()) { return str; } const QStringList addressList = splitAddressList(str); QStringList normalizedAddressList; QByteArray displayName, addrSpec, comment; for (QStringList::ConstIterator it = addressList.begin(); (it != addressList.end()); ++it) { if (!(*it).isEmpty()) { if (splitAddress((*it).toUtf8(), displayName, addrSpec, comment) == AddressOk) { QByteArray cs; displayName = KCodecs::decodeRFC2047String(displayName, &cs).toUtf8(); comment = KCodecs::decodeRFC2047String(comment, &cs).toUtf8(); normalizedAddressList << normalizedAddress(QString::fromUtf8(displayName), fromIdn(QString::fromUtf8(addrSpec)), QString::fromUtf8(comment)); } } } /* qCDebug(KCODECS_LOG) << "normalizedAddressList: \"" << normalizedAddressList.join( ", " ) << "\""; */ return normalizedAddressList.join(QStringLiteral(", ")); } //----------------------------------------------------------------------------- QString KEmailAddress::normalizeAddressesAndEncodeIdn(const QString &str) { //qCDebug(KCODECS_LOG) << str; if (str.isEmpty()) { return str; } const QStringList addressList = splitAddressList(str); QStringList normalizedAddressList; QByteArray displayName, addrSpec, comment; for (QStringList::ConstIterator it = addressList.begin(); (it != addressList.end()); ++it) { if (!(*it).isEmpty()) { if (splitAddress((*it).toUtf8(), displayName, addrSpec, comment) == AddressOk) { normalizedAddressList << normalizedAddress(QString::fromUtf8(displayName), toIdn(QString::fromUtf8(addrSpec)), QString::fromUtf8(comment)); } } } /* qCDebug(KCODECS_LOG) << "normalizedAddressList: \"" << normalizedAddressList.join( ", " ) << "\""; */ return normalizedAddressList.join(QStringLiteral(", ")); } //----------------------------------------------------------------------------- // Escapes unescaped doublequotes in str. static QString escapeQuotes(const QString &str) { if (str.isEmpty()) { return QString(); } QString escaped; // reserve enough memory for the worst case ( """..."" -> \"\"\"...\"\" ) escaped.reserve(2 * str.length()); unsigned int len = 0; for (int i = 0; i < str.length(); ++i, ++len) { if (str[i] == QLatin1Char('"')) { // unescaped doublequote escaped[len] = QLatin1Char('\\'); ++len; } else if (str[i] == QLatin1Char('\\')) { // escaped character escaped[len] = QLatin1Char('\\'); ++len; ++i; if (i >= str.length()) { // handle trailing '\' gracefully break; } } escaped[len] = str[i]; } escaped.truncate(len); return escaped; } //----------------------------------------------------------------------------- QString KEmailAddress::quoteNameIfNecessary(const QString &str) { QString quoted = str; const QRegularExpression needQuotes(QStringLiteral("[^ 0-9A-Za-z\\x{0080}-\\x{FFFF}]")); // avoid double quoting if ((quoted[0] == QLatin1Char('"')) && (quoted[quoted.length() - 1] == QLatin1Char('"'))) { quoted = QLatin1String("\"") + escapeQuotes(quoted.mid(1, quoted.length() - 2)) + QLatin1String("\""); } else if (quoted.indexOf(needQuotes) != -1) { quoted = QLatin1String("\"") + escapeQuotes(quoted) + QLatin1String("\""); } return quoted; } QUrl KEmailAddress::encodeMailtoUrl(const QString &mailbox) { const QByteArray encodedPath = KCodecs::encodeRFC2047String(mailbox, "utf-8"); QUrl mailtoUrl; mailtoUrl.setScheme(QStringLiteral("mailto")); mailtoUrl.setPath(QLatin1String(encodedPath)); return mailtoUrl; } QString KEmailAddress::decodeMailtoUrl(const QUrl &mailtoUrl) { Q_ASSERT(mailtoUrl.scheme() == QLatin1String("mailto")); return KCodecs::decodeRFC2047String(mailtoUrl.path()); } diff --git a/src/kemailaddress.h b/src/kemailaddress.h index a7afe58..eac4921 100644 --- a/src/kemailaddress.h +++ b/src/kemailaddress.h @@ -1,468 +1,455 @@ /* - Copyright (c) 2004 Matt Douhan - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2004 Matt Douhan + + SPDX-License-Identifier: LGPL-2.0-or-later */ /** @file This file provides static methods for email address validation. @brief Email address validation methods. @author Matt Douhan \ */ #ifndef KCODECS_EMAILADDRESS_H #define KCODECS_EMAILADDRESS_H #include #include #include #include /** * @since 5.5.0 */ namespace KEmailAddress { /** @defgroup emailvalidation Email Validation Functions This collection of methods that can validate email addresses as supplied by the user (typically, user input from a text box). There are also functions for splitting an RFC2822 address into its component parts. @{ */ /** Email validation result. The only 'success' code in this enumeration is AddressOK; all the other values indicate some specific problem with the address which is being validated. Result type for splitAddress(), isValidAddress() and isValidSimpleAddress(). */ enum EmailParseResult { AddressOk, /**< Email is valid */ AddressEmpty, /**< The address is empty */ UnexpectedEnd, /**< Something is unbalanced */ UnbalancedParens, /**< Unbalanced ( ) */ MissingDomainPart, /**< No domain in address */ UnclosedAngleAddr, /**< \< with no matching \> */ UnopenedAngleAddr, /**< \> with no preceding \< */ TooManyAts, /**< More than one \@ in address */ UnexpectedComma, /**< Comma not allowed here */ TooFewAts, /**< Missing \@ in address */ MissingLocalPart, /**< No address specified, only domain */ UnbalancedQuote, /**< Quotes (single or double) not matched */ NoAddressSpec, DisallowedChar, /**< An invalid character detected in address */ InvalidDisplayName, /**< An invalid displayname detected in address */ TooFewDots /**< Missing \. in address */ }; /** Split a comma separated list of email addresses. @param aStr a single string representing a list of addresses @return a list of strings, where each string is one address from the original list */ KCODECS_EXPORT QStringList splitAddressList(const QString &aStr); /** Splits the given address into display name, email address and comment. Returns AddressOk if no error was encountered. Otherwise an appropriate error code is returned. In case of an error the values of displayName, addrSpec and comment are undefined. @param address a single email address, example: Joe User (comment1) (comment2) @param displayName only out: the display-name of the email address, i.e. "Joe User" in the example; in case of an error the return value is undefined @param addrSpec only out: the addr-spec, i.e. "joe.user@example.org" in the example; in case of an error the return value is undefined @param comment only out: the space-separated comments, i.e. "comment1 comment2" in the example; in case of an error the return value is undefined @return AddressOk if no error was encountered. Otherwise an appropriate error code is returned. */ KCODECS_EXPORT EmailParseResult splitAddress(const QByteArray &address, QByteArray &displayName, QByteArray &addrSpec, QByteArray &comment); /** This is an overloaded member function, provided for convenience. It behaves essentially like the above function. Splits the given address into display name, email address and comment. Returns AddressOk if no error was encountered. Otherwise an appropriate error code is returned. In case of an error the values of displayName, addrSpec and comment are undefined. @param address a single email address, example: Joe User (comment1) (comment2) @param displayName only out: the display-name of the email address, i.e. "Joe User" in the example; in case of an error the return value is undefined @param addrSpec only out: the addr-spec, i.e. "joe.user@example.org" in the example; in case of an error the return value is undefined @param comment only out: the space-separated comments, i.e. "comment1 comment2" in the example; in case of an error the return value is undefined @return AddressOk if no error was encountered. Otherwise an appropriate error code is returned. */ KCODECS_EXPORT EmailParseResult splitAddress(const QString &address, QString &displayName, QString &addrSpec, QString &comment); /** Validates an email address in the form of "Joe User" . Returns AddressOk if no error was encountered. Otherwise an appropriate error code is returned. @param aStr a single email address, example: Joe User (comment1) @return AddressOk if no error was encountered. Otherwise an appropriate error code is returned. */ KCODECS_EXPORT EmailParseResult isValidAddress(const QString &aStr); /** Validates a list of email addresses, and also allow aliases and distribution lists to be expanded before validation. @param aStr a string containing a list of email addresses. @param badAddr a string to hold the address that was faulty. @return AddressOk if no error was encountered. Otherwise an appropriate error code is returned. */ KCODECS_EXPORT EmailParseResult isValidAddressList(const QString &aStr, QString &badAddr); /** Translate the enum errorcodes from emailParseResult into i18n'd strings that can be used for msg boxes. @param errorCode an @em error code returned from one of the email validation functions. Do not pass AddressOk as a value, since that will yield a misleading error message @return human-readable and already translated message describing the validation error. */ KCODECS_EXPORT QString emailParseResultToString(EmailParseResult errorCode); /** Validates an email address in the form of joe@example.org. Returns true if no error was encountered. This method should be used when the input field should not allow a "full" email address with comments and other special cases that normally are valid in an email address. @param aStr a single email address, example: joe.user@example.org @return true if no error was encountered. @note This method differs from calling isValidAddress() and checking that that returns AddressOk in two ways: it is faster, and it does @em not allow fancy addresses. */ KCODECS_EXPORT bool isValidSimpleAddress(const QString &aStr); /** Returns a i18n string to be used in msgboxes. This allows for error messages to be the same across the board. @return An i18n ready string for use in msgboxes. */ KCODECS_EXPORT QString simpleEmailAddressErrorMsg(); /** @} */ /** @defgroup emailextraction Email Extraction Functions @{ */ /** Returns the pure email address (addr-spec in RFC2822) of the given address (mailbox in RFC2822). @param address an email address, e.g. "Joe User " @return the addr-spec of @a address, i.e. joe.user@example.org in the example */ KCODECS_EXPORT QByteArray extractEmailAddress(const QByteArray &address); /*KF6 merge with above*/ /** Returns the pure email address (addr-spec in RFC2822) of the given address (mailbox in RFC2822). @param address an email address, e.g. "Joe User " @param errorMessage return error message when we can't parse email @return the addr-spec of @a address, i.e. joe.user@example.org in the example @since 5.11.0 */ KCODECS_EXPORT QByteArray extractEmailAddress(const QByteArray &address, QString &errorMessage); /** This is an overloaded member function, provided for convenience. It behaves essentially like the above function. Returns the pure email address (addr-spec in RFC2822) of the given address (mailbox in RFC2822). @param address an email address, e.g. "Joe User " @return the addr-spec of @a address, i.e. joe.user@example.org in the example */ KCODECS_EXPORT QString extractEmailAddress(const QString &address); /** Returns the pure email address (addr-spec in RFC2822) of the first email address of a list of addresses. @param addresses an email address, e.g. "Joe User " @param errorMessage return error message when we can't parse email @return the addr-spec of @a addresses, i.e. joe.user@example.org in the example @since 5.11 */ KCODECS_EXPORT QString extractEmailAddress(const QString &address, QString &errorMessage); /** Returns the pure email address (addr-spec in RFC2822) of the first email address of a list of addresses. @param addresses an email address, e.g. "Joe User " @return the addr-spec of @a addresses, i.e. joe.user@example.org in the example */ /*KF6 merge with above*/ KCODECS_EXPORT QByteArray firstEmailAddress(const QByteArray &addresses); /** Returns the pure email address (addr-spec in RFC2822) of the first email address of a list of addresses. @param addresses an email address, e.g. "Joe User " @param errorMessage return error message when we can't parse email @return the addr-spec of @a addresses, i.e. joe.user@example.org in the example @since 5.11.0 */ KCODECS_EXPORT QByteArray firstEmailAddress(const QByteArray &addresses, QString &errorMessage); /** This is an overloaded member function, provided for convenience. It behaves essentially like the above function. Returns the pure email address (addr-spec in RFC2822) of the first email address of a list of addresses. @param addresses an email address, e.g. "Joe User " @return the addr-spec of @a addresses, i.e. joe.user@example.org in the example */ KCODECS_EXPORT QString firstEmailAddress(const QString &addresses); /** This is an overloaded member function, provided for convenience. It behaves essentially like the above function. Returns the pure email address (addr-spec in RFC2822) of the first email address of a list of addresses. @param addresses an email address, e.g. "Joe User " @param errorMessage return error message when we can't parse email @return the addr-spec of @a addresses, i.e. joe.user@example.org in the example @since 5.11.0 */ KCODECS_EXPORT QString firstEmailAddress(const QString &addresses, QString &errorMessage); /** Return email address and name from string. Examples: "Stefan Taferner " returns "taferner@example.org" and "Stefan Taferner". "joe@example.com" returns "joe@example.com" and "". Note that this only returns the first address. Also note that the return value is true if both the name and the mail are not empty: this does NOT tell you if mail contains a valid email address or just some rubbish. @param aStr an email address, e.g "Joe User " @param name only out: returns the displayname, "Joe User" in the example @param mail only out: returns the email address "joe.user@example.org" in the example @return true if both name and email address are not empty */ KCODECS_EXPORT bool extractEmailAddressAndName(const QString &aStr, QString &mail, QString &name); /** Compare two email addresses. If matchName is false, it just checks the email address, and returns true if this matches. If matchName is true, both the name and the email must be the same. @param email1 the first email address to use for comparison @param email2 the second email address to use for comparison @param matchName if set to true email address and displayname must match @return true if the comparison matches true in all other cases */ KCODECS_EXPORT bool compareEmail(const QString &email1, const QString &email2, bool matchName); /** Returns a normalized address built from the given parts. The normalized address is of one the following forms: - displayName (comment) <addrSpec> - displayName <addrSpec> - comment <addrSpec> - addrSpec @param displayName the display name of the address @param addrSpec the actual email address (addr-spec in RFC 2822) @param comment a comment @return a normalized address built from the given parts */ KCODECS_EXPORT QString normalizedAddress(const QString &displayName, const QString &addrSpec, const QString &comment = QString()); /** @} */ /** @defgroup emailidn Email IDN (punycode) handling @{ */ /** Decodes the punycode domain part of the given addr-spec if it's an IDN. @param addrSpec a pure 7-bit email address (addr-spec in RFC2822) @return the email address with Unicode domain */ KCODECS_EXPORT QString fromIdn(const QString &addrSpec); /** Encodes the domain part of the given addr-spec in punycode if it's an IDN. @param addrSpec a pure email address with Unicode domain @return the email address with domain in punycode */ KCODECS_EXPORT QString toIdn(const QString &addrSpec); /** Normalizes all email addresses in the given list and decodes all IDNs. @param addresses a list of email addresses with punycoded IDNs @return the email addresses in normalized form with Unicode IDNs */ KCODECS_EXPORT QString normalizeAddressesAndDecodeIdn(const QString &addresses); /** Normalizes all email addresses in the given list and encodes all IDNs in punycode. @param str a list of email addresses @return the email addresses in normalized form */ KCODECS_EXPORT QString normalizeAddressesAndEncodeIdn(const QString &str); /** @} */ /** @ingroup emailextraction Add quote characters around the given string if it contains a character that makes that necessary, in an email name, such as ",". @param str a string that may need quoting @return the string quoted if necessary */ KCODECS_EXPORT QString quoteNameIfNecessary(const QString &str); /** * Creates a valid mailto: URL from the given mailbox. * @param mailbox The mailbox, which means the display name and the address specification, for * example "Thomas McGuire" . The display name is optional. * @return a valid mailto: URL for the given mailbox. */ KCODECS_EXPORT QUrl encodeMailtoUrl(const QString &mailbox); /** * Extracts the mailbox out of the mailto: URL. * @param mailtoUrl the URL with the mailto protocol, which contains the mailbox to be extracted * @return the mailbox, which means the display name and the address specification. */ KCODECS_EXPORT QString decodeMailtoUrl(const QUrl &mailtoUrl); } // namespace KEmailAddress #endif diff --git a/src/kencodingprober.cpp b/src/kencodingprober.cpp index bc9d2e6..8b14032 100644 --- a/src/kencodingprober.cpp +++ b/src/kencodingprober.cpp @@ -1,329 +1,315 @@ /* This file is part of the KDE libraries - Copyright (C) 2008 Wang Hoi (zealot.hoi@gmail.com) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2008 Wang Hoi + SPDX-License-Identifier: LGPL-2.0-or-later */ #include "kencodingprober.h" #include "probers/nsCharSetProber.h" #include "probers/nsUniversalDetector.h" #include "probers/ChineseGroupProber.h" #include "probers/JapaneseGroupProber.h" #include "probers/UnicodeGroupProber.h" #include "probers/nsSBCSGroupProber.h" #include "probers/nsMBCSGroupProber.h" #include class KEncodingProberPrivate { public: KEncodingProberPrivate(): prober(nullptr), mStart(true) {}; ~KEncodingProberPrivate() { delete prober; } void setProberType(KEncodingProber::ProberType pType) { proberType = pType; /* handle multi-byte encodings carefully , because they're hard to detect, * and have to use some Stastics methods. * for single-byte encodings (most western encodings), nsSBCSGroupProber is ok, * because encoding state machine can detect many such encodings. */ delete prober; switch (proberType) { case KEncodingProber::None: prober = nullptr; break; case KEncodingProber::Arabic: case KEncodingProber::Baltic: case KEncodingProber::CentralEuropean: case KEncodingProber::Cyrillic: case KEncodingProber::Greek: case KEncodingProber::Hebrew: case KEncodingProber::NorthernSaami: case KEncodingProber::Other: case KEncodingProber::SouthEasternEurope: case KEncodingProber::Thai: case KEncodingProber::Turkish: case KEncodingProber::WesternEuropean: prober = new kencodingprober::nsSBCSGroupProber(); break; case KEncodingProber::ChineseSimplified: case KEncodingProber::ChineseTraditional: prober = new kencodingprober::ChineseGroupProber(); break; case KEncodingProber::Japanese: prober = new kencodingprober::JapaneseGroupProber(); break; case KEncodingProber::Korean: prober = new kencodingprober::nsMBCSGroupProber(); break; case KEncodingProber::Unicode: prober = new kencodingprober::UnicodeGroupProber(); break; case KEncodingProber::Universal: prober = new kencodingprober::nsUniversalDetector(); break; default: prober = nullptr; } } void unicodeTest(const char *aBuf, int aLen) { if (mStart) { mStart = false; if (aLen > 3) switch (aBuf[0]) { case '\xEF': if (('\xBB' == aBuf[1]) && ('\xBF' == aBuf[2])) // EF BB BF UTF-8 encoded BOM { proberState = KEncodingProber::FoundIt; } break; case '\xFE': if (('\xFF' == aBuf[1]) && ('\x00' == aBuf[2]) && ('\x00' == aBuf[3])) // FE FF 00 00 UCS-4, unusual octet order BOM (3412) { proberState = KEncodingProber::FoundIt; } else if ('\xFF' == aBuf[1]) // FE FF UTF-16, big endian BOM { proberState = KEncodingProber::FoundIt; } break; case '\x00': if (('\x00' == aBuf[1]) && ('\xFE' == aBuf[2]) && ('\xFF' == aBuf[3])) // 00 00 FE FF UTF-32, big-endian BOM { proberState = KEncodingProber::FoundIt; } else if (('\x00' == aBuf[1]) && ('\xFF' == aBuf[2]) && ('\xFE' == aBuf[3])) // 00 00 FF FE UCS-4, unusual octet order BOM (2143) { proberState = KEncodingProber::FoundIt; } break; case '\xFF': if (('\xFE' == aBuf[1]) && ('\x00' == aBuf[2]) && ('\x00' == aBuf[3])) // FF FE 00 00 UTF-32, little-endian BOM { proberState = KEncodingProber::FoundIt; } else if ('\xFE' == aBuf[1]) // FF FE UTF-16, little endian BOM { proberState = KEncodingProber::FoundIt; } break; } // switch } } KEncodingProber::ProberType proberType; KEncodingProber::ProberState proberState; kencodingprober::nsCharSetProber *prober; bool mStart; }; KEncodingProber::KEncodingProber(KEncodingProber::ProberType proberType): d(new KEncodingProberPrivate()) { setProberType(proberType); } KEncodingProber::~KEncodingProber() { delete d; } void KEncodingProber::reset() { d->proberState = KEncodingProber::Probing; d->mStart = true; } KEncodingProber::ProberState KEncodingProber::feed(const QByteArray &data) { return feed(data.data(), data.size()); } KEncodingProber::ProberState KEncodingProber::feed(const char *data, int len) { if (!d->prober) { return d->proberState; } if (d->proberState == Probing) { if (d->mStart) { d->unicodeTest(data, len); if (d->proberState == FoundIt) { return d->proberState; } } d->prober->HandleData(data, len); switch (d->prober->GetState()) { case kencodingprober::eNotMe: d->proberState = NotMe; break; case kencodingprober::eFoundIt: d->proberState = FoundIt; break; default: d->proberState = Probing; break; } } #ifdef DEBUG_PROBE d->prober->DumpStatus(); #endif return d->proberState; } KEncodingProber::ProberState KEncodingProber::state() const { return d->proberState; } QByteArray KEncodingProber::encoding() const { if (!d->prober) { return QByteArray("UTF-8"); } return QByteArray(d->prober->GetCharSetName()); } float KEncodingProber::confidence() const { if (!d->prober) { return 0.0; } return d->prober->GetConfidence(); } KEncodingProber::ProberType KEncodingProber::proberType() const { return d->proberType; } void KEncodingProber::setProberType(KEncodingProber::ProberType proberType) { d->setProberType(proberType); reset(); } KEncodingProber::ProberType KEncodingProber::proberTypeForName(const QString &lang) { if (lang.isEmpty()) { return KEncodingProber::Universal; } else if (lang == tr("Disabled", "@item Text character set")) { return KEncodingProber::None; } else if (lang == tr("Universal", "@item Text character set")) { return KEncodingProber::Universal; } else if (lang == tr("Unicode", "@item Text character set")) { return KEncodingProber::Unicode; } else if (lang == tr("Cyrillic", "@item Text character set")) { return KEncodingProber::Cyrillic; } else if (lang == tr("Western European", "@item Text character set")) { return KEncodingProber::WesternEuropean; } else if (lang == tr("Central European", "@item Text character set")) { return KEncodingProber::CentralEuropean; } else if (lang == tr("Greek", "@item Text character set")) { return KEncodingProber::Greek; } else if (lang == tr("Hebrew", "@item Text character set")) { return KEncodingProber::Hebrew; } else if (lang == tr("Turkish", "@item Text character set")) { return KEncodingProber::Turkish; } else if (lang == tr("Japanese", "@item Text character set")) { return KEncodingProber::Japanese; } else if (lang == tr("Baltic", "@item Text character set")) { return KEncodingProber::Baltic; } else if (lang == tr("Chinese Traditional", "@item Text character set")) { return KEncodingProber::ChineseTraditional; } else if (lang == tr("Chinese Simplified", "@item Text character set")) { return KEncodingProber::ChineseSimplified; } else if (lang == tr("Korean", "@item Text character set")) { return KEncodingProber::Korean; } else if (lang == tr("Thai", "@item Text character set")) { return KEncodingProber::Thai; } else if (lang == tr("Arabic", "@item Text character set")) { return KEncodingProber::Arabic; } return KEncodingProber::Universal; } QString KEncodingProber::nameForProberType(KEncodingProber::ProberType proberType) { switch (proberType) { case KEncodingProber::None: return tr("Disabled", "@item Text character set"); break; case KEncodingProber::Universal: return tr("Universal", "@item Text character set"); break; case KEncodingProber::Arabic: return tr("Arabic", "@item Text character set"); break; case KEncodingProber::Baltic: return tr("Baltic", "@item Text character set"); break; case KEncodingProber::CentralEuropean: return tr("Central European", "@item Text character set"); break; case KEncodingProber::Cyrillic: return tr("Cyrillic", "@item Text character set"); break; case KEncodingProber::Greek: return tr("Greek", "@item Text character set"); break; case KEncodingProber::Hebrew: return tr("Hebrew", "@item Text character set"); break; case KEncodingProber::Japanese: return tr("Japanese", "@item Text character set"); break; case KEncodingProber::Turkish: return tr("Turkish", "@item Text character set"); break; case KEncodingProber::WesternEuropean: return tr("Western European", "@item Text character set"); break; case KEncodingProber::ChineseTraditional: return tr("Chinese Traditional", "@item Text character set"); break; case KEncodingProber::ChineseSimplified: return tr("Chinese Simplified", "@item Text character set"); break; case KEncodingProber::Korean: return tr("Korean", "@item Text character set"); break; case KEncodingProber::Thai: return tr("Thai", "@item Text character set"); break; case KEncodingProber::Unicode: return tr("Unicode", "@item Text character set"); break; default: return QString(); } } diff --git a/src/kencodingprober.h b/src/kencodingprober.h index e907afc..a226755 100644 --- a/src/kencodingprober.h +++ b/src/kencodingprober.h @@ -1,169 +1,155 @@ /* This file is part of the KDE libraries - Copyright (C) 2008 Wang Hoi (zealot.hoi@gmail.com) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. + SPDX-FileCopyrightText: 2008 Wang Hoi + SPDX-License-Identifier: LGPL-2.0-or-later */ #ifndef KENCODINGPROBER_H #define KENCODINGPROBER_H // enable debug of private probers // #define DEBUG_PROBE #include #ifdef DEBUG_PROBE #include #endif #include #include class KEncodingProberPrivate; /** * @class KEncodingProber kencodingprober.h KEncodingProber * * @short Provides encoding detection(probe) capabilities. * * Probe the encoding of raw data only. * In the case it can't find it, return the most possible encoding it guessed. * * Always do Unicode probe regardless the ProberType * * Feed data to it several times with feed() until ProberState changes to FoundIt/NotMe, * or confidence() returns a value you find acceptable. * * Intended lifetime of the object: one instance per ProberType. * * Typical use: * \code * QByteArray data, moredata; * ... * KEncodingProber prober(KEncodingProber::Chinese); * prober.feed(data); * prober.feed(moredata); * if (prober.confidence() > 0.6) * QString out = QTextCodec::codecForName(prober.encoding())->toUnicode(data); * \endcode * * At least 256 characters are needed to change the ProberState from Probing to FoundIt. * If you don't have so many characters to probe, * decide whether to accept the encoding it guessed so far according to the Confidence by yourself. * * @short Guess encoding of char array * */ class KCODECS_EXPORT KEncodingProber { Q_DECLARE_TR_FUNCTIONS(KEncodingProber) public: enum ProberState { FoundIt, /**< Sure find the encoding */ NotMe, /**< Sure not included in current ProberType's all supported encodings */ Probing /**< Need more data to make a decision */ }; enum ProberType { None, Universal, Arabic, Baltic, CentralEuropean, ChineseSimplified, ChineseTraditional, Cyrillic, Greek, Hebrew, Japanese, Korean, NorthernSaami, Other, SouthEasternEurope, Thai, Turkish, Unicode, WesternEuropean }; /** * Default ProberType is Universal(detect all possibe encodings) */ KEncodingProber(ProberType proberType = Universal); ~KEncodingProber(); KEncodingProber(const KEncodingProber &) = delete; KEncodingProber& operator=(const KEncodingProber &) = delete; /** * reset the prober's internal state and data. */ void reset(); /** * The main class method * * feed data to the prober * * @returns the ProberState after probing the fed data. */ ProberState feed(const QByteArray &data); ProberState feed(const char *data, int len); /** * @returns the prober's current ProberState * */ ProberState state() const; /** * @returns a QByteArray with the name of the best encoding it has guessed so far * @since 4.2.2 */ QByteArray encoding() const; /** * @returns the confidence(sureness) of encoding it guessed so far (0.0 ~ 0.99), not very reliable for single byte encodings */ float confidence() const; ProberType proberType() const; /** * change current prober's ProberType and reset the prober */ void setProberType(ProberType proberType); /** * @return the ProberType for lang (eg. proberTypeForName("Chinese Simplified") will return KEncodingProber::ChineseSimplified */ static ProberType proberTypeForName(const QString &lang); /** * map ProberType to language string */ static QString nameForProberType(ProberType proberType); private: KEncodingProberPrivate *const d; }; #endif diff --git a/src/kentities.gperf b/src/kentities.gperf index 90ba88a..df2677c 100644 --- a/src/kentities.gperf +++ b/src/kentities.gperf @@ -1,325 +1,312 @@ %language=C++ %enum %readonly-tables %compare-strncmp %struct-type %define lookup-function-name kde_findEntity %define hash-function-name hash_Entity %define word-array-name wordlist_Entity %define class-name KCodecsEntities %{ /* This file is part of the KDE libraries - - Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. - + + SPDX-FileCopyrightText: 1999 Lars Knoll + + SPDX-License-Identifier: LGPL-2.0-or-later + ---------------------------------------------------------------------------- - + kentities.gperf: input file to generate a hash table for entities kentities.c: DO NOT EDIT! generated by the command "gperf -k '*' -D -s 2 --output-file=kentities.h kentities.gperf" from kentities.gperf -*/ +*/ %} struct entity { const char *name; int code; }; %% AElig, 0x00c6 Aacute, 0x00c1 Acirc, 0x00c2 Agrave, 0x00c0 Alpha, 0x0391 AMP, 38 Aring, 0x00c5 Atilde, 0x00c3 Auml, 0x00c4 Beta, 0x0392 Ccaron, 0x010c Ccedil, 0x00c7 Chi, 0x03a7 Dagger, 0x2021 Dcaron, 0x010e Delta, 0x0394 ETH, 0x00d0 Eacute, 0x00c9 Ecaron, 0x011a Ecirc, 0x00ca Egrave, 0x00c8 Eague, 0x00c9 Epsilon, 0x0395 Eta, 0x0397 Euml, 0x00cb Gamma, 0x0393 GT, 62 Iacute, 0x00cd Icirc, 0x00ce Igrave, 0x00cc Iota, 0x0399 Iuml, 0x00cf Kappa, 0x039a Lambda, 0x039b LT, 60 Mu, 0x039c Ncaron, 0x0147 Ntilde, 0x00d1 Nu, 0x039d OElig, 0x0152 Oacute, 0x00d3 Ocirc, 0x00d4 Ograve, 0x00d2 Omega, 0x03a9 Omicron, 0x039f Oslash, 0x00d8 Otilde, 0x00d5 Ouml, 0x00d6 Phi, 0x03a6 Pi, 0x03a0 Prime, 0x2033 Psi, 0x03a8 QUOT, 34 Rcaron, 0x0158 Rho, 0x03a1 Scaron, 0x0160 Sigma, 0x03a3 THORN, 0x00de Tau, 0x03a4 Tcaron, 0x0164 Theta, 0x0398 Uacute, 0x00da Ucirc, 0x00db Ugrave, 0x00d9 Upsilon, 0x03a5 Uring, 0x016e Uuml, 0x00dc Xi, 0x039e Yacute, 0x00dd Yuml, 0x0178 Zcaron, 0x017d Zeta, 0x0396 aacute, 0x00e1 acirc, 0x00e2 acute, 0x00b4 aelig, 0x00e6 agrave, 0x00e0 alefsym, 0x2135 alpha, 0x03b1 amp, 38 and, 0x2227 ang, 0x2220 apos, 0x0027 aring, 0x00e5 asymp, 0x2248 atilde, 0x00e3 auml, 0x00e4 bdquo, 0x201e beta, 0x03b2 brvbar, 0x00a6 bull, 0x2022 cap, 0x2229 ccaron, 0x010d ccedil, 0x00e7 cedil, 0x00b8 cent, 0x00a2 chi, 0x03c7 circ, 0x02c6 clubs, 0x2663 cong, 0x2245 copy, 0x00a9 crarr, 0x21b5 cup, 0x222a curren, 0x00a4 dArr, 0x21d3 dagger, 0x2020 darr, 0x2193 dcaron, 0x10f deg, 0x00b0 delta, 0x03b4 diams, 0x2666 divide, 0x00f7 dol, 0x0024 dollar, 0x0024 eacute, 0x00e9 ecaron, 0x011b eague, 0x00e9 ecirc, 0x00ea egrave, 0x00e8 emdash, 0x2014 empty, 0x2205 emsp, 0x2003 endash, 0x2013 ensp, 0x2002 epsilon, 0x03b5 equiv, 0x2261 eta, 0x03b7 eth, 0x00f0 euml, 0x00eb euro, 0x20ac exist, 0x2203 fnof, 0x0192 forall, 0x2200 frac12, 0x00bd frac14, 0x00bc frac34, 0x00be frasl, 0x2044 gamma, 0x03b3 ge, 0x2265 gt, 62 hArr, 0x21d4 harr, 0x2194 hearts, 0x2665 hellip, 0x2026 iacute, 0x00ed icirc, 0x00ee iexcl, 0x00a1 igrave, 0x00ec image, 0x2111 infin, 0x221e int, 0x222b iota, 0x03b9 iquest, 0x00bf isin, 0x2208 iuml, 0x00ef kappa, 0x03ba lArr, 0x21d0 lambda, 0x03bb lang, 0x2329 laquo, 0x00ab larr, 0x2190 lceil, 0x2308 ldquo, 0x201c le, 0x2264 lfloor, 0x230a lowast, 0x2217 loz, 0x25ca lrm, 0x200e lsaquo, 0x2039 lsquo, 0x2018 lt, 60 macr, 0x00af mdash, 0x2014 micro, 0x00b5 middot, 0x00b7 minus, 0x2212 mu, 0x03bc nabla, 0x2207 nbsp, 0x00a0 ncaron, 0x0148 ndash, 0x2013 ne, 0x2260 ni, 0x220b not, 0x00ac notin, 0x2209 nsub, 0x2284 ntilde, 0x00f1 nu, 0x03bd oacute, 0x00f3 ocirc, 0x00f4 oelig, 0x0153 ograve, 0x00f2 oline, 0x203e omega, 0x03c9 omicron, 0x03bf oplus, 0x2295 or, 0x2228 ordf, 0x00aa ordm, 0x00ba oslash, 0x00f8 otilde, 0x00f5 otimes, 0x2297 ouml, 0x00f6 para, 0x00b6 part, 0x2202 percnt, 0x0025 permil, 0x2030 perp, 0x22a5 phi, 0x03c6 pi, 0x03c0 piv, 0x03d6 plusmn, 0x00b1 pound, 0x00a3 prime, 0x2032 prod, 0x220f prop, 0x221d psi, 0x03c8 quot, 34 rArr, 0x21d2 radic, 0x221a rang, 0x232a raquo, 0x00bb rarr, 0x2192 rcaron, 0x0159 rceil, 0x2309 rdquo, 0x201d real, 0x211c reg, 0x00ae rfloor, 0x230b rho, 0x03c1 rlm, 0x200f rsaquo, 0x203a rsquo, 0x2019 sbquo, 0x201a scaron, 0x0161 sdot, 0x22c5 sect, 0x00a7 shy, 0x00ad sigma, 0x03c3 sigmaf, 0x03c2 sim, 0x223c spades, 0x2660 sub, 0x2282 sube, 0x2286 sum, 0x2211 sup1, 0x00b9 supl, 0x00b9 sup2, 0x00b2 sup3, 0x00b3 sup, 0x2283 supe, 0x2287 szlig, 0x00df tau, 0x03c4 tcaron, 0x0165 there4, 0x2234 theta, 0x03b8 thetasym, 0x03d1 thinsp, 0x2009 thorn, 0x00fe tilde, 0x02dc times, 0x00d7 trade, 0x2122 uArr, 0x21d1 uacute, 0x00fa uarr, 0x2191 ucirc, 0x00fb ugrave, 0x00f9 uml, 0x00a8 upsih, 0x03d2 upsilon, 0x03c5 uring, 0x016f uuml, 0x00fc weierp, 0x2118 xi, 0x03be yacute, 0x00fd yen, 0x00a5 yuml, 0x00ff zcaron, 0x017e zeta, 0x03b6 zwj, 0x200d zwnj, 0x200c %% diff --git a/src/probers/CharDistribution.cpp b/src/probers/CharDistribution.cpp index 6c06434..0ee07ea 100644 --- a/src/probers/CharDistribution.cpp +++ b/src/probers/CharDistribution.cpp @@ -1,91 +1,73 @@ /* -*- C++ -*- - * Copyright (C) 1998 - * - * - * 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. - */ + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT +*/ #include "CharDistribution.h" #include "tables/JISFreq.tab" #include "tables/Big5Freq.tab" #include "tables/EUCKRFreq.tab" #include "tables/GB2312Freq.tab" #define SURE_YES 0.99f #define SURE_NO 0.01f namespace kencodingprober { //return confidence base on received data float CharDistributionAnalysis::GetConfidence() { //if we didn't receive any character in our consideration range, return negative answer if (mTotalChars <= 0) { return SURE_NO; } if (mTotalChars != mFreqChars) { float r = mFreqChars / ((mTotalChars - mFreqChars) * mTypicalDistributionRatio); if (r < SURE_YES) { return r; } } //normalize confidence, (we don't want to be 100% sure) return SURE_YES; } EUCKRDistributionAnalysis::EUCKRDistributionAnalysis() { mCharToFreqOrder = EUCKRCharToFreqOrder; mTableSize = EUCKR_TABLE_SIZE; mTypicalDistributionRatio = EUCKR_TYPICAL_DISTRIBUTION_RATIO; } GB2312DistributionAnalysis::GB2312DistributionAnalysis() { mCharToFreqOrder = GB2312CharToFreqOrder; mTableSize = GB2312_TABLE_SIZE; mTypicalDistributionRatio = GB2312_TYPICAL_DISTRIBUTION_RATIO; } Big5DistributionAnalysis::Big5DistributionAnalysis() { mCharToFreqOrder = Big5CharToFreqOrder; mTableSize = BIG5_TABLE_SIZE; mTypicalDistributionRatio = BIG5_TYPICAL_DISTRIBUTION_RATIO; } SJISDistributionAnalysis::SJISDistributionAnalysis() { mCharToFreqOrder = JISCharToFreqOrder; mTableSize = JIS_TABLE_SIZE; mTypicalDistributionRatio = JIS_TYPICAL_DISTRIBUTION_RATIO; } EUCJPDistributionAnalysis::EUCJPDistributionAnalysis() { mCharToFreqOrder = JISCharToFreqOrder; mTableSize = JIS_TABLE_SIZE; mTypicalDistributionRatio = JIS_TYPICAL_DISTRIBUTION_RATIO; } } diff --git a/src/probers/CharDistribution.h b/src/probers/CharDistribution.h index 1e8029c..841348f 100644 --- a/src/probers/CharDistribution.h +++ b/src/probers/CharDistribution.h @@ -1,226 +1,208 @@ /* -*- C++ -*- - * Copyright (C) 1998 - * - * - * 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. - */ + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT +*/ #ifndef CharDistribution_h__ #define CharDistribution_h__ #include "kcodecs_export.h" #include #define ENOUGH_DATA_THRESHOLD 256 namespace kencodingprober { class KCODECS_NO_EXPORT CharDistributionAnalysis { public: CharDistributionAnalysis() { Reset(); } virtual ~CharDistributionAnalysis() {} //feed a block of data and do distribution analysis void HandleData(const char * /* aBuf */, unsigned int /* aLen */) {} //Feed a character with known length void HandleOneChar(const char *aStr, unsigned int aCharLen) { int order; //we only care about 2-bytes character in our distribution analysis order = (aCharLen == 2) ? GetOrder(aStr) : -1; if (order >= 0) { mTotalChars++; //order is valid if ((unsigned int)order < mTableSize) { if (512 > mCharToFreqOrder[order]) { mFreqChars++; } } } } //return confidence base on existing data float GetConfidence(); //Reset analyser, clear any state void Reset(void) { mDone = false; mTotalChars = 0; mFreqChars = 0; } //This function is for future extension. Caller can use this function to control //analyser's behavior void SetOpion() {} //It is not necessary to receive all data to draw conclusion. For charset detection, // certain amount of data is enough bool GotEnoughData() { return mTotalChars > ENOUGH_DATA_THRESHOLD; } protected: //we do not handle character base on its original encoding string, but //convert this encoding string to a number, here called order. //This allow multiple encoding of a language to share one frequency table virtual int GetOrder(const char * /* str */) { return -1; } //If this flag is set to true, detection is done and conclusion has been made bool mDone; //The number of characters whose frequency order is less than 512 unsigned int mFreqChars; //Total character encounted. unsigned int mTotalChars; //Mapping table to get frequency order from char order (get from GetOrder()) const short *mCharToFreqOrder; //Size of above table unsigned int mTableSize; //This is a constant value varies from language to language, it is used in //calculating confidence. See my paper for further detail. float mTypicalDistributionRatio; }; class KCODECS_NO_EXPORT EUCKRDistributionAnalysis : public CharDistributionAnalysis { public: EUCKRDistributionAnalysis(); protected: //for euc-KR encoding, we are interested // first byte range: 0xb0 -- 0xfe // second byte range: 0xa1 -- 0xfe //no validation needed here. State machine has done that int GetOrder(const char *str) override { if ((unsigned char)*str >= (unsigned char)0xb0) { return 94 * ((unsigned char)str[0] - (unsigned char)0xb0) + (unsigned char)str[1] - (unsigned char)0xa1; } else { return -1; } } }; class KCODECS_NO_EXPORT GB2312DistributionAnalysis : public CharDistributionAnalysis { public: GB2312DistributionAnalysis(); protected: //for GB2312 encoding, we are interested // first byte range: 0xb0 -- 0xfe // second byte range: 0xa1 -- 0xfe //no validation needed here. State machine has done that int GetOrder(const char *str) override { if ((unsigned char)*str >= (unsigned char)0xb0 && (unsigned char)str[1] >= (unsigned char)0xa1) { return 94 * ((unsigned char)str[0] - (unsigned char)0xb0) + (unsigned char)str[1] - (unsigned char)0xa1; } else { return -1; } } }; class KCODECS_NO_EXPORT Big5DistributionAnalysis : public CharDistributionAnalysis { public: Big5DistributionAnalysis(); protected: //for big5 encoding, we are interested // first byte range: 0xa4 -- 0xfe // second byte range: 0x40 -- 0x7e , 0xa1 -- 0xfe //no validation needed here. State machine has done that int GetOrder(const char *str) override { if ((unsigned char)*str >= (unsigned char)0xa4) if ((unsigned char)str[1] >= (unsigned char)0xa1) { return 157 * ((unsigned char)str[0] - (unsigned char)0xa4) + (unsigned char)str[1] - (unsigned char)0xa1 + 63; } else { return 157 * ((unsigned char)str[0] - (unsigned char)0xa4) + (unsigned char)str[1] - (unsigned char)0x40; } else { return -1; } } }; class KCODECS_NO_EXPORT SJISDistributionAnalysis : public CharDistributionAnalysis { public: SJISDistributionAnalysis(); protected: //for sjis encoding, we are interested // first byte range: 0x81 -- 0x9f , 0xe0 -- 0xfe // second byte range: 0x40 -- 0x7e, 0x81 -- oxfe //no validation needed here. State machine has done that int GetOrder(const char *str) override { int order; if ((unsigned char)*str >= (unsigned char)0x81 && (unsigned char)*str <= (unsigned char)0x9f) { order = 188 * ((unsigned char)str[0] - (unsigned char)0x81); } else if ((unsigned char)*str >= (unsigned char)0xe0 && (unsigned char)*str <= (unsigned char)0xef) { order = 188 * ((unsigned char)str[0] - (unsigned char)0xe0 + 31); } else { return -1; } order += (unsigned char) * (str + 1) - 0x40; if ((unsigned char)str[1] > (unsigned char)0x7f) { order--; } return order; } }; class KCODECS_NO_EXPORT EUCJPDistributionAnalysis : public CharDistributionAnalysis { public: EUCJPDistributionAnalysis(); protected: //for euc-JP encoding, we are interested // first byte range: 0xa0 -- 0xfe // second byte range: 0xa1 -- 0xfe //no validation needed here. State machine has done that int GetOrder(const char *str) override { if ((unsigned char)*str >= (unsigned char)0xa0) { return 94 * ((unsigned char)str[0] - (unsigned char)0xa1) + (unsigned char)str[1] - (unsigned char)0xa1; } else { return -1; } } }; } #endif //CharDistribution_h__ diff --git a/src/probers/ChineseGroupProber.cpp b/src/probers/ChineseGroupProber.cpp index 2839723..d098454 100644 --- a/src/probers/ChineseGroupProber.cpp +++ b/src/probers/ChineseGroupProber.cpp @@ -1,179 +1,161 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "ChineseGroupProber.h" #include "UnicodeGroupProber.h" #include "nsGB2312Prober.h" #include "nsBig5Prober.h" #include #include namespace kencodingprober { #ifdef DEBUG_PROBE static const char *const ProberName[] = { "Unicode", "GB18030", "Big5", }; #endif ChineseGroupProber::ChineseGroupProber() { mProbers[0] = new UnicodeGroupProber(); mProbers[1] = new nsGB18030Prober(); mProbers[2] = new nsBig5Prober(); Reset(); } ChineseGroupProber::~ChineseGroupProber() { for (unsigned int i = 0; i < CN_NUM_OF_PROBERS; i++) { delete mProbers[i]; } } const char *ChineseGroupProber::GetCharSetName() { if (mBestGuess == -1) { GetConfidence(); if (mBestGuess == -1) { mBestGuess = 1; // assume it's GB18030 } } return mProbers[mBestGuess]->GetCharSetName(); } void ChineseGroupProber::Reset(void) { mActiveNum = 0; for (unsigned int i = 0; i < CN_NUM_OF_PROBERS; i++) { if (mProbers[i]) { mProbers[i]->Reset(); mIsActive[i] = true; ++mActiveNum; } else { mIsActive[i] = false; } } mBestGuess = -1; mState = eDetecting; } nsProbingState ChineseGroupProber::HandleData(const char *aBuf, unsigned int aLen) { nsProbingState st; unsigned int i; //do filtering to reduce load to probers char *highbyteBuf; char *hptr; bool keepNext = true; //assume previous is not ascii, it will do no harm except add some noise hptr = highbyteBuf = (char *)malloc(aLen); if (!hptr) { return mState; } for (i = 0; i < aLen; ++i) { if (aBuf[i] & 0x80) { *hptr++ = aBuf[i]; keepNext = true; } else { //if previous is highbyte, keep this even it is a ASCII if (keepNext) { *hptr++ = aBuf[i]; keepNext = false; } } } for (i = 0; i < CN_NUM_OF_PROBERS; ++i) { if (!mIsActive[i]) { continue; } st = mProbers[i]->HandleData(highbyteBuf, hptr - highbyteBuf); if (st == eFoundIt) { mBestGuess = i; mState = eFoundIt; break; } else if (st == eNotMe) { mIsActive[i] = false; mActiveNum--; if (mActiveNum <= 0) { mState = eNotMe; break; } } } free(highbyteBuf); return mState; } float ChineseGroupProber::GetConfidence(void) { unsigned int i; float bestConf = 0.0, cf; switch (mState) { case eFoundIt: return (float)0.99; case eNotMe: return (float)0.01; default: for (i = 0; i < CN_NUM_OF_PROBERS; ++i) { if (!mIsActive[i]) { continue; } cf = mProbers[i]->GetConfidence(); if (bestConf < cf) { bestConf = cf; mBestGuess = i; } } } return bestConf; } #ifdef DEBUG_PROBE void ChineseGroupProber::DumpStatus() { unsigned int i; float cf; GetConfidence(); for (i = 0; i < CN_NUM_OF_PROBERS; i++) { if (!mIsActive[i]) { printf(" Chinese group inactive: [%s] (confidence is too low).\r\n", ProberName[i]); } else { cf = mProbers[i]->GetConfidence(); printf(" Chinese group %1.3f: [%s]\r\n", cf, ProberName[i]); } } } #endif } diff --git a/src/probers/ChineseGroupProber.h b/src/probers/ChineseGroupProber.h index c91f6b5..6408a78 100644 --- a/src/probers/ChineseGroupProber.h +++ b/src/probers/ChineseGroupProber.h @@ -1,61 +1,43 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef CHINESEGROUPPROBER_H #define CHINESEGROUPPROBER_H #include "nsCharSetProber.h" #define CN_NUM_OF_PROBERS 3 namespace kencodingprober { class KCODECS_NO_EXPORT ChineseGroupProber: public nsCharSetProber { public: ChineseGroupProber(); ~ChineseGroupProber() override; nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override; nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {} #ifdef DEBUG_PROBE void DumpStatus() override; #endif protected: nsProbingState mState; nsCharSetProber *mProbers[CN_NUM_OF_PROBERS]; bool mIsActive[CN_NUM_OF_PROBERS]; int mBestGuess; unsigned int mActiveNum; }; } #endif /* CHINESEGROUPPROBER_H */ diff --git a/src/probers/JapaneseGroupProber.cpp b/src/probers/JapaneseGroupProber.cpp index 5220067..5dc6d6c 100644 --- a/src/probers/JapaneseGroupProber.cpp +++ b/src/probers/JapaneseGroupProber.cpp @@ -1,179 +1,161 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "JapaneseGroupProber.h" #include "UnicodeGroupProber.h" #include "nsSJISProber.h" #include "nsEUCJPProber.h" #include #include namespace kencodingprober { #ifdef DEBUG_PROBE static const char *const ProberName[] = { "Unicode", "GB18030", "Big5", }; #endif JapaneseGroupProber::JapaneseGroupProber() { mProbers[0] = new UnicodeGroupProber(); mProbers[1] = new nsSJISProber(); mProbers[2] = new nsEUCJPProber(); Reset(); } JapaneseGroupProber::~JapaneseGroupProber() { for (unsigned int i = 0; i < JP_NUM_OF_PROBERS; i++) { delete mProbers[i]; } } const char *JapaneseGroupProber::GetCharSetName() { if (mBestGuess == -1) { GetConfidence(); if (mBestGuess == -1) { mBestGuess = 1; // assume it's GB18030 } } return mProbers[mBestGuess]->GetCharSetName(); } void JapaneseGroupProber::Reset(void) { mActiveNum = 0; for (unsigned int i = 0; i < JP_NUM_OF_PROBERS; i++) { if (mProbers[i]) { mProbers[i]->Reset(); mIsActive[i] = true; ++mActiveNum; } else { mIsActive[i] = false; } } mBestGuess = -1; mState = eDetecting; } nsProbingState JapaneseGroupProber::HandleData(const char *aBuf, unsigned int aLen) { nsProbingState st; unsigned int i; //do filtering to reduce load to probers char *highbyteBuf; char *hptr; bool keepNext = true; //assume previous is not ascii, it will do no harm except add some noise hptr = highbyteBuf = (char *)malloc(aLen); if (!hptr) { return mState; } for (i = 0; i < aLen; ++i) { if (aBuf[i] & 0x80) { *hptr++ = aBuf[i]; keepNext = true; } else { //if previous is highbyte, keep this even it is a ASCII if (keepNext) { *hptr++ = aBuf[i]; keepNext = false; } } } for (i = 0; i < JP_NUM_OF_PROBERS; ++i) { if (!mIsActive[i]) { continue; } st = mProbers[i]->HandleData(highbyteBuf, hptr - highbyteBuf); if (st == eFoundIt) { mBestGuess = i; mState = eFoundIt; break; } else if (st == eNotMe) { mIsActive[i] = false; mActiveNum--; if (mActiveNum <= 0) { mState = eNotMe; break; } } } free(highbyteBuf); return mState; } float JapaneseGroupProber::GetConfidence(void) { unsigned int i; float bestConf = 0.0, cf; switch (mState) { case eFoundIt: return (float)0.99; case eNotMe: return (float)0.01; default: for (i = 0; i < JP_NUM_OF_PROBERS; ++i) { if (!mIsActive[i]) { continue; } cf = mProbers[i]->GetConfidence(); if (bestConf < cf) { bestConf = cf; mBestGuess = i; } } } return bestConf; } #ifdef DEBUG_PROBE void JapaneseGroupProber::DumpStatus() { unsigned int i; float cf; GetConfidence(); for (i = 0; i < JP_NUM_OF_PROBERS; i++) { if (!mIsActive[i]) { printf(" Chinese group inactive: [%s] (confidence is too low).\r\n", ProberName[i]); } else { cf = mProbers[i]->GetConfidence(); printf(" Chinese group %1.3f: [%s]\r\n", cf, ProberName[i]); } } } #endif } diff --git a/src/probers/JapaneseGroupProber.h b/src/probers/JapaneseGroupProber.h index 7793da8..7a5e1b1 100644 --- a/src/probers/JapaneseGroupProber.h +++ b/src/probers/JapaneseGroupProber.h @@ -1,64 +1,46 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef JAPANESEGROUPPROBER_H #define JAPANESEGROUPPROBER_H #include "nsCharSetProber.h" #include "UnicodeGroupProber.h" #include "nsSJISProber.h" #include "nsEUCJPProber.h" #define JP_NUM_OF_PROBERS 3 namespace kencodingprober { class KCODECS_NO_EXPORT JapaneseGroupProber: public nsCharSetProber { public: JapaneseGroupProber(); ~JapaneseGroupProber() override; nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override; nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {} #ifdef DEBUG_PROBE void DumpStatus() override; #endif protected: nsProbingState mState; nsCharSetProber *mProbers[JP_NUM_OF_PROBERS]; bool mIsActive[JP_NUM_OF_PROBERS]; int mBestGuess; unsigned int mActiveNum; }; } #endif /* JAPANESEGROUPPROBER_H */ diff --git a/src/probers/JpCntx.cpp b/src/probers/JpCntx.cpp index 733ee19..a05d695 100644 --- a/src/probers/JpCntx.cpp +++ b/src/probers/JpCntx.cpp @@ -1,219 +1,201 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "JpCntx.h" namespace kencodingprober { //This is hiragana 2-char sequence table, the number in each cell represents its frequency category const char jp2CharContext[83][83] = { { 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,}, { 2, 4, 0, 4, 0, 3, 0, 4, 0, 3, 4, 4, 4, 2, 4, 3, 3, 4, 3, 2, 3, 3, 4, 2, 3, 3, 3, 2, 4, 1, 4, 3, 3, 1, 5, 4, 3, 4, 3, 4, 3, 5, 3, 0, 3, 5, 4, 2, 0, 3, 1, 0, 3, 3, 0, 3, 3, 0, 1, 1, 0, 4, 3, 0, 3, 3, 0, 4, 0, 2, 0, 3, 5, 5, 5, 5, 4, 0, 4, 1, 0, 3, 4,}, { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,}, { 0, 4, 0, 5, 0, 5, 0, 4, 0, 4, 5, 4, 4, 3, 5, 3, 5, 1, 5, 3, 4, 3, 4, 4, 3, 4, 3, 3, 4, 3, 5, 4, 4, 3, 5, 5, 3, 5, 5, 5, 3, 5, 5, 3, 4, 5, 5, 3, 1, 3, 2, 0, 3, 4, 0, 4, 2, 0, 4, 2, 1, 5, 3, 2, 3, 5, 0, 4, 0, 2, 0, 5, 4, 4, 5, 4, 5, 0, 4, 0, 0, 4, 4,}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, { 0, 3, 0, 4, 0, 3, 0, 3, 0, 4, 5, 4, 3, 3, 3, 3, 4, 3, 5, 4, 4, 3, 5, 4, 4, 3, 4, 3, 4, 4, 4, 4, 5, 3, 4, 4, 3, 4, 5, 5, 4, 5, 5, 1, 4, 5, 4, 3, 0, 3, 3, 1, 3, 3, 0, 4, 4, 0, 3, 3, 1, 5, 3, 3, 3, 5, 0, 4, 0, 3, 0, 4, 4, 3, 4, 3, 3, 0, 4, 1, 1, 3, 4,}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, { 0, 4, 0, 3, 0, 3, 0, 4, 0, 3, 4, 4, 3, 2, 2, 1, 2, 1, 3, 1, 3, 3, 3, 3, 3, 4, 3, 1, 3, 3, 5, 3, 3, 0, 4, 3, 0, 5, 4, 3, 3, 5, 4, 4, 3, 4, 4, 5, 0, 1, 2, 0, 1, 2, 0, 2, 2, 0, 1, 0, 0, 5, 2, 2, 1, 4, 0, 3, 0, 1, 0, 4, 4, 3, 5, 4, 3, 0, 2, 1, 0, 4, 3,}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, { 0, 3, 0, 5, 0, 4, 0, 2, 1, 4, 4, 2, 4, 1, 4, 2, 4, 2, 4, 3, 3, 3, 4, 3, 3, 3, 3, 1, 4, 2, 3, 3, 3, 1, 4, 4, 1, 1, 1, 4, 3, 3, 2, 0, 2, 4, 3, 2, 0, 3, 3, 0, 3, 1, 1, 0, 0, 0, 3, 3, 0, 4, 2, 2, 3, 4, 0, 4, 0, 3, 0, 4, 4, 5, 3, 4, 4, 0, 3, 0, 0, 1, 4,}, { 1, 4, 0, 4, 0, 4, 0, 4, 0, 3, 5, 4, 4, 3, 4, 3, 5, 4, 3, 3, 4, 3, 5, 4, 4, 4, 4, 3, 4, 2, 4, 3, 3, 1, 5, 4, 3, 2, 4, 5, 4, 5, 5, 4, 4, 5, 4, 4, 0, 3, 2, 2, 3, 3, 0, 4, 3, 1, 3, 2, 1, 4, 3, 3, 4, 5, 0, 3, 0, 2, 0, 4, 5, 5, 4, 5, 4, 0, 4, 0, 0, 5, 4,}, { 0, 5, 0, 5, 0, 4, 0, 3, 0, 4, 4, 3, 4, 3, 3, 3, 4, 0, 4, 4, 4, 3, 4, 3, 4, 3, 3, 1, 4, 2, 4, 3, 4, 0, 5, 4, 1, 4, 5, 4, 4, 5, 3, 2, 4, 3, 4, 3, 2, 4, 1, 3, 3, 3, 2, 3, 2, 0, 4, 3, 3, 4, 3, 3, 3, 4, 0, 4, 0, 3, 0, 4, 5, 4, 4, 4, 3, 0, 4, 1, 0, 1, 3,}, { 0, 3, 1, 4, 0, 3, 0, 2, 0, 3, 4, 4, 3, 1, 4, 2, 3, 3, 4, 3, 4, 3, 4, 3, 4, 4, 3, 2, 3, 1, 5, 4, 4, 1, 4, 4, 3, 5, 4, 4, 3, 5, 5, 4, 3, 4, 4, 3, 1, 2, 3, 1, 2, 2, 0, 3, 2, 0, 3, 1, 0, 5, 3, 3, 3, 4, 3, 3, 3, 3, 4, 4, 4, 4, 5, 4, 2, 0, 3, 3, 2, 4, 3,}, { 0, 2, 0, 3, 0, 1, 0, 1, 0, 0, 3, 2, 0, 0, 2, 0, 1, 0, 2, 1, 3, 3, 3, 1, 2, 3, 1, 0, 1, 0, 4, 2, 1, 1, 3, 3, 0, 4, 3, 3, 1, 4, 3, 3, 0, 3, 3, 2, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 4, 1, 0, 2, 3, 2, 2, 2, 1, 3, 3, 3, 4, 4, 3, 2, 0, 3, 1, 0, 3, 3,}, { 0, 4, 0, 4, 0, 3, 0, 3, 0, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 3, 4, 2, 4, 3, 4, 3, 3, 2, 4, 3, 4, 5, 4, 1, 4, 5, 3, 5, 4, 5, 3, 5, 4, 0, 3, 5, 5, 3, 1, 3, 3, 2, 2, 3, 0, 3, 4, 1, 3, 3, 2, 4, 3, 3, 3, 4, 0, 4, 0, 3, 0, 4, 5, 4, 4, 5, 3, 0, 4, 1, 0, 3, 4,}, { 0, 2, 0, 3, 0, 3, 0, 0, 0, 2, 2, 2, 1, 0, 1, 0, 0, 0, 3, 0, 3, 0, 3, 0, 1, 3, 1, 0, 3, 1, 3, 3, 3, 1, 3, 3, 3, 0, 1, 3, 1, 3, 4, 0, 0, 3, 1, 1, 0, 3, 2, 0, 0, 0, 0, 1, 3, 0, 1, 0, 0, 3, 3, 2, 0, 3, 0, 0, 0, 0, 0, 3, 4, 3, 4, 3, 3, 0, 3, 0, 0, 2, 3,}, { 2, 3, 0, 3, 0, 2, 0, 1, 0, 3, 3, 4, 3, 1, 3, 1, 1, 1, 3, 1, 4, 3, 4, 3, 3, 3, 0, 0, 3, 1, 5, 4, 3, 1, 4, 3, 2, 5, 5, 4, 4, 4, 4, 3, 3, 4, 4, 4, 0, 2, 1, 1, 3, 2, 0, 1, 2, 0, 0, 1, 0, 4, 1, 3, 3, 3, 0, 3, 0, 1, 0, 4, 4, 4, 5, 5, 3, 0, 2, 0, 0, 4, 4,}, { 0, 2, 0, 1, 0, 3, 1, 3, 0, 2, 3, 3, 3, 0, 3, 1, 0, 0, 3, 0, 3, 2, 3, 1, 3, 2, 1, 1, 0, 0, 4, 2, 1, 0, 2, 3, 1, 4, 3, 2, 0, 4, 4, 3, 1, 3, 1, 3, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 4, 1, 1, 1, 2, 0, 3, 0, 0, 0, 3, 4, 2, 4, 3, 2, 0, 1, 0, 0, 3, 3,}, { 0, 1, 0, 4, 0, 5, 0, 4, 0, 2, 4, 4, 2, 3, 3, 2, 3, 3, 5, 3, 3, 3, 4, 3, 4, 2, 3, 0, 4, 3, 3, 3, 4, 1, 4, 3, 2, 1, 5, 5, 3, 4, 5, 1, 3, 5, 4, 2, 0, 3, 3, 0, 1, 3, 0, 4, 2, 0, 1, 3, 1, 4, 3, 3, 3, 3, 0, 3, 0, 1, 0, 3, 4, 4, 4, 5, 5, 0, 3, 0, 1, 4, 5,}, { 0, 2, 0, 3, 0, 3, 0, 0, 0, 2, 3, 1, 3, 0, 4, 0, 1, 1, 3, 0, 3, 4, 3, 2, 3, 1, 0, 3, 3, 2, 3, 1, 3, 0, 2, 3, 0, 2, 1, 4, 1, 2, 2, 0, 0, 3, 3, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 2, 2, 0, 3, 2, 1, 3, 3, 0, 2, 0, 2, 0, 0, 3, 3, 1, 2, 4, 0, 3, 0, 2, 2, 3,}, { 2, 4, 0, 5, 0, 4, 0, 4, 0, 2, 4, 4, 4, 3, 4, 3, 3, 3, 1, 2, 4, 3, 4, 3, 4, 4, 5, 0, 3, 3, 3, 3, 2, 0, 4, 3, 1, 4, 3, 4, 1, 4, 4, 3, 3, 4, 4, 3, 1, 2, 3, 0, 4, 2, 0, 4, 1, 0, 3, 3, 0, 4, 3, 3, 3, 4, 0, 4, 0, 2, 0, 3, 5, 3, 4, 5, 2, 0, 3, 0, 0, 4, 5,}, { 0, 3, 0, 4, 0, 1, 0, 1, 0, 1, 3, 2, 2, 1, 3, 0, 3, 0, 2, 0, 2, 0, 3, 0, 2, 0, 0, 0, 1, 0, 1, 1, 0, 0, 3, 1, 0, 0, 0, 4, 0, 3, 1, 0, 2, 1, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 3, 1, 0, 3, 0, 0, 0, 1, 4, 4, 4, 3, 0, 0, 4, 0, 0, 1, 4,}, { 1, 4, 1, 5, 0, 3, 0, 3, 0, 4, 5, 4, 4, 3, 5, 3, 3, 4, 4, 3, 4, 1, 3, 3, 3, 3, 2, 1, 4, 1, 5, 4, 3, 1, 4, 4, 3, 5, 4, 4, 3, 5, 4, 3, 3, 4, 4, 4, 0, 3, 3, 1, 2, 3, 0, 3, 1, 0, 3, 3, 0, 5, 4, 4, 4, 4, 4, 4, 3, 3, 5, 4, 4, 3, 3, 5, 4, 0, 3, 2, 0, 4, 4,}, { 0, 2, 0, 3, 0, 1, 0, 0, 0, 1, 3, 3, 3, 2, 4, 1, 3, 0, 3, 1, 3, 0, 2, 2, 1, 1, 0, 0, 2, 0, 4, 3, 1, 0, 4, 3, 0, 4, 4, 4, 1, 4, 3, 1, 1, 3, 3, 1, 0, 2, 0, 0, 1, 3, 0, 0, 0, 0, 2, 0, 0, 4, 3, 2, 4, 3, 5, 4, 3, 3, 3, 4, 3, 3, 4, 3, 3, 0, 2, 1, 0, 3, 3,}, { 0, 2, 0, 4, 0, 3, 0, 2, 0, 2, 5, 5, 3, 4, 4, 4, 4, 1, 4, 3, 3, 0, 4, 3, 4, 3, 1, 3, 3, 2, 4, 3, 0, 3, 4, 3, 0, 3, 4, 4, 2, 4, 4, 0, 4, 5, 3, 3, 2, 2, 1, 1, 1, 2, 0, 1, 5, 0, 3, 3, 2, 4, 3, 3, 3, 4, 0, 3, 0, 2, 0, 4, 4, 3, 5, 5, 0, 0, 3, 0, 2, 3, 3,}, { 0, 3, 0, 4, 0, 3, 0, 1, 0, 3, 4, 3, 3, 1, 3, 3, 3, 0, 3, 1, 3, 0, 4, 3, 3, 1, 1, 0, 3, 0, 3, 3, 0, 0, 4, 4, 0, 1, 5, 4, 3, 3, 5, 0, 3, 3, 4, 3, 0, 2, 0, 1, 1, 1, 0, 1, 3, 0, 1, 2, 1, 3, 3, 2, 3, 3, 0, 3, 0, 1, 0, 1, 3, 3, 4, 4, 1, 0, 1, 2, 2, 1, 3,}, { 0, 1, 0, 4, 0, 4, 0, 3, 0, 1, 3, 3, 3, 2, 3, 1, 1, 0, 3, 0, 3, 3, 4, 3, 2, 4, 2, 0, 1, 0, 4, 3, 2, 0, 4, 3, 0, 5, 3, 3, 2, 4, 4, 4, 3, 3, 3, 4, 0, 1, 3, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 2, 3, 3, 3, 0, 3, 0, 0, 0, 4, 4, 4, 5, 3, 2, 0, 3, 3, 0, 3, 5,}, { 0, 2, 0, 3, 0, 0, 0, 3, 0, 1, 3, 0, 2, 0, 0, 0, 1, 0, 3, 1, 1, 3, 3, 0, 0, 3, 0, 0, 3, 0, 2, 3, 1, 0, 3, 1, 0, 3, 3, 2, 0, 4, 2, 2, 0, 2, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 1, 0, 1, 0, 0, 0, 1, 3, 1, 2, 0, 0, 0, 1, 0, 0, 1, 4,}, { 0, 3, 0, 3, 0, 5, 0, 1, 0, 2, 4, 3, 1, 3, 3, 2, 1, 1, 5, 2, 1, 0, 5, 1, 2, 0, 0, 0, 3, 3, 2, 2, 3, 2, 4, 3, 0, 0, 3, 3, 1, 3, 3, 0, 2, 5, 3, 4, 0, 3, 3, 0, 1, 2, 0, 2, 2, 0, 3, 2, 0, 2, 2, 3, 3, 3, 0, 2, 0, 1, 0, 3, 4, 4, 2, 5, 4, 0, 3, 0, 0, 3, 5,}, { 0, 3, 0, 3, 0, 3, 0, 1, 0, 3, 3, 3, 3, 0, 3, 0, 2, 0, 2, 1, 1, 0, 2, 0, 1, 0, 0, 0, 2, 1, 0, 0, 1, 0, 3, 2, 0, 0, 3, 3, 1, 2, 3, 1, 0, 3, 3, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 3, 1, 2, 3, 0, 3, 0, 1, 0, 3, 2, 1, 0, 4, 3, 0, 1, 1, 0, 3, 3,}, { 0, 4, 0, 5, 0, 3, 0, 3, 0, 4, 5, 5, 4, 3, 5, 3, 4, 3, 5, 3, 3, 2, 5, 3, 4, 4, 4, 3, 4, 3, 4, 5, 5, 3, 4, 4, 3, 4, 4, 5, 4, 4, 4, 3, 4, 5, 5, 4, 2, 3, 4, 2, 3, 4, 0, 3, 3, 1, 4, 3, 2, 4, 3, 3, 5, 5, 0, 3, 0, 3, 0, 5, 5, 5, 5, 4, 4, 0, 4, 0, 1, 4, 4,}, { 0, 4, 0, 4, 0, 3, 0, 3, 0, 3, 5, 4, 4, 2, 3, 2, 5, 1, 3, 2, 5, 1, 4, 2, 3, 2, 3, 3, 4, 3, 3, 3, 3, 2, 5, 4, 1, 3, 3, 5, 3, 4, 4, 0, 4, 4, 3, 1, 1, 3, 1, 0, 2, 3, 0, 2, 3, 0, 3, 0, 0, 4, 3, 1, 3, 4, 0, 3, 0, 2, 0, 4, 4, 4, 3, 4, 5, 0, 4, 0, 0, 3, 4,}, { 0, 3, 0, 3, 0, 3, 1, 2, 0, 3, 4, 4, 3, 3, 3, 0, 2, 2, 4, 3, 3, 1, 3, 3, 3, 1, 1, 0, 3, 1, 4, 3, 2, 3, 4, 4, 2, 4, 4, 4, 3, 4, 4, 3, 2, 4, 4, 3, 1, 3, 3, 1, 3, 3, 0, 4, 1, 0, 2, 2, 1, 4, 3, 2, 3, 3, 5, 4, 3, 3, 5, 4, 4, 3, 3, 0, 4, 0, 3, 2, 2, 4, 4,}, { 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 2, 1, 3, 0, 0, 0, 0, 0, 2, 0, 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 1, 0, 1, 1, 3, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 0, 3, 4, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,}, { 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 4, 1, 4, 0, 3, 0, 4, 0, 3, 0, 4, 0, 3, 0, 3, 0, 4, 1, 5, 1, 4, 0, 0, 3, 0, 5, 0, 5, 2, 0, 1, 0, 0, 0, 2, 1, 4, 0, 1, 3, 0, 0, 3, 0, 0, 3, 1, 1, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,}, { 1, 4, 0, 5, 0, 3, 0, 2, 0, 3, 5, 4, 4, 3, 4, 3, 5, 3, 4, 3, 3, 0, 4, 3, 3, 3, 3, 3, 3, 2, 4, 4, 3, 1, 3, 4, 4, 5, 4, 4, 3, 4, 4, 1, 3, 5, 4, 3, 3, 3, 1, 2, 2, 3, 3, 1, 3, 1, 3, 3, 3, 5, 3, 3, 4, 5, 0, 3, 0, 3, 0, 3, 4, 3, 4, 4, 3, 0, 3, 0, 2, 4, 3,}, { 0, 1, 0, 4, 0, 0, 0, 0, 0, 1, 4, 0, 4, 1, 4, 2, 4, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 3, 1, 1, 1, 0, 3, 0, 0, 0, 1, 2, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 3, 2, 0, 2, 2, 0, 1, 0, 0, 0, 2, 3, 2, 3, 3, 0, 0, 0, 0, 2, 1, 0,}, { 0, 5, 1, 5, 0, 3, 0, 3, 0, 5, 4, 4, 5, 1, 5, 3, 3, 0, 4, 3, 4, 3, 5, 3, 4, 3, 3, 2, 4, 3, 4, 3, 3, 0, 3, 3, 1, 4, 4, 3, 4, 4, 4, 3, 4, 5, 5, 3, 2, 3, 1, 1, 3, 3, 1, 3, 1, 1, 3, 3, 2, 4, 5, 3, 3, 5, 0, 4, 0, 3, 0, 4, 4, 3, 5, 3, 3, 0, 3, 4, 0, 4, 3,}, { 0, 5, 0, 5, 0, 3, 0, 2, 0, 4, 4, 3, 5, 2, 4, 3, 3, 3, 4, 4, 4, 3, 5, 3, 5, 3, 3, 1, 4, 0, 4, 3, 3, 0, 3, 3, 0, 4, 4, 4, 4, 5, 4, 3, 3, 5, 5, 3, 2, 3, 1, 2, 3, 2, 0, 1, 0, 0, 3, 2, 2, 4, 4, 3, 1, 5, 0, 4, 0, 3, 0, 4, 3, 1, 3, 2, 1, 0, 3, 3, 0, 3, 3,}, { 0, 4, 0, 5, 0, 5, 0, 4, 0, 4, 5, 5, 5, 3, 4, 3, 3, 2, 5, 4, 4, 3, 5, 3, 5, 3, 4, 0, 4, 3, 4, 4, 3, 2, 4, 4, 3, 4, 5, 4, 4, 5, 5, 0, 3, 5, 5, 4, 1, 3, 3, 2, 3, 3, 1, 3, 1, 0, 4, 3, 1, 4, 4, 3, 4, 5, 0, 4, 0, 2, 0, 4, 3, 4, 4, 3, 3, 0, 4, 0, 0, 5, 5,}, { 0, 4, 0, 4, 0, 5, 0, 1, 1, 3, 3, 4, 4, 3, 4, 1, 3, 0, 5, 1, 3, 0, 3, 1, 3, 1, 1, 0, 3, 0, 3, 3, 4, 0, 4, 3, 0, 4, 4, 4, 3, 4, 4, 0, 3, 5, 4, 1, 0, 3, 0, 0, 2, 3, 0, 3, 1, 0, 3, 1, 0, 3, 2, 1, 3, 5, 0, 3, 0, 1, 0, 3, 2, 3, 3, 4, 4, 0, 2, 2, 0, 4, 4,}, { 2, 4, 0, 5, 0, 4, 0, 3, 0, 4, 5, 5, 4, 3, 5, 3, 5, 3, 5, 3, 5, 2, 5, 3, 4, 3, 3, 4, 3, 4, 5, 3, 2, 1, 5, 4, 3, 2, 3, 4, 5, 3, 4, 1, 2, 5, 4, 3, 0, 3, 3, 0, 3, 2, 0, 2, 3, 0, 4, 1, 0, 3, 4, 3, 3, 5, 0, 3, 0, 1, 0, 4, 5, 5, 5, 4, 3, 0, 4, 2, 0, 3, 5,}, { 0, 5, 0, 4, 0, 4, 0, 2, 0, 5, 4, 3, 4, 3, 4, 3, 3, 3, 4, 3, 4, 2, 5, 3, 5, 3, 4, 1, 4, 3, 4, 4, 4, 0, 3, 5, 0, 4, 4, 4, 4, 5, 3, 1, 3, 4, 5, 3, 3, 3, 3, 3, 3, 3, 0, 2, 2, 0, 3, 3, 2, 4, 3, 3, 3, 5, 3, 4, 1, 3, 3, 5, 3, 2, 0, 0, 0, 0, 4, 3, 1, 3, 3,}, { 0, 1, 0, 3, 0, 3, 0, 1, 0, 1, 3, 3, 3, 2, 3, 3, 3, 0, 3, 0, 0, 0, 3, 1, 3, 0, 0, 0, 2, 2, 2, 3, 0, 0, 3, 2, 0, 1, 2, 4, 1, 3, 3, 0, 0, 3, 3, 3, 0, 1, 0, 0, 2, 1, 0, 0, 3, 0, 3, 1, 0, 3, 0, 0, 1, 3, 0, 2, 0, 1, 0, 3, 3, 1, 3, 3, 0, 0, 1, 1, 0, 3, 3,}, { 0, 2, 0, 3, 0, 2, 1, 4, 0, 2, 2, 3, 1, 1, 3, 1, 1, 0, 2, 0, 3, 1, 2, 3, 1, 3, 0, 0, 1, 0, 4, 3, 2, 3, 3, 3, 1, 4, 2, 3, 3, 3, 3, 1, 0, 3, 1, 4, 0, 1, 1, 0, 1, 2, 0, 1, 1, 0, 1, 1, 0, 3, 1, 3, 2, 2, 0, 1, 0, 0, 0, 2, 3, 3, 3, 1, 0, 0, 0, 0, 0, 2, 3,}, { 0, 5, 0, 4, 0, 5, 0, 2, 0, 4, 5, 5, 3, 3, 4, 3, 3, 1, 5, 4, 4, 2, 4, 4, 4, 3, 4, 2, 4, 3, 5, 5, 4, 3, 3, 4, 3, 3, 5, 5, 4, 5, 5, 1, 3, 4, 5, 3, 1, 4, 3, 1, 3, 3, 0, 3, 3, 1, 4, 3, 1, 4, 5, 3, 3, 5, 0, 4, 0, 3, 0, 5, 3, 3, 1, 4, 3, 0, 4, 0, 1, 5, 3,}, { 0, 5, 0, 5, 0, 4, 0, 2, 0, 4, 4, 3, 4, 3, 3, 3, 3, 3, 5, 4, 4, 4, 4, 4, 4, 5, 3, 3, 5, 2, 4, 4, 4, 3, 4, 4, 3, 3, 4, 4, 5, 5, 3, 3, 4, 3, 4, 3, 3, 4, 3, 3, 3, 3, 1, 2, 2, 1, 4, 3, 3, 5, 4, 4, 3, 4, 0, 4, 0, 3, 0, 4, 4, 4, 4, 4, 1, 0, 4, 2, 0, 2, 4,}, { 0, 4, 0, 4, 0, 3, 0, 1, 0, 3, 5, 2, 3, 0, 3, 0, 2, 1, 4, 2, 3, 3, 4, 1, 4, 3, 3, 2, 4, 1, 3, 3, 3, 0, 3, 3, 0, 0, 3, 3, 3, 5, 3, 3, 3, 3, 3, 2, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 1, 0, 0, 3, 1, 2, 2, 3, 0, 3, 0, 2, 0, 4, 4, 3, 3, 4, 1, 0, 3, 0, 0, 2, 4,}, { 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 3, 1, 3, 0, 3, 2, 0, 0, 0, 1, 0, 3, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 4, 0, 2, 0, 0, 0, 0, 0, 0, 2,}, { 0, 2, 1, 3, 0, 2, 0, 2, 0, 3, 3, 3, 3, 1, 3, 1, 3, 3, 3, 3, 3, 3, 4, 2, 2, 1, 2, 1, 4, 0, 4, 3, 1, 3, 3, 3, 2, 4, 3, 5, 4, 3, 3, 3, 3, 3, 3, 3, 0, 1, 3, 0, 2, 0, 0, 1, 0, 0, 1, 0, 0, 4, 2, 0, 2, 3, 0, 3, 3, 0, 3, 3, 4, 2, 3, 1, 4, 0, 1, 2, 0, 2, 3,}, { 0, 3, 0, 3, 0, 1, 0, 3, 0, 2, 3, 3, 3, 0, 3, 1, 2, 0, 3, 3, 2, 3, 3, 2, 3, 2, 3, 1, 3, 0, 4, 3, 2, 0, 3, 3, 1, 4, 3, 3, 2, 3, 4, 3, 1, 3, 3, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 4, 1, 1, 0, 3, 0, 3, 1, 0, 2, 3, 3, 3, 3, 3, 1, 0, 0, 2, 0, 3, 3,}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 3, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3,}, { 0, 2, 0, 3, 1, 3, 0, 3, 0, 2, 3, 3, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 1, 3, 0, 2, 3, 1, 1, 4, 3, 3, 2, 3, 3, 1, 2, 2, 4, 1, 3, 3, 0, 1, 4, 2, 3, 0, 1, 3, 0, 3, 0, 0, 1, 3, 0, 2, 0, 0, 3, 3, 2, 1, 3, 0, 3, 0, 2, 0, 3, 4, 4, 4, 3, 1, 0, 3, 0, 0, 3, 3,}, { 0, 2, 0, 1, 0, 2, 0, 0, 0, 1, 3, 2, 2, 1, 3, 0, 1, 1, 3, 0, 3, 2, 3, 1, 2, 0, 2, 0, 1, 1, 3, 3, 3, 0, 3, 3, 1, 1, 2, 3, 2, 3, 3, 1, 2, 3, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 2, 1, 2, 1, 3, 0, 3, 0, 0, 0, 3, 4, 4, 4, 3, 2, 0, 2, 0, 0, 2, 4,}, { 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 3,}, { 0, 3, 0, 3, 0, 2, 0, 3, 0, 3, 3, 3, 2, 3, 2, 2, 2, 0, 3, 1, 3, 3, 3, 2, 3, 3, 0, 0, 3, 0, 3, 2, 2, 0, 2, 3, 1, 4, 3, 4, 3, 3, 2, 3, 1, 5, 4, 4, 0, 3, 1, 2, 1, 3, 0, 3, 1, 1, 2, 0, 2, 3, 1, 3, 1, 3, 0, 3, 0, 1, 0, 3, 3, 4, 4, 2, 1, 0, 2, 1, 0, 2, 4,}, { 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 4, 2, 5, 1, 4, 0, 2, 0, 2, 1, 3, 1, 4, 0, 2, 1, 0, 0, 2, 1, 4, 1, 1, 0, 3, 3, 0, 5, 1, 3, 2, 3, 3, 1, 0, 3, 2, 3, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 4, 0, 1, 0, 3, 0, 2, 0, 1, 0, 3, 3, 3, 4, 3, 3, 0, 0, 0, 0, 2, 3,}, { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 3,}, { 0, 1, 0, 3, 0, 4, 0, 3, 0, 2, 4, 3, 1, 0, 3, 2, 2, 1, 3, 1, 2, 2, 3, 1, 1, 1, 2, 1, 3, 0, 1, 2, 0, 1, 3, 2, 1, 3, 0, 5, 5, 1, 0, 0, 1, 3, 2, 1, 0, 3, 0, 0, 1, 0, 0, 0, 0, 0, 3, 4, 0, 1, 1, 1, 3, 2, 0, 2, 0, 1, 0, 2, 3, 3, 1, 2, 3, 0, 1, 0, 1, 0, 4,}, { 0, 0, 0, 1, 0, 3, 0, 3, 0, 2, 2, 1, 0, 0, 4, 0, 3, 0, 3, 1, 3, 0, 3, 0, 3, 0, 1, 0, 3, 0, 3, 1, 3, 0, 3, 3, 0, 0, 1, 2, 1, 1, 1, 0, 1, 2, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 2, 0, 0, 2, 0, 0, 0, 0, 2, 3, 3, 3, 3, 0, 0, 0, 0, 1, 4,}, { 0, 0, 0, 3, 0, 3, 0, 0, 0, 0, 3, 1, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 2, 0, 2, 3, 0, 0, 2, 2, 3, 1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 2, 3,}, { 2, 4, 0, 5, 0, 5, 0, 4, 0, 3, 4, 3, 3, 3, 4, 3, 3, 3, 4, 3, 4, 4, 5, 4, 5, 5, 5, 2, 3, 0, 5, 5, 4, 1, 5, 4, 3, 1, 5, 4, 3, 4, 4, 3, 3, 4, 3, 3, 0, 3, 2, 0, 2, 3, 0, 3, 0, 0, 3, 3, 0, 5, 3, 2, 3, 3, 0, 3, 0, 3, 0, 3, 4, 5, 4, 5, 3, 0, 4, 3, 0, 3, 4,}, { 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 3, 4, 3, 2, 3, 2, 3, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 2, 4, 3, 3, 1, 3, 4, 3, 4, 4, 4, 3, 4, 4, 3, 2, 4, 4, 1, 0, 2, 0, 0, 1, 1, 0, 2, 0, 0, 3, 1, 0, 5, 3, 2, 1, 3, 0, 3, 0, 1, 2, 4, 3, 2, 4, 3, 3, 0, 3, 2, 0, 4, 4,}, { 0, 3, 0, 3, 0, 1, 0, 0, 0, 1, 4, 3, 3, 2, 3, 1, 3, 1, 4, 2, 3, 2, 4, 2, 3, 4, 3, 0, 2, 2, 3, 3, 3, 0, 3, 3, 3, 0, 3, 4, 1, 3, 3, 0, 3, 4, 3, 3, 0, 1, 1, 0, 1, 0, 0, 0, 4, 0, 3, 0, 0, 3, 1, 2, 1, 3, 0, 4, 0, 1, 0, 4, 3, 3, 4, 3, 3, 0, 2, 0, 0, 3, 3,}, { 0, 3, 0, 4, 0, 1, 0, 3, 0, 3, 4, 3, 3, 0, 3, 3, 3, 1, 3, 1, 3, 3, 4, 3, 3, 3, 0, 0, 3, 1, 5, 3, 3, 1, 3, 3, 2, 5, 4, 3, 3, 4, 5, 3, 2, 5, 3, 4, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 1, 1, 0, 4, 2, 2, 1, 3, 0, 3, 0, 2, 0, 4, 4, 3, 5, 3, 2, 0, 1, 1, 0, 3, 4,}, { 0, 5, 0, 4, 0, 5, 0, 2, 0, 4, 4, 3, 3, 2, 3, 3, 3, 1, 4, 3, 4, 1, 5, 3, 4, 3, 4, 0, 4, 2, 4, 3, 4, 1, 5, 4, 0, 4, 4, 4, 4, 5, 4, 1, 3, 5, 4, 2, 1, 4, 1, 1, 3, 2, 0, 3, 1, 0, 3, 2, 1, 4, 3, 3, 3, 4, 0, 4, 0, 3, 0, 4, 4, 4, 3, 3, 3, 0, 4, 2, 0, 3, 4,}, { 1, 4, 0, 4, 0, 3, 0, 1, 0, 3, 3, 3, 1, 1, 3, 3, 2, 2, 3, 3, 1, 0, 3, 2, 2, 1, 2, 0, 3, 1, 2, 1, 2, 0, 3, 2, 0, 2, 2, 3, 3, 4, 3, 0, 3, 3, 1, 2, 0, 1, 1, 3, 1, 2, 0, 0, 3, 0, 1, 1, 0, 3, 2, 2, 3, 3, 0, 3, 0, 0, 0, 2, 3, 3, 4, 3, 3, 0, 1, 0, 0, 1, 4,}, { 0, 4, 0, 4, 0, 4, 0, 0, 0, 3, 4, 4, 3, 1, 4, 2, 3, 2, 3, 3, 3, 1, 4, 3, 4, 0, 3, 0, 4, 2, 3, 3, 2, 2, 5, 4, 2, 1, 3, 4, 3, 4, 3, 1, 3, 3, 4, 2, 0, 2, 1, 0, 3, 3, 0, 0, 2, 0, 3, 1, 0, 4, 4, 3, 4, 3, 0, 4, 0, 1, 0, 2, 4, 4, 4, 4, 4, 0, 3, 2, 0, 3, 3,}, { 0, 0, 0, 1, 0, 4, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2,}, { 0, 2, 0, 3, 0, 4, 0, 4, 0, 1, 3, 3, 3, 0, 4, 0, 2, 1, 2, 1, 1, 1, 2, 0, 3, 1, 1, 0, 1, 0, 3, 1, 0, 0, 3, 3, 2, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 2, 2, 0, 3, 1, 0, 0, 1, 0, 1, 1, 0, 1, 2, 0, 3, 0, 0, 0, 0, 1, 0, 0, 3, 3, 4, 3, 1, 0, 1, 0, 3, 0, 2,}, { 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 1, 0, 2, 0, 3, 1, 0, 1, 3, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 4, 0, 0, 0, 2, 3, 0, 1, 4, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 0, 3,}, { 0, 2, 0, 5, 0, 5, 0, 1, 0, 2, 4, 3, 3, 2, 5, 1, 3, 2, 3, 3, 3, 0, 4, 1, 2, 0, 3, 0, 4, 0, 2, 2, 1, 1, 5, 3, 0, 0, 1, 4, 2, 3, 2, 0, 3, 3, 3, 2, 0, 2, 4, 1, 1, 2, 0, 1, 1, 0, 3, 1, 0, 1, 3, 1, 2, 3, 0, 2, 0, 0, 0, 1, 3, 5, 4, 4, 4, 0, 3, 0, 0, 1, 3,}, { 0, 4, 0, 5, 0, 4, 0, 4, 0, 4, 5, 4, 3, 3, 4, 3, 3, 3, 4, 3, 4, 4, 5, 3, 4, 5, 4, 2, 4, 2, 3, 4, 3, 1, 4, 4, 1, 3, 5, 4, 4, 5, 5, 4, 4, 5, 5, 5, 2, 3, 3, 1, 4, 3, 1, 3, 3, 0, 3, 3, 1, 4, 3, 4, 4, 4, 0, 3, 0, 4, 0, 3, 3, 4, 4, 5, 0, 0, 4, 3, 0, 4, 5,}, { 0, 4, 0, 4, 0, 3, 0, 3, 0, 3, 4, 4, 4, 3, 3, 2, 4, 3, 4, 3, 4, 3, 5, 3, 4, 3, 2, 1, 4, 2, 4, 4, 3, 1, 3, 4, 2, 4, 5, 5, 3, 4, 5, 4, 1, 5, 4, 3, 0, 3, 2, 2, 3, 2, 1, 3, 1, 0, 3, 3, 3, 5, 3, 3, 3, 5, 4, 4, 2, 3, 3, 4, 3, 3, 3, 2, 1, 0, 3, 2, 1, 4, 3,}, { 0, 4, 0, 5, 0, 4, 0, 3, 0, 3, 5, 5, 3, 2, 4, 3, 4, 0, 5, 4, 4, 1, 4, 4, 4, 3, 3, 3, 4, 3, 5, 5, 2, 3, 3, 4, 1, 2, 5, 5, 3, 5, 5, 2, 3, 5, 5, 4, 0, 3, 2, 0, 3, 3, 1, 1, 5, 1, 4, 1, 0, 4, 3, 2, 3, 5, 0, 4, 0, 3, 0, 5, 4, 3, 4, 3, 0, 0, 4, 1, 0, 4, 4,}, { 1, 3, 0, 4, 0, 2, 0, 2, 0, 2, 5, 5, 3, 3, 3, 3, 3, 0, 4, 2, 3, 4, 4, 4, 3, 4, 0, 0, 3, 4, 5, 4, 3, 3, 3, 3, 2, 5, 5, 4, 5, 5, 5, 4, 3, 5, 5, 5, 1, 3, 1, 0, 1, 0, 0, 3, 2, 0, 4, 2, 0, 5, 2, 3, 2, 4, 1, 3, 0, 3, 0, 4, 5, 4, 5, 4, 3, 0, 4, 2, 0, 5, 4,}, { 0, 3, 0, 4, 0, 5, 0, 3, 0, 3, 4, 4, 3, 2, 3, 2, 3, 3, 3, 3, 3, 2, 4, 3, 3, 2, 2, 0, 3, 3, 3, 3, 3, 1, 3, 3, 3, 0, 4, 4, 3, 4, 4, 1, 1, 4, 4, 2, 0, 3, 1, 0, 1, 1, 0, 4, 1, 0, 2, 3, 1, 3, 3, 1, 3, 4, 0, 3, 0, 1, 0, 3, 1, 3, 0, 0, 1, 0, 2, 0, 0, 4, 4,}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, { 0, 3, 0, 3, 0, 2, 0, 3, 0, 1, 5, 4, 3, 3, 3, 1, 4, 2, 1, 2, 3, 4, 4, 2, 4, 4, 5, 0, 3, 1, 4, 3, 4, 0, 4, 3, 3, 3, 2, 3, 2, 5, 3, 4, 3, 2, 2, 3, 0, 0, 3, 0, 2, 1, 0, 1, 2, 0, 0, 0, 0, 2, 1, 1, 3, 1, 0, 2, 0, 4, 0, 3, 4, 4, 4, 5, 2, 0, 2, 0, 0, 1, 3,}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 4, 2, 1, 1, 0, 1, 0, 3, 2, 0, 0, 3, 1, 1, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, 1, 4, 0, 4, 2, 1, 0, 0, 0, 0, 0, 1,}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 2, 0, 2, 1, 0, 0, 1, 2, 1, 0, 1, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2,}, { 0, 4, 0, 4, 0, 4, 0, 3, 0, 4, 4, 3, 4, 2, 4, 3, 2, 0, 4, 4, 4, 3, 5, 3, 5, 3, 3, 2, 4, 2, 4, 3, 4, 3, 1, 4, 0, 2, 3, 4, 4, 4, 3, 3, 3, 4, 4, 4, 3, 4, 1, 3, 4, 3, 2, 1, 2, 1, 3, 3, 3, 4, 4, 3, 3, 5, 0, 4, 0, 3, 0, 4, 3, 3, 3, 2, 1, 0, 3, 0, 0, 3, 3,}, { 0, 4, 0, 3, 0, 3, 0, 3, 0, 3, 5, 5, 3, 3, 3, 3, 4, 3, 4, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 4, 3, 5, 3, 3, 1, 3, 2, 4, 5, 5, 5, 5, 4, 3, 4, 5, 5, 3, 2, 2, 3, 3, 3, 3, 2, 3, 3, 1, 2, 3, 2, 4, 3, 3, 3, 4, 0, 4, 0, 2, 0, 4, 3, 2, 2, 1, 2, 0, 3, 0, 0, 4, 1,}, }; #define MINIMUM_DATA_THRESHOLD 4 void JapaneseContextAnalysis::HandleData(const char *aBuf, unsigned int aLen) { unsigned int charLen; int order; unsigned int i; if (mDone) { return; } //The buffer we got is byte oriented, and a character may span in more than one //buffers. In case the last one or two byte in last buffer is not complete, we //record how many byte needed to complete that character and skip these bytes here. //We can choose to record those bytes as well and analyze the character once it //is complete, but since a character will not make much difference, by simply skipping //this character will simply our logic and improve performance. for (i = mNeedToSkipCharNum; i < aLen;) { order = GetOrder(aBuf + i, &charLen); i += charLen; if (i > aLen) { mNeedToSkipCharNum = i - aLen; mLastCharOrder = -1; } else { if (order != -1 && mLastCharOrder != -1) { mTotalRel ++; if (mTotalRel > MAX_REL_THRESHOLD) { mDone = true; break; } mRelSample[(int)jp2CharContext[mLastCharOrder][order]]++; } mLastCharOrder = order; } } return; } void JapaneseContextAnalysis::Reset(void) { mTotalRel = 0; for (unsigned int i = 0; i < NUM_OF_CATEGORY; i++) { mRelSample[i] = 0; } mNeedToSkipCharNum = 0; mLastCharOrder = -1; mDone = false; } #define DONT_KNOW (float)-1 float JapaneseContextAnalysis::GetConfidence() { //This is just one way to calculate confidence. It works well for me. if (mTotalRel > MINIMUM_DATA_THRESHOLD) { return ((float)(mTotalRel - mRelSample[0])) / mTotalRel; } else { return (float)DONT_KNOW; } } int SJISContextAnalysis::GetOrder(const char *str, unsigned int *charLen) { //find out current char's byte length if (((unsigned char)*str >= (unsigned char)0x81 && (unsigned char)*str <= (unsigned char)0x9f) || ((unsigned char)*str >= (unsigned char)0xe0 && (unsigned char)*str <= (unsigned char)0xfc)) { *charLen = 2; } else { *charLen = 1; } //return its order if it is hiragana if (*str == '\202' && (unsigned char) * (str + 1) >= (unsigned char)0x9f && (unsigned char) * (str + 1) <= (unsigned char)0xf1) { return (unsigned char) * (str + 1) - (unsigned char)0x9f; } return -1; } int EUCJPContextAnalysis::GetOrder(const char *str, unsigned int *charLen) { //find out current char's byte length if ((unsigned char)*str == (unsigned char)0x8e || ((unsigned char)*str >= (unsigned char)0xa1 && (unsigned char)*str <= (unsigned char)0xfe)) { *charLen = 2; } else if ((unsigned char)*str == (unsigned char)0x8f) { *charLen = 3; } else { *charLen = 1; } //return its order if it is hiragana if ((unsigned char)*str == (unsigned char)0xa4 && (unsigned char) * (str + 1) >= (unsigned char)0xa1 && (unsigned char) * (str + 1) <= (unsigned char)0xf3) { return (unsigned char) * (str + 1) - (unsigned char)0xa1; } return -1; } } diff --git a/src/probers/JpCntx.h b/src/probers/JpCntx.h index cf8963e..6915f24 100644 --- a/src/probers/JpCntx.h +++ b/src/probers/JpCntx.h @@ -1,138 +1,120 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef __JPCNTX_H__ #define __JPCNTX_H__ #include "kcodecs_export.h" #include #define NUM_OF_CATEGORY 6 #define ENOUGH_REL_THRESHOLD 100 #define MAX_REL_THRESHOLD 1000 namespace kencodingprober { //hiragana frequency category table extern const char jp2CharContext[83][83]; class KCODECS_NO_EXPORT JapaneseContextAnalysis { public: JapaneseContextAnalysis() { Reset(); } virtual ~JapaneseContextAnalysis() {} void HandleData(const char *aBuf, unsigned int aLen); void HandleOneChar(const char *aStr, unsigned int aCharLen) { int order; //if we received enough data, stop here if (mTotalRel > MAX_REL_THRESHOLD) { mDone = true; } if (mDone) { return; } //Only 2-bytes characters are of our interest order = (aCharLen == 2) ? GetOrder(aStr) : -1; if (order != -1 && mLastCharOrder != -1) { mTotalRel++; //count this sequence to its category counter mRelSample[(int)jp2CharContext[mLastCharOrder][order]]++; } mLastCharOrder = order; } float GetConfidence(); void Reset(void); void SetOpion() {} bool GotEnoughData() { return mTotalRel > ENOUGH_REL_THRESHOLD; } protected: virtual int GetOrder(const char *str, unsigned int *charLen) = 0; virtual int GetOrder(const char *str) = 0; //category counters, each interger counts sequence in its category unsigned int mRelSample[NUM_OF_CATEGORY]; //total sequence received unsigned int mTotalRel; //The order of previous char int mLastCharOrder; //if last byte in current buffer is not the last byte of a character, we //need to know how many byte to skip in next buffer. unsigned int mNeedToSkipCharNum; //If this flag is set to true, detection is done and conclusion has been made bool mDone; }; class KCODECS_NO_EXPORT SJISContextAnalysis : public JapaneseContextAnalysis { //SJISContextAnalysis(){}; protected: int GetOrder(const char *str, unsigned int *charLen) override; int GetOrder(const char *str) override { //We only interested in Hiragana, so first byte is '\202' if (*str == '\202' && (unsigned char) * (str + 1) >= (unsigned char)0x9f && (unsigned char) * (str + 1) <= (unsigned char)0xf1) { return (unsigned char) * (str + 1) - (unsigned char)0x9f; } return -1; } }; class KCODECS_NO_EXPORT EUCJPContextAnalysis : public JapaneseContextAnalysis { protected: int GetOrder(const char *str, unsigned int *charLen) override; int GetOrder(const char *str) override //We only interested in Hiragana, so first byte is '\244' { if (*str == '\244' && (unsigned char) * (str + 1) >= (unsigned char)0xa1 && (unsigned char) * (str + 1) <= (unsigned char)0xf3) { return (unsigned char) * (str + 1) - (unsigned char)0xa1; } return -1; } }; } #endif /* __JPCNTX_H__ */ diff --git a/src/probers/LangBulgarianModel.cpp b/src/probers/LangBulgarianModel.cpp index ceea7d9..cf06a1f 100644 --- a/src/probers/LangBulgarianModel.cpp +++ b/src/probers/LangBulgarianModel.cpp @@ -1,230 +1,212 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsSBCharSetProber.h" /**************************************************************** 255: Control characters that usually does not exist in any text 254: Carriage/Return 253: symbol (punctuation) that does not belong to word 252: 0 - 9 *****************************************************************/ namespace kencodingprober { //Character Mapping Table: //this talbe is modified base on win1251BulgarianCharToOrderMap, so //only number <64 is sure valid const unsigned char Latin5_BulgarianCharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 77, 90, 99, 100, 72, 109, 107, 101, 79, 185, 81, 102, 76, 94, 82, //40 110, 186, 108, 91, 74, 119, 84, 96, 111, 187, 115, 253, 253, 253, 253, 253, //50 253, 65, 69, 70, 66, 63, 68, 112, 103, 92, 194, 104, 95, 86, 87, 71, //60 116, 195, 85, 93, 97, 113, 196, 197, 198, 199, 200, 253, 253, 253, 253, 253, //70 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, //80 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, //90 81, 226, 227, 228, 229, 230, 105, 231, 232, 233, 234, 235, 236, 45, 237, 238, //a0 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, //b0 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61, 239, 67, 240, 60, 56, //c0 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, //d0 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52, 241, 42, 16, //e0 62, 242, 243, 244, 58, 245, 98, 246, 247, 248, 249, 250, 251, 91, 252, 253, //f0 }; const unsigned char win1251BulgarianCharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 77, 90, 99, 100, 72, 109, 107, 101, 79, 185, 81, 102, 76, 94, 82, //40 110, 186, 108, 91, 74, 119, 84, 96, 111, 187, 115, 253, 253, 253, 253, 253, //50 253, 65, 69, 70, 66, 63, 68, 112, 103, 92, 194, 104, 95, 86, 87, 71, //60 116, 195, 85, 93, 97, 113, 196, 197, 198, 199, 200, 253, 253, 253, 253, 253, //70 206, 207, 208, 209, 210, 211, 212, 213, 120, 214, 215, 216, 217, 218, 219, 220, //80 221, 78, 64, 83, 121, 98, 117, 105, 222, 223, 224, 225, 226, 227, 228, 229, //90 88, 230, 231, 232, 233, 122, 89, 106, 234, 235, 236, 237, 238, 45, 239, 240, //a0 73, 80, 118, 114, 241, 242, 243, 244, 245, 62, 58, 246, 247, 248, 249, 250, //b0 31, 32, 35, 43, 37, 44, 55, 47, 40, 59, 33, 46, 38, 36, 41, 30, //c0 39, 28, 34, 51, 48, 49, 53, 50, 54, 57, 61, 251, 67, 252, 60, 56, //d0 1, 18, 9, 20, 11, 3, 23, 15, 2, 26, 12, 10, 14, 6, 4, 13, //e0 7, 8, 5, 19, 29, 25, 22, 21, 27, 24, 17, 75, 52, 253, 42, 16, //f0 }; //Model Table: //total sequences: 100% //first 512 sequences: 96.9392% //first 1024 sequences:3.0618% //rest sequences: 0.2992% //negative sequences: 0.0020% const char BulgarianLangModel[] = { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 2, 2, 3, 2, 2, 1, 2, 2, 3, 1, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 2, 1, 3, 3, 3, 3, 2, 2, 2, 1, 1, 2, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 2, 3, 3, 1, 1, 2, 3, 3, 2, 3, 3, 3, 3, 2, 1, 2, 0, 2, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 2, 3, 3, 1, 3, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 2, 3, 3, 3, 1, 3, 3, 2, 3, 2, 2, 2, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 2, 2, 3, 3, 3, 1, 2, 2, 3, 2, 1, 1, 2, 0, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 1, 2, 3, 2, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3, 1, 2, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 2, 3, 1, 2, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 2, 2, 1, 3, 1, 3, 2, 2, 3, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 2, 2, 3, 2, 2, 3, 1, 2, 1, 1, 1, 2, 3, 1, 3, 1, 2, 2, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 1, 3, 2, 2, 3, 3, 1, 2, 3, 1, 1, 3, 3, 3, 3, 1, 2, 2, 1, 1, 1, 0, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 2, 2, 3, 3, 3, 2, 2, 1, 1, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 1, 2, 1, 3, 3, 2, 3, 3, 3, 3, 3, 2, 3, 2, 1, 0, 3, 1, 2, 1, 2, 1, 2, 3, 2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 1, 3, 3, 2, 3, 3, 2, 2, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 2, 1, 1, 2, 1, 3, 3, 0, 3, 1, 1, 1, 1, 3, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 3, 1, 3, 3, 2, 3, 2, 2, 2, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 3, 2, 1, 1, 1, 1, 1, 3, 1, 3, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 3, 2, 0, 3, 2, 0, 3, 0, 2, 0, 0, 2, 1, 3, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 2, 1, 3, 1, 1, 2, 1, 3, 2, 1, 1, 0, 1, 2, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3, 2, 2, 1, 0, 1, 0, 0, 1, 0, 0, 0, 2, 1, 0, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 2, 3, 2, 3, 3, 1, 3, 2, 1, 1, 1, 2, 1, 1, 2, 1, 3, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 2, 2, 3, 3, 2, 3, 2, 2, 2, 3, 1, 2, 2, 1, 1, 2, 1, 1, 2, 2, 0, 1, 1, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2, 1, 3, 1, 0, 2, 2, 1, 3, 2, 1, 0, 0, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 1, 2, 0, 2, 3, 1, 2, 3, 2, 0, 1, 3, 1, 2, 1, 1, 1, 0, 0, 1, 0, 0, 2, 2, 2, 3, 2, 2, 2, 2, 1, 2, 1, 1, 2, 2, 1, 1, 2, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 3, 3, 3, 3, 3, 2, 1, 2, 2, 1, 2, 0, 2, 0, 1, 0, 1, 2, 1, 2, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 2, 3, 3, 1, 1, 3, 1, 0, 3, 2, 1, 0, 0, 0, 1, 2, 0, 2, 0, 1, 0, 0, 0, 1, 0, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 3, 1, 0, 1, 0, 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 1, 0, 2, 1, 2, 1, 1, 1, 0, 1, 2, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 1, 2, 1, 1, 0, 1, 2, 1, 2, 2, 2, 1, 1, 1, 0, 1, 1, 1, 1, 2, 0, 1, 0, 0, 0, 0, 2, 3, 2, 3, 3, 0, 0, 2, 1, 0, 2, 1, 0, 0, 0, 0, 2, 3, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 1, 2, 2, 1, 2, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 0, 1, 2, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 2, 0, 0, 3, 3, 2, 2, 3, 0, 2, 3, 1, 1, 2, 0, 0, 0, 1, 0, 0, 2, 0, 2, 0, 0, 0, 1, 0, 1, 0, 1, 2, 0, 2, 2, 1, 1, 1, 1, 2, 1, 0, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 3, 2, 3, 3, 0, 0, 3, 0, 1, 1, 0, 1, 0, 0, 0, 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 2, 2, 2, 1, 1, 1, 1, 1, 2, 2, 2, 1, 0, 2, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 3, 3, 3, 3, 2, 2, 2, 2, 2, 0, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 0, 2, 0, 1, 0, 1, 0, 0, 2, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 0, 2, 0, 1, 0, 2, 0, 0, 1, 1, 1, 0, 0, 2, 0, 0, 0, 1, 1, 0, 0, 2, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 2, 2, 2, 2, 1, 1, 2, 1, 1, 2, 2, 2, 1, 2, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 2, 3, 3, 3, 3, 0, 2, 2, 0, 2, 1, 0, 0, 0, 1, 1, 1, 2, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 2, 0, 2, 2, 1, 1, 1, 2, 1, 2, 1, 1, 2, 2, 2, 1, 2, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 2, 1, 0, 0, 0, 1, 1, 0, 0, 2, 3, 3, 3, 3, 0, 2, 1, 0, 0, 2, 0, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 3, 3, 2, 2, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 3, 1, 0, 1, 0, 2, 2, 2, 2, 3, 2, 1, 1, 1, 2, 3, 0, 0, 1, 0, 2, 1, 1, 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 2, 1, 1, 0, 1, 2, 1, 2, 2, 1, 1, 1, 0, 0, 1, 1, 1, 2, 1, 0, 1, 0, 0, 0, 0, 2, 1, 0, 1, 0, 3, 1, 2, 2, 2, 2, 1, 2, 2, 1, 1, 1, 0, 2, 1, 2, 2, 1, 1, 2, 1, 1, 0, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, 1, 1, 0, 2, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 1, 1, 2, 1, 2, 3, 2, 2, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 2, 0, 1, 2, 0, 1, 2, 1, 1, 0, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 2, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 2, 1, 2, 1, 1, 1, 0, 2, 1, 2, 1, 1, 1, 0, 2, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 3, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0, 2, 2, 2, 2, 2, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 2, 3, 1, 2, 1, 0, 1, 1, 0, 2, 2, 2, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2, 2, 2, 2, 2, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 1, 1, 1, 1, 1, 0, 0, 1, 2, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0, 0, 2, 0, 1, 1, 0, 0, 0, 1, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 2, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 2, 2, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 1, 0, 1, 1, 1, 1, 2, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 3, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 1, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 2, 0, 1, 0, 0, 1, 1, 2, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0, 1, 1, 0, 2, 1, 0, 1, 1, 1, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 2, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 2, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, }; const SequenceModel KCODECS_NO_EXPORT Latin5BulgarianModel = { Latin5_BulgarianCharToOrderMap, BulgarianLangModel, (float)0.969392, false, "ISO-8859-5" }; const SequenceModel KCODECS_NO_EXPORT Win1251BulgarianModel = { win1251BulgarianCharToOrderMap, BulgarianLangModel, (float)0.969392, false, "windows-1251" }; } diff --git a/src/probers/LangCyrillicModel.cpp b/src/probers/LangCyrillicModel.cpp index 48cd363..9036010 100644 --- a/src/probers/LangCyrillicModel.cpp +++ b/src/probers/LangCyrillicModel.cpp @@ -1,330 +1,312 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsSBCharSetProber.h" namespace kencodingprober { //KOI8-R language model //Character Mapping Table: static const unsigned char KOI8R_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 74, 153, 75, 154, //40 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 253, 253, 253, 253, 253, //50 253, 71, 172, 66, 173, 65, 174, 76, 175, 64, 176, 177, 77, 72, 178, 69, //60 67, 179, 78, 73, 180, 181, 79, 182, 183, 184, 185, 253, 253, 253, 253, 253, //70 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, //80 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, //90 223, 224, 225, 68, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, //a0 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, //b0 27, 3, 21, 28, 13, 2, 39, 19, 26, 4, 23, 11, 8, 12, 5, 1, //c0 15, 16, 9, 7, 6, 14, 24, 10, 17, 18, 20, 25, 30, 29, 22, 54, //d0 59, 37, 44, 58, 41, 48, 53, 46, 55, 42, 60, 36, 49, 38, 31, 34, //e0 35, 43, 45, 32, 40, 52, 56, 33, 61, 62, 51, 57, 47, 63, 50, 70, //f0 }; static const unsigned char win1251_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 74, 153, 75, 154, //40 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 253, 253, 253, 253, 253, //50 253, 71, 172, 66, 173, 65, 174, 76, 175, 64, 176, 177, 77, 72, 178, 69, //60 67, 179, 78, 73, 180, 181, 79, 182, 183, 184, 185, 253, 253, 253, 253, 253, //70 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 68, 247, 248, 249, 250, 251, 252, 253, 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, }; const unsigned char latin5_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 74, 153, 75, 154, //40 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 253, 253, 253, 253, 253, //50 253, 71, 172, 66, 173, 65, 174, 76, 175, 64, 176, 177, 77, 72, 178, 69, //60 67, 179, 78, 73, 180, 181, 79, 182, 183, 184, 185, 253, 253, 253, 253, 253, //70 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, 239, 68, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 255, }; const unsigned char macCyrillic_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 74, 153, 75, 154, //40 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 253, 253, 253, 253, 253, //50 253, 71, 172, 66, 173, 65, 174, 76, 175, 64, 176, 177, 77, 72, 178, 69, //60 67, 179, 78, 73, 180, 181, 79, 182, 183, 184, 185, 253, 253, 253, 253, 253, //70 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 68, 16, 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 255, }; const unsigned char IBM855_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 74, 153, 75, 154, //40 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 253, 253, 253, 253, 253, //50 253, 71, 172, 66, 173, 65, 174, 76, 175, 64, 176, 177, 77, 72, 178, 69, //60 67, 179, 78, 73, 180, 181, 79, 182, 183, 184, 185, 253, 253, 253, 253, 253, //70 191, 192, 193, 194, 68, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 27, 59, 54, 70, 3, 37, 21, 44, 28, 58, 13, 41, 2, 48, 39, 53, 19, 46, 218, 219, 220, 221, 222, 223, 224, 26, 55, 4, 42, 225, 226, 227, 228, 23, 60, 229, 230, 231, 232, 233, 234, 235, 11, 36, 236, 237, 238, 239, 240, 241, 242, 243, 8, 49, 12, 38, 5, 31, 1, 34, 15, 244, 245, 246, 247, 35, 16, 248, 43, 9, 45, 7, 32, 6, 40, 14, 52, 24, 56, 10, 33, 17, 61, 249, 250, 18, 62, 20, 51, 25, 57, 30, 47, 29, 63, 22, 50, 251, 252, 255, }; const unsigned char IBM866_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 74, 153, 75, 154, //40 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 253, 253, 253, 253, 253, //50 253, 71, 172, 66, 173, 65, 174, 76, 175, 64, 176, 177, 77, 72, 178, 69, //60 67, 179, 78, 73, 180, 181, 79, 182, 183, 184, 185, 253, 253, 253, 253, 253, //70 37, 44, 33, 46, 41, 48, 56, 51, 42, 60, 36, 49, 38, 31, 34, 35, 45, 32, 40, 52, 53, 55, 58, 50, 57, 63, 70, 62, 61, 47, 59, 43, 3, 21, 10, 19, 13, 2, 24, 20, 4, 23, 11, 8, 12, 5, 1, 15, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 9, 7, 6, 14, 39, 26, 28, 22, 25, 29, 54, 18, 17, 30, 27, 16, 239, 68, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 255, }; //Model Table: //total sequences: 100% //first 512 sequences: 97.6601% //first 1024 sequences: 2.3389% //rest sequences: 0.1237% //negative sequences: 0.0009% const char RussianLangModel[] = { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 3, 3, 3, 3, 1, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 2, 2, 2, 2, 2, 0, 0, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 3, 1, 3, 3, 1, 3, 3, 3, 3, 2, 2, 3, 0, 2, 2, 2, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 1, 2, 2, 0, 1, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 3, 0, 2, 2, 3, 3, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 3, 3, 1, 2, 3, 2, 2, 3, 2, 3, 3, 3, 3, 2, 2, 3, 0, 3, 2, 2, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 2, 2, 0, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 2, 3, 2, 2, 0, 1, 3, 2, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 1, 3, 0, 1, 1, 1, 1, 2, 1, 1, 0, 2, 2, 2, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 1, 3, 2, 3, 2, 3, 2, 1, 2, 2, 0, 1, 1, 2, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 2, 3, 3, 3, 2, 2, 2, 2, 0, 2, 2, 2, 2, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 2, 0, 0, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3, 3, 2, 2, 3, 3, 0, 2, 1, 0, 3, 2, 3, 2, 3, 0, 0, 1, 2, 0, 0, 1, 0, 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 0, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 1, 2, 2, 0, 0, 2, 3, 2, 2, 2, 3, 2, 3, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 2, 3, 2, 3, 0, 1, 2, 3, 3, 2, 0, 2, 3, 0, 0, 2, 3, 2, 2, 0, 1, 3, 1, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 0, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 3, 2, 0, 0, 2, 2, 3, 3, 3, 2, 3, 3, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 2, 3, 3, 0, 0, 1, 1, 1, 1, 1, 2, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 0, 3, 2, 3, 3, 2, 3, 2, 0, 2, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 2, 2, 2, 3, 1, 3, 2, 3, 1, 1, 2, 1, 0, 2, 2, 2, 2, 1, 3, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 3, 3, 3, 1, 2, 2, 1, 3, 1, 0, 3, 0, 0, 3, 0, 0, 0, 1, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 1, 1, 3, 3, 3, 2, 2, 1, 2, 2, 3, 1, 1, 2, 0, 0, 2, 2, 1, 3, 0, 0, 2, 1, 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 3, 3, 3, 1, 2, 2, 2, 1, 2, 1, 3, 3, 1, 1, 2, 1, 2, 1, 2, 2, 0, 2, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3, 3, 2, 1, 3, 2, 2, 3, 2, 0, 3, 2, 0, 3, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 2, 3, 3, 3, 2, 2, 2, 3, 3, 1, 2, 1, 2, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 2, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 2, 1, 2, 3, 3, 2, 2, 1, 2, 2, 3, 0, 2, 1, 0, 0, 2, 2, 3, 2, 1, 2, 2, 2, 2, 2, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 1, 0, 1, 1, 2, 2, 1, 1, 3, 0, 0, 1, 3, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 3, 3, 3, 2, 0, 0, 0, 2, 1, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 2, 3, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1, 0, 0, 1, 1, 1, 0, 2, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 2, 0, 0, 1, 1, 2, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 2, 2, 3, 2, 2, 2, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 3, 3, 3, 2, 2, 2, 2, 3, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 3, 1, 2, 1, 2, 0, 0, 1, 1, 0, 1, 0, 2, 1, 1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 0, 0, 1, 0, 3, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 0, 0, 0, 2, 1, 2, 2, 1, 1, 2, 2, 0, 1, 1, 0, 2, 1, 1, 1, 1, 1, 0, 1, 1, 1, 2, 1, 1, 1, 2, 1, 0, 1, 2, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 3, 2, 2, 2, 1, 1, 1, 2, 3, 0, 0, 0, 0, 2, 0, 2, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 2, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2, 3, 2, 3, 2, 1, 2, 2, 2, 2, 1, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 1, 1, 1, 2, 1, 0, 2, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 2, 1, 2, 1, 1, 1, 2, 2, 0, 0, 0, 1, 2, 1, 1, 1, 1, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 2, 3, 2, 3, 3, 2, 0, 1, 1, 1, 0, 0, 1, 0, 2, 0, 1, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 3, 3, 3, 1, 2, 2, 2, 2, 0, 1, 1, 0, 2, 1, 1, 1, 2, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 2, 0, 0, 1, 1, 2, 2, 1, 0, 0, 2, 0, 1, 1, 3, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 2, 1, 1, 1, 2, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 3, 2, 3, 2, 1, 0, 0, 2, 2, 2, 0, 1, 0, 2, 0, 1, 1, 1, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 2, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 2, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 3, 1, 2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 1, 0, 0, 0, 2, 2, 2, 0, 0, 0, 1, 2, 1, 0, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 3, 0, 0, 0, 0, 2, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 3, 3, 2, 2, 0, 0, 0, 2, 2, 0, 0, 0, 1, 2, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 2, 3, 2, 0, 0, 0, 0, 1, 1, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 2, 0, 1, 2, 1, 0, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 3, 2, 2, 2, 1, 0, 0, 2, 2, 1, 0, 1, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 2, 3, 1, 2, 2, 2, 2, 2, 2, 1, 1, 0, 0, 0, 1, 0, 1, 0, 2, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 2, 0, 0, 1, 0, 3, 2, 1, 2, 1, 2, 2, 0, 1, 0, 0, 0, 2, 1, 0, 0, 2, 1, 1, 1, 1, 0, 2, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 2, 2, 2, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 2, 0, 0, 2, 0, 1, 0, 1, 1, 1, 2, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 2, 1, 2, 2, 2, 0, 3, 0, 1, 1, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 2, 2, 3, 2, 2, 0, 0, 1, 1, 2, 0, 1, 2, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 0, 1, 0, 0, 0, 1, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 2, 2, 2, 2, 0, 1, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0, 0, 0, 2, 2, 2, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 0, 0, 0, 0, 1, 0, 0, 1, 1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 1, 1, 2, 0, 2, 1, 1, 1, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 2, 0, 1, 2, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, }; const SequenceModel Koi8rModel = { KOI8R_CharToOrderMap, RussianLangModel, (float)0.976601, false, "KOI8-R" }; const SequenceModel Win1251Model = { win1251_CharToOrderMap, RussianLangModel, (float)0.976601, false, "windows-1251" }; const SequenceModel Latin5Model = { latin5_CharToOrderMap, RussianLangModel, (float)0.976601, false, "ISO-8859-5" }; const SequenceModel MacCyrillicModel = { macCyrillic_CharToOrderMap, RussianLangModel, (float)0.976601, false, "x-mac-cyrillic" }; const SequenceModel Ibm866Model = { IBM866_CharToOrderMap, RussianLangModel, (float)0.976601, false, "IBM866" }; const SequenceModel Ibm855Model = { IBM855_CharToOrderMap, RussianLangModel, (float)0.976601, false, "IBM855" }; } diff --git a/src/probers/LangGreekModel.cpp b/src/probers/LangGreekModel.cpp index 7e2c412..401390d 100644 --- a/src/probers/LangGreekModel.cpp +++ b/src/probers/LangGreekModel.cpp @@ -1,228 +1,210 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsSBCharSetProber.h" /**************************************************************** 255: Control characters that usually does not exist in any text 254: Carriage/Return 253: symbol (punctuation) that does not belong to word 252: 0 - 9 *****************************************************************/ namespace kencodingprober { //Character Mapping Table: const unsigned char Latin7_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 82, 100, 104, 94, 98, 101, 116, 102, 111, 187, 117, 92, 88, 113, 85, //40 79, 118, 105, 83, 67, 114, 119, 95, 99, 109, 188, 253, 253, 253, 253, 253, //50 253, 72, 70, 80, 81, 60, 96, 93, 89, 68, 120, 97, 77, 86, 69, 55, //60 78, 115, 65, 66, 58, 76, 106, 103, 87, 107, 112, 253, 253, 253, 253, 253, //70 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //80 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //90 +253, 233, 90, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 74, 253, 253, //a0 253, 253, 253, 253, 247, 248, 61, 36, 46, 71, 73, 253, 54, 253, 108, 123, //b0 110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, //c0 35, 48, 250, 37, 33, 45, 56, 50, 84, 57, 120, 121, 17, 18, 22, 15, //d0 124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, //e0 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27, 253, //f0 }; const unsigned char win1253_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 82, 100, 104, 94, 98, 101, 116, 102, 111, 187, 117, 92, 88, 113, 85, //40 79, 118, 105, 83, 67, 114, 119, 95, 99, 109, 188, 253, 253, 253, 253, 253, //50 253, 72, 70, 80, 81, 60, 96, 93, 89, 68, 120, 97, 77, 86, 69, 55, //60 78, 115, 65, 66, 58, 76, 106, 103, 87, 107, 112, 253, 253, 253, 253, 253, //70 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //80 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //90 +253, 233, 61, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 74, 253, 253, //a0 253, 253, 253, 253, 247, 253, 253, 36, 46, 71, 73, 253, 54, 253, 108, 123, //b0 110, 31, 51, 43, 41, 34, 91, 40, 52, 47, 44, 53, 38, 49, 59, 39, //c0 35, 48, 250, 37, 33, 45, 56, 50, 84, 57, 120, 121, 17, 18, 22, 15, //d0 124, 1, 29, 20, 21, 3, 32, 13, 25, 5, 11, 16, 10, 6, 30, 4, //e0 9, 8, 14, 7, 2, 12, 28, 23, 42, 24, 64, 75, 19, 26, 27, 253, //f0 }; //Model Table: //total sequences: 100% //first 512 sequences: 98.2851% //first 1024 sequences:1.7001% //rest sequences: 0.0359% //negative sequences: 0.0148% const char GreekLangModel[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 0, 2, 2, 3, 3, 0, 3, 0, 3, 2, 0, 3, 3, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 2, 3, 3, 0, 3, 2, 3, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 2, 3, 3, 0, 3, 3, 3, 3, 2, 3, 3, 3, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 1, 3, 3, 3, 3, 2, 3, 3, 2, 3, 3, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 2, 3, 3, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 3, 0, 0, 0, 0, 3, 3, 0, 3, 1, 3, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 0, 3, 0, 3, 3, 3, 3, 3, 0, 3, 2, 2, 2, 3, 0, 2, 3, 3, 3, 3, 3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 2, 2, 3, 3, 3, 3, 0, 3, 1, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 0, 3, 0, 0, 0, 3, 3, 2, 3, 3, 3, 3, 3, 0, 0, 3, 2, 3, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 0, 0, 3, 3, 0, 2, 3, 0, 3, 0, 3, 3, 3, 0, 0, 3, 0, 3, 0, 2, 2, 3, 3, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 0, 3, 2, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 0, 3, 3, 2, 3, 2, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 0, 2, 3, 2, 3, 2, 2, 2, 3, 2, 3, 3, 2, 3, 0, 2, 2, 2, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 3, 3, 2, 3, 3, 0, 0, 3, 0, 3, 0, 0, 0, 3, 2, 0, 3, 0, 3, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 0, 3, 0, 0, 0, 3, 3, 0, 3, 3, 3, 0, 0, 1, 2, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 0, 0, 3, 2, 2, 3, 3, 0, 3, 3, 3, 3, 3, 2, 1, 3, 0, 3, 2, 3, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 3, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 0, 0, 3, 3, 0, 3, 2, 3, 0, 0, 3, 3, 3, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 0, 3, 0, 3, 0, 0, 0, 3, 2, 0, 3, 2, 3, 0, 0, 3, 2, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2, 2, 3, 3, 3, 3, 3, 3, 0, 2, 3, 0, 3, 0, 0, 0, 3, 3, 0, 3, 0, 2, 0, 0, 2, 3, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 3, 0, 3, 0, 3, 3, 2, 3, 0, 3, 3, 3, 3, 3, 3, 0, 3, 3, 3, 0, 2, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 0, 0, 3, 0, 0, 0, 3, 3, 0, 3, 0, 2, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 3, 0, 2, 0, 0, 0, 3, 3, 0, 3, 0, 3, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 3, 0, 2, 0, 3, 2, 0, 3, 2, 3, 2, 3, 0, 0, 3, 2, 3, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 3, 3, 3, 3, 3, 0, 0, 0, 3, 0, 2, 1, 0, 0, 3, 2, 2, 2, 0, 3, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 2, 0, 3, 0, 3, 0, 3, 3, 0, 2, 1, 2, 3, 3, 0, 0, 3, 0, 3, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 3, 0, 3, 3, 3, 3, 3, 3, 0, 2, 3, 0, 3, 0, 0, 0, 2, 1, 0, 2, 2, 3, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 3, 3, 3, 2, 3, 0, 0, 1, 3, 0, 2, 0, 0, 0, 0, 3, 0, 1, 0, 2, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 1, 0, 3, 0, 0, 0, 3, 2, 0, 3, 2, 3, 3, 3, 0, 0, 3, 0, 3, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 3, 3, 3, 0, 0, 3, 0, 0, 0, 0, 2, 0, 2, 3, 3, 2, 2, 2, 2, 3, 0, 2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 2, 3, 0, 2, 0, 2, 3, 2, 0, 0, 3, 0, 3, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 3, 2, 2, 3, 0, 2, 0, 3, 0, 0, 0, 2, 0, 0, 0, 0, 1, 2, 0, 2, 0, 2, 0, 0, 2, 0, 2, 0, 2, 2, 0, 0, 1, 0, 2, 2, 2, 0, 2, 2, 2, 0, 2, 2, 2, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 3, 3, 2, 0, 0, 0, 0, 0, 0, 1, 3, 0, 2, 0, 2, 2, 2, 0, 0, 2, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 3, 2, 0, 2, 2, 0, 2, 0, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 0, 2, 2, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 2, 3, 2, 2, 3, 2, 3, 2, 0, 0, 3, 3, 3, 0, 0, 3, 2, 0, 0, 0, 1, 1, 0, 2, 0, 2, 2, 0, 2, 0, 2, 0, 2, 2, 0, 0, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 0, 0, 2, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 0, 3, 0, 3, 3, 2, 2, 0, 3, 0, 0, 0, 2, 2, 0, 2, 2, 2, 1, 2, 0, 0, 1, 2, 2, 0, 0, 3, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 1, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 2, 2, 0, 0, 0, 2, 0, 2, 3, 3, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 2, 2, 0, 2, 0, 2, 0, 2, 2, 0, 0, 2, 2, 2, 2, 1, 0, 0, 2, 2, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 2, 3, 0, 0, 0, 3, 0, 0, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 3, 2, 0, 2, 2, 2, 2, 2, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 1, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2, 2, 2, 0, 2, 2, 0, 1, 2, 0, 2, 2, 2, 0, 2, 2, 2, 2, 1, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 2, 0, 0, 0, 0, 1, 2, 1, 0, 0, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 3, 0, 0, 2, 0, 0, 0, 2, 2, 0, 2, 0, 0, 0, 1, 0, 0, 2, 0, 2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 2, 2, 0, 0, 0, 0, 0, 0, 1, 3, 0, 2, 0, 2, 2, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 3, 2, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 1, 1, 0, 0, 2, 1, 2, 0, 2, 2, 0, 1, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 2, 2, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 3, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 1, 2, 2, 1, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 2, 2, 0, 2, 0, 0, 2, 0, 0, 0, 0, 1, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 1, 2, 2, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 3, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 2, 2, 2, 2, 2, 0, 1, 2, 0, 0, 0, 2, 2, 0, 1, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 0, 2, 2, 1, 0, 1, 0, 1, 0, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 2, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 2, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 2, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; const SequenceModel Latin7Model = { Latin7_CharToOrderMap, GreekLangModel, (float)0.982851, false, "ISO-8859-7" }; const SequenceModel Win1253Model = { win1253_CharToOrderMap, GreekLangModel, (float)0.982851, false, "windows-1253" }; } diff --git a/src/probers/LangHebrewModel.cpp b/src/probers/LangHebrewModel.cpp index 01acc4f..0d4ecde 100644 --- a/src/probers/LangHebrewModel.cpp +++ b/src/probers/LangHebrewModel.cpp @@ -1,203 +1,185 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsSBCharSetProber.h" /**************************************************************** 255: Control characters that usually does not exist in any text 254: Carriage/Return 253: symbol (punctuation) that does not belong to word 252: 0 - 9 *****************************************************************/ namespace kencodingprober { //Windows-1255 language model //Character Mapping Table: const unsigned char win1255_CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 69, 91, 79, 80, 92, 89, 97, 90, 68, 111, 112, 82, 73, 95, 85, //40 78, 121, 86, 71, 67, 102, 107, 84, 114, 103, 115, 253, 253, 253, 253, 253, //50 253, 50, 74, 60, 61, 42, 76, 70, 64, 53, 105, 93, 56, 65, 54, 49, //60 66, 110, 51, 43, 44, 63, 81, 77, 98, 75, 108, 253, 253, 253, 253, 253, //70 124, 202, 203, 204, 205, 40, 58, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 83, 52, 47, 46, 72, 32, 94, 216, 113, 217, 109, 218, 219, 220, 221, 34, 116, 222, 118, 100, 223, 224, 117, 119, 104, 125, 225, 226, 87, 99, 227, 106, 122, 123, 228, 55, 229, 230, 101, 231, 232, 120, 233, 48, 39, 57, 234, 30, 59, 41, 88, 33, 37, 36, 31, 29, 35, 235, 62, 28, 236, 126, 237, 238, 38, 45, 239, 240, 241, 242, 243, 127, 244, 245, 246, 247, 248, 249, 250, 9, 8, 20, 16, 3, 2, 24, 14, 22, 1, 25, 15, 4, 11, 6, 23, 12, 19, 13, 26, 18, 27, 21, 17, 7, 10, 5, 251, 252, 128, 96, 253, }; //Model Table: //total sequences: 100% //first 512 sequences: 98.4004% //first 1024 sequences: 1.5981% //rest sequences: 0.087% //negative sequences: 0.0015% const char HebrewLangModel[] = { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 1, 2, 0, 1, 0, 0, 3, 0, 3, 1, 0, 0, 1, 3, 2, 0, 1, 1, 2, 0, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 0, 0, 2, 2, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 2, 1, 3, 1, 1, 0, 0, 2, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 1, 2, 2, 1, 3, 1, 2, 1, 1, 2, 2, 0, 0, 2, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 2, 2, 3, 2, 1, 2, 1, 2, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 2, 3, 2, 2, 3, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 1, 1, 2, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 2, 2, 2, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 0, 2, 2, 2, 0, 2, 1, 2, 2, 2, 0, 0, 2, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 2, 3, 2, 2, 2, 1, 2, 1, 2, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 2, 0, 2, 0, 2, 1, 2, 2, 2, 0, 0, 1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 3, 2, 2, 3, 2, 1, 2, 1, 1, 1, 0, 1, 1, 1, 1, 1, 3, 0, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 1, 2, 3, 3, 2, 3, 3, 3, 3, 2, 3, 2, 1, 2, 0, 2, 1, 2, 0, 2, 0, 2, 2, 2, 0, 0, 1, 2, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 1, 2, 2, 3, 3, 2, 3, 2, 3, 2, 2, 3, 1, 2, 2, 0, 2, 2, 2, 0, 2, 1, 2, 2, 2, 0, 0, 1, 2, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 2, 2, 3, 3, 3, 3, 1, 3, 2, 2, 2, 0, 2, 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 2, 3, 2, 2, 2, 1, 2, 2, 0, 2, 2, 2, 2, 0, 2, 0, 2, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 1, 3, 2, 3, 3, 2, 3, 3, 2, 2, 1, 2, 2, 2, 2, 2, 2, 0, 2, 1, 2, 1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 2, 3, 2, 3, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 1, 0, 2, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 2, 3, 3, 3, 3, 3, 3, 3, 2, 3, 2, 3, 2, 1, 2, 3, 0, 2, 1, 2, 2, 0, 2, 1, 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 1, 3, 1, 2, 2, 2, 1, 2, 3, 3, 1, 2, 1, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 2, 3, 3, 3, 1, 3, 3, 3, 1, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 0, 2, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 2, 3, 3, 3, 2, 1, 2, 3, 2, 3, 2, 2, 2, 2, 1, 2, 1, 1, 1, 2, 2, 0, 2, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 2, 3, 3, 2, 3, 1, 2, 2, 2, 2, 3, 2, 3, 1, 1, 2, 2, 1, 2, 2, 1, 1, 0, 2, 2, 2, 2, 0, 1, 0, 1, 2, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 3, 3, 3, 0, 3, 0, 2, 2, 2, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2, 1, 1, 1, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 0, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1, 2, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 2, 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 2, 1, 2, 2, 2, 0, 2, 0, 2, 0, 1, 1, 2, 1, 1, 1, 1, 2, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 2, 2, 0, 1, 0, 0, 1, 1, 2, 2, 1, 2, 0, 2, 0, 0, 0, 1, 2, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 1, 2, 0, 2, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 2, 1, 1, 0, 1, 0, 0, 1, 1, 1, 2, 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 0, 2, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 2, 1, 1, 2, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 2, 0, 1, 0, 0, 0, 0, 2, 1, 1, 2, 0, 2, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 1, 0, 1, 0, 0, 2, 2, 1, 2, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 2, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 2, 1, 1, 1, 0, 2, 1, 1, 0, 0, 0, 2, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 2, 0, 1, 0, 0, 1, 1, 0, 2, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 2, 2, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 2, 1, 0, 2, 0, 0, 0, 1, 1, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 2, 1, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 2, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 2, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, }; const SequenceModel Win1255Model = { win1255_CharToOrderMap, HebrewLangModel, (float)0.984004, false, "windows-1255" }; } diff --git a/src/probers/LangHungarianModel.cpp b/src/probers/LangHungarianModel.cpp index 68b4ec4..af60ac8 100644 --- a/src/probers/LangHungarianModel.cpp +++ b/src/probers/LangHungarianModel.cpp @@ -1,228 +1,210 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsSBCharSetProber.h" /**************************************************************** 255: Control characters that usually does not exist in any text 254: Carriage/Return 253: symbol (punctuation) that does not belong to word 252: 0 - 9 *****************************************************************/ namespace kencodingprober { //Character Mapping Table: const unsigned char Latin2_HungarianCharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, 46, 71, 43, 33, 37, 57, 48, 64, 68, 55, 52, 253, 253, 253, 253, 253, 253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11, 253, 253, 253, 253, 253, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 75, 198, 199, 200, 201, 202, 203, 204, 205, 79, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 51, 81, 222, 78, 223, 224, 225, 226, 44, 227, 228, 229, 61, 230, 231, 232, 233, 234, 58, 235, 66, 59, 236, 237, 238, 60, 69, 63, 239, 240, 241, 82, 14, 74, 242, 70, 80, 243, 72, 244, 15, 83, 77, 84, 30, 76, 85, 245, 246, 247, 25, 73, 42, 24, 248, 249, 250, 31, 56, 29, 251, 252, 253, }; const unsigned char win1250HungarianCharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 28, 40, 54, 45, 32, 50, 49, 38, 39, 53, 36, 41, 34, 35, 47, 46, 72, 43, 33, 37, 57, 48, 64, 68, 55, 52, 253, 253, 253, 253, 253, 253, 2, 18, 26, 17, 1, 27, 12, 20, 9, 22, 7, 6, 13, 4, 8, 23, 67, 10, 5, 3, 21, 19, 65, 62, 16, 11, 253, 253, 253, 253, 253, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 78, 181, 69, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 76, 198, 199, 200, 201, 202, 203, 204, 205, 81, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 51, 83, 222, 80, 223, 224, 225, 226, 44, 227, 228, 229, 61, 230, 231, 232, 233, 234, 58, 235, 66, 59, 236, 237, 238, 60, 70, 63, 239, 240, 241, 84, 14, 75, 242, 71, 82, 243, 73, 244, 15, 85, 79, 86, 30, 77, 87, 245, 246, 247, 25, 74, 42, 24, 248, 249, 250, 31, 56, 29, 251, 252, 253, }; //Model Table: //total sequences: 100% //first 512 sequences: 94.7368% //first 1024 sequences:5.2623% //rest sequences: 0.8894% //negative sequences: 0.0009% const char HungarianLangModel[] = { 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 1, 1, 2, 2, 2, 2, 2, 1, 2, 3, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 1, 2, 3, 3, 3, 3, 2, 3, 3, 1, 1, 3, 3, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 2, 1, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 1, 1, 3, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 2, 3, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 3, 2, 2, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 3, 3, 3, 3, 2, 3, 3, 2, 2, 3, 2, 3, 2, 0, 3, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 1, 2, 3, 2, 2, 3, 1, 2, 3, 3, 2, 2, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 2, 3, 3, 3, 3, 0, 2, 3, 2, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 3, 3, 2, 1, 3, 2, 2, 3, 2, 1, 3, 2, 2, 1, 0, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 2, 2, 3, 3, 3, 3, 3, 1, 2, 3, 3, 3, 3, 1, 2, 1, 3, 3, 3, 3, 2, 2, 3, 1, 1, 3, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 1, 3, 3, 3, 3, 3, 2, 2, 1, 3, 3, 3, 0, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 3, 2, 3, 3, 3, 2, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 2, 3, 3, 3, 1, 3, 2, 2, 2, 3, 1, 1, 3, 3, 1, 1, 0, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 2, 3, 3, 3, 2, 3, 2, 3, 3, 3, 2, 3, 3, 3, 3, 3, 1, 2, 3, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 2, 2, 2, 3, 1, 3, 3, 2, 2, 1, 3, 3, 3, 1, 1, 3, 1, 2, 3, 2, 3, 2, 2, 2, 1, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 3, 3, 3, 3, 3, 1, 2, 3, 3, 3, 3, 1, 2, 1, 3, 3, 3, 2, 2, 3, 2, 1, 0, 3, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 3, 3, 3, 3, 3, 1, 2, 3, 3, 3, 3, 1, 1, 0, 3, 3, 3, 3, 0, 2, 3, 0, 0, 2, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 2, 2, 3, 3, 0, 1, 2, 3, 2, 3, 2, 2, 3, 2, 1, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 1, 2, 3, 3, 3, 2, 1, 2, 3, 3, 2, 2, 2, 3, 2, 3, 3, 1, 3, 3, 1, 1, 0, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 1, 2, 2, 2, 2, 3, 3, 3, 1, 1, 1, 3, 3, 1, 1, 3, 1, 1, 3, 2, 1, 2, 3, 1, 1, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 2, 1, 2, 1, 1, 3, 3, 1, 1, 1, 1, 3, 3, 1, 1, 2, 2, 1, 2, 1, 1, 2, 2, 1, 1, 0, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 1, 1, 2, 1, 1, 3, 3, 1, 0, 1, 1, 3, 3, 2, 0, 1, 1, 2, 3, 1, 0, 2, 2, 1, 0, 0, 1, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 2, 1, 3, 3, 3, 3, 3, 1, 2, 3, 2, 3, 3, 2, 1, 1, 3, 2, 3, 2, 1, 2, 2, 0, 1, 2, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 2, 2, 2, 2, 3, 1, 2, 2, 1, 1, 3, 3, 0, 3, 2, 1, 2, 3, 2, 1, 3, 3, 1, 1, 0, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 2, 2, 2, 3, 2, 3, 3, 3, 2, 1, 1, 3, 3, 1, 1, 1, 2, 2, 3, 2, 3, 2, 2, 2, 1, 0, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 3, 3, 3, 3, 0, 0, 3, 3, 2, 3, 0, 0, 0, 2, 3, 3, 1, 0, 1, 2, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 2, 3, 3, 3, 3, 3, 1, 2, 3, 3, 2, 2, 1, 1, 0, 3, 3, 2, 2, 1, 2, 2, 1, 0, 2, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 2, 2, 1, 3, 1, 2, 3, 3, 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 2, 1, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 1, 1, 1, 1, 1, 3, 3, 3, 0, 1, 1, 3, 3, 1, 1, 1, 1, 1, 2, 2, 0, 3, 1, 1, 2, 0, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 1, 2, 1, 2, 2, 0, 1, 2, 3, 1, 2, 0, 0, 0, 2, 1, 1, 1, 1, 1, 2, 0, 0, 1, 1, 0, 0, 0, 0, 1, 2, 1, 2, 2, 2, 1, 2, 1, 2, 0, 2, 0, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 2, 3, 2, 3, 3, 0, 1, 2, 2, 3, 1, 0, 1, 0, 2, 1, 2, 2, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 3, 2, 2, 1, 0, 0, 3, 2, 3, 2, 0, 0, 0, 1, 1, 3, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 2, 2, 3, 3, 1, 0, 1, 3, 2, 3, 1, 1, 1, 0, 1, 1, 1, 1, 1, 3, 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 1, 0, 1, 2, 3, 3, 2, 0, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 0, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 3, 2, 2, 1, 0, 0, 1, 1, 2, 2, 0, 3, 0, 1, 2, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 2, 3, 3, 0, 1, 0, 0, 0, 3, 3, 1, 0, 0, 1, 2, 2, 1, 0, 0, 0, 0, 2, 0, 0, 1, 1, 1, 0, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 2, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 2, 3, 3, 0, 1, 0, 0, 0, 2, 2, 0, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 0, 1, 0, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 0, 1, 3, 2, 2, 0, 1, 0, 1, 0, 2, 3, 2, 0, 0, 1, 2, 2, 1, 0, 0, 1, 1, 1, 0, 0, 2, 1, 0, 1, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 0, 2, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 2, 1, 1, 0, 1, 2, 2, 2, 0, 0, 1, 0, 0, 2, 2, 1, 1, 0, 0, 2, 1, 1, 0, 0, 0, 1, 2, 0, 0, 2, 1, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 2, 3, 0, 0, 0, 1, 0, 3, 2, 1, 0, 0, 1, 2, 1, 1, 0, 0, 0, 0, 2, 1, 0, 1, 1, 0, 0, 2, 1, 2, 1, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 2, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 3, 0, 0, 2, 1, 2, 2, 1, 0, 0, 2, 1, 2, 2, 0, 0, 0, 2, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 2, 0, 0, 0, 1, 2, 1, 2, 2, 1, 1, 2, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 3, 2, 0, 0, 0, 1, 0, 2, 2, 2, 0, 0, 0, 2, 2, 1, 0, 0, 0, 0, 3, 1, 1, 1, 1, 0, 0, 2, 1, 1, 1, 2, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 2, 3, 2, 0, 0, 0, 1, 0, 2, 2, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 0, 2, 1, 0, 1, 1, 0, 0, 2, 1, 1, 0, 2, 1, 1, 1, 1, 2, 1, 2, 1, 2, 0, 1, 1, 1, 0, 2, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 3, 1, 1, 2, 2, 2, 3, 2, 1, 1, 2, 2, 1, 1, 0, 1, 0, 2, 2, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 2, 1, 0, 0, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 1, 1, 1, 2, 2, 1, 1, 1, 2, 1, 2, 1, 1, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 0, 1, 2, 1, 1, 1, 0, 1, 1, 0, 0, 1, 2, 3, 2, 1, 0, 0, 2, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 1, 1, 2, 0, 2, 1, 1, 1, 0, 1, 2, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 2, 0, 0, 0, 0, 0, 1, 1, 2, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 0, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 2, 2, 0, 1, 1, 1, 0, 2, 2, 2, 0, 0, 0, 3, 2, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 2, 1, 0, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 2, 3, 0, 0, 0, 1, 0, 2, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 2, 0, 1, 0, 2, 1, 1, 1, 1, 1, 0, 2, 0, 0, 0, 1, 2, 1, 1, 1, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 2, 2, 2, 0, 0, 0, 1, 0, 2, 1, 2, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 0, 1, 1, 2, 2, 0, 0, 0, 1, 0, 2, 2, 2, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 2, 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 2, 1, 0, 0, 1, 1, 1, 2, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, 1, 2, 1, 1, 1, 1, 1, 2, 0, 2, 0, 1, 1, 0, 1, 2, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 1, 2, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 2, 1, 0, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 2, 2, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 2, 0, 0, 2, 2, 0, 0, 2, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 2, 0, 0, 3, 1, 0, 2, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 2, 1, 0, 1, 1, 1, 2, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 2, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 2, 1, 1, 1, 2, 1, 1, 1, 0, 1, 1, 2, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 2, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 2, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 2, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; const SequenceModel Latin2HungarianModel = { Latin2_HungarianCharToOrderMap, HungarianLangModel, (float)0.947368, true, "ISO-8859-2" }; const SequenceModel Win1250HungarianModel = { win1250HungarianCharToOrderMap, HungarianLangModel, (float)0.947368, true, "windows-1250" }; } diff --git a/src/probers/LangThaiModel.cpp b/src/probers/LangThaiModel.cpp index 3449641..fee5727 100644 --- a/src/probers/LangThaiModel.cpp +++ b/src/probers/LangThaiModel.cpp @@ -1,204 +1,186 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsSBCharSetProber.h" /**************************************************************** 255: Control characters that usually does not exist in any text 254: Carriage/Return 253: symbol (punctuation) that does not belong to word 252: 0 - 9 *****************************************************************/ namespace kencodingprober { //The following result for thai was collected from a limited sample (1M). //Character Mapping Table: const unsigned char TIS620CharToOrderMap[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 255, 255, 254, 255, 255, //00 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, //10 +253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, //20 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, //30 253, 182, 106, 107, 100, 183, 184, 185, 101, 94, 186, 187, 108, 109, 110, 111, //40 188, 189, 190, 89, 95, 112, 113, 191, 192, 193, 194, 253, 253, 253, 253, 253, //50 253, 64, 72, 73, 114, 74, 115, 116, 102, 81, 201, 117, 90, 103, 78, 82, //60 96, 202, 91, 79, 84, 104, 105, 97, 98, 92, 203, 253, 253, 253, 253, 253, //70 209, 210, 211, 212, 213, 88, 214, 215, 216, 217, 218, 219, 220, 118, 221, 222, 223, 224, 99, 85, 83, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 5, 30, 237, 24, 238, 75, 8, 26, 52, 34, 51, 119, 47, 58, 57, 49, 53, 55, 43, 20, 19, 44, 14, 48, 3, 17, 25, 39, 62, 31, 54, 45, 9, 16, 2, 61, 15, 239, 12, 42, 46, 18, 21, 76, 4, 66, 63, 22, 10, 1, 36, 23, 13, 40, 27, 32, 35, 86, 240, 241, 242, 243, 244, 11, 28, 41, 29, 33, 245, 50, 37, 6, 7, 67, 77, 38, 93, 246, 247, 68, 56, 59, 65, 69, 60, 70, 80, 71, 87, 248, 249, 250, 251, 252, 253, }; //Model Table: //total sequences: 100% //first 512 sequences: 92.6386% //first 1024 sequences:7.3177% //rest sequences: 1.0230% //negative sequences: 0.0436% const char ThaiLangModel[] = { 0, 1, 3, 3, 3, 3, 0, 0, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 3, 3, 3, 0, 3, 3, 3, 3, 0, 3, 3, 0, 0, 0, 1, 3, 0, 3, 3, 2, 3, 3, 0, 1, 2, 3, 3, 3, 3, 0, 2, 0, 2, 0, 0, 3, 2, 1, 2, 2, 3, 0, 3, 3, 2, 3, 0, 0, 3, 3, 0, 3, 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 2, 3, 0, 2, 2, 2, 3, 0, 2, 3, 0, 0, 0, 0, 1, 0, 1, 2, 3, 1, 1, 3, 2, 2, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 3, 3, 2, 3, 2, 3, 3, 2, 2, 2, 3, 1, 2, 3, 0, 3, 3, 2, 2, 1, 2, 3, 3, 1, 2, 0, 1, 3, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 3, 3, 2, 2, 3, 3, 3, 3, 1, 2, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 2, 2, 3, 3, 2, 2, 3, 2, 3, 2, 2, 3, 3, 1, 2, 3, 1, 2, 2, 3, 3, 1, 0, 2, 1, 0, 0, 3, 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 2, 3, 2, 2, 3, 3, 2, 2, 3, 2, 2, 2, 2, 1, 1, 3, 1, 2, 1, 1, 3, 2, 1, 0, 2, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 2, 3, 2, 3, 3, 2, 2, 3, 2, 3, 3, 2, 3, 1, 1, 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 1, 1, 3, 3, 2, 1, 0, 1, 2, 2, 0, 1, 3, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 2, 3, 0, 0, 2, 1, 1, 3, 3, 2, 3, 3, 2, 0, 0, 3, 3, 0, 3, 3, 0, 2, 2, 3, 1, 2, 2, 1, 1, 1, 0, 2, 2, 2, 0, 2, 2, 1, 1, 0, 2, 1, 0, 2, 0, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 2, 3, 3, 2, 0, 0, 3, 3, 0, 2, 3, 0, 2, 1, 2, 2, 2, 2, 1, 2, 0, 0, 2, 2, 2, 0, 2, 2, 1, 1, 0, 2, 1, 0, 2, 0, 0, 2, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 2, 3, 2, 3, 2, 0, 2, 2, 1, 3, 2, 1, 3, 2, 1, 2, 3, 2, 2, 3, 0, 2, 3, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 0, 0, 0, 0, 2, 0, 1, 2, 0, 1, 1, 1, 0, 1, 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 2, 3, 3, 2, 3, 2, 2, 2, 3, 2, 2, 3, 2, 2, 1, 2, 3, 2, 2, 3, 1, 3, 2, 2, 2, 3, 2, 2, 2, 3, 3, 2, 1, 3, 0, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 3, 0, 3, 3, 3, 3, 3, 0, 0, 3, 0, 2, 2, 3, 3, 3, 3, 3, 0, 0, 0, 1, 1, 3, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 0, 3, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 3, 3, 3, 0, 0, 2, 3, 0, 0, 3, 0, 3, 3, 2, 3, 3, 3, 3, 3, 0, 0, 3, 3, 3, 0, 0, 0, 3, 3, 0, 0, 3, 0, 0, 0, 0, 2, 0, 0, 2, 1, 1, 3, 0, 0, 1, 0, 0, 2, 3, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 3, 1, 2, 1, 3, 3, 2, 2, 1, 2, 2, 2, 3, 1, 1, 2, 0, 2, 1, 2, 1, 2, 2, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 1, 2, 3, 3, 3, 0, 2, 0, 2, 2, 0, 2, 1, 3, 2, 2, 1, 2, 1, 0, 0, 2, 2, 1, 0, 2, 1, 2, 2, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2, 1, 3, 3, 1, 1, 3, 0, 2, 3, 1, 1, 3, 2, 1, 1, 2, 0, 2, 2, 3, 2, 1, 1, 1, 1, 1, 2, 3, 0, 0, 1, 3, 1, 2, 1, 2, 0, 3, 0, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 3, 1, 1, 3, 2, 3, 3, 3, 1, 3, 2, 1, 3, 2, 1, 3, 2, 2, 2, 2, 1, 3, 3, 1, 2, 1, 3, 1, 2, 3, 0, 2, 1, 1, 3, 2, 2, 2, 1, 2, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 3, 2, 3, 2, 3, 3, 2, 3, 2, 3, 2, 3, 3, 2, 1, 0, 3, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 1, 2, 1, 1, 2, 2, 2, 3, 0, 1, 3, 1, 1, 1, 1, 0, 1, 1, 0, 2, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2, 3, 2, 2, 1, 1, 3, 2, 3, 2, 3, 2, 0, 3, 2, 2, 1, 2, 0, 2, 2, 2, 1, 2, 2, 2, 2, 1, 3, 2, 1, 2, 2, 1, 0, 2, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 3, 3, 3, 3, 2, 3, 1, 2, 3, 3, 2, 2, 3, 0, 1, 1, 2, 0, 3, 3, 2, 2, 3, 0, 1, 1, 3, 0, 0, 0, 0, 3, 1, 0, 3, 3, 0, 2, 0, 2, 1, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 2, 3, 2, 3, 3, 0, 1, 3, 1, 1, 2, 1, 2, 1, 1, 3, 1, 1, 0, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 2, 2, 2, 1, 1, 1, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 2, 1, 1, 2, 1, 3, 3, 2, 3, 2, 2, 3, 2, 2, 3, 1, 2, 2, 1, 2, 0, 3, 2, 1, 2, 2, 2, 2, 2, 1, 3, 2, 1, 2, 2, 2, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 3, 0, 2, 1, 0, 3, 2, 0, 0, 3, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 2, 2, 3, 0, 0, 1, 3, 0, 3, 2, 0, 3, 2, 2, 3, 3, 3, 3, 3, 1, 0, 2, 2, 2, 0, 2, 2, 1, 2, 0, 2, 3, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 2, 3, 1, 3, 3, 2, 3, 3, 0, 3, 3, 0, 3, 2, 2, 3, 2, 3, 3, 3, 0, 0, 2, 2, 3, 0, 1, 1, 1, 3, 0, 0, 3, 0, 0, 0, 2, 2, 0, 1, 3, 0, 1, 2, 2, 2, 3, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 3, 3, 2, 0, 3, 3, 2, 2, 3, 1, 3, 2, 1, 3, 2, 0, 1, 2, 2, 0, 2, 3, 2, 1, 0, 3, 0, 0, 0, 0, 3, 0, 0, 2, 3, 1, 3, 0, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 2, 2, 2, 1, 2, 0, 1, 3, 1, 1, 3, 1, 3, 0, 0, 2, 1, 1, 1, 1, 2, 1, 1, 1, 0, 2, 1, 0, 1, 1, 2, 0, 0, 0, 3, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 1, 0, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 3, 1, 1, 1, 2, 0, 1, 1, 2, 1, 2, 1, 3, 2, 0, 0, 3, 1, 1, 1, 1, 1, 3, 1, 0, 2, 3, 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 3, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 1, 3, 0, 0, 1, 2, 0, 0, 2, 0, 3, 3, 2, 3, 3, 3, 2, 3, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 1, 3, 3, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 2, 3, 1, 2, 3, 1, 0, 3, 0, 2, 2, 1, 0, 2, 1, 1, 2, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 2, 1, 0, 1, 1, 1, 3, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 0, 3, 1, 0, 1, 3, 1, 1, 1, 1, 1, 1, 0, 2, 0, 1, 3, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 3, 0, 2, 2, 1, 3, 3, 2, 3, 3, 0, 1, 1, 0, 2, 2, 1, 2, 1, 3, 3, 1, 0, 0, 3, 2, 0, 0, 0, 0, 2, 1, 0, 1, 0, 0, 0, 0, 1, 2, 0, 1, 1, 3, 1, 1, 2, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 3, 0, 0, 3, 0, 3, 1, 0, 1, 1, 1, 3, 2, 0, 0, 0, 3, 0, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 3, 2, 1, 3, 3, 1, 2, 2, 0, 1, 2, 1, 0, 1, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 3, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 2, 0, 3, 3, 3, 2, 2, 0, 1, 1, 0, 1, 3, 0, 0, 0, 2, 2, 0, 0, 0, 0, 3, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 2, 3, 1, 2, 0, 0, 2, 1, 0, 3, 1, 0, 1, 2, 0, 1, 1, 1, 1, 3, 0, 0, 3, 1, 1, 0, 2, 2, 1, 1, 0, 2, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 3, 1, 2, 0, 0, 2, 2, 0, 1, 2, 0, 1, 0, 1, 3, 1, 2, 1, 0, 0, 0, 2, 0, 3, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 2, 2, 0, 0, 0, 2, 0, 2, 1, 0, 1, 1, 0, 1, 1, 1, 2, 1, 0, 0, 1, 1, 1, 0, 2, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 2, 0, 1, 3, 1, 1, 1, 1, 0, 0, 0, 0, 3, 2, 0, 1, 0, 0, 0, 1, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 3, 2, 2, 0, 0, 0, 1, 0, 0, 0, 0, 2, 3, 2, 1, 2, 2, 3, 0, 0, 0, 2, 3, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 2, 2, 0, 1, 0, 0, 0, 0, 2, 0, 2, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 2, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 2, 0, 0, 1, 0, 3, 0, 1, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 2, 0, 0, 0, 0, 1, 0, 0, 1, 3, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 1, 1, 1, 2, 3, 0, 0, 2, 1, 1, 1, 1, 1, 0, 2, 1, 1, 0, 0, 0, 2, 1, 0, 1, 2, 1, 1, 0, 1, 2, 1, 0, 3, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 2, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 1, 1, 0, 2, 0, 0, 1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 1, 3, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 3, 3, 0, 0, 1, 1, 2, 0, 0, 1, 2, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, 0, 1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 2, 0, 1, 2, 0, 0, 1, 1, 0, 2, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 2, 1, 3, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 1, 0, 0, 2, 0, 0, 2, 0, 0, 1, 1, 2, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 3, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; const SequenceModel TIS620ThaiModel = { TIS620CharToOrderMap, ThaiLangModel, (float)0.926386, false, "TIS-620" }; } diff --git a/src/probers/UnicodeGroupProber.cpp b/src/probers/UnicodeGroupProber.cpp index e6ff6a7..797aded 100644 --- a/src/probers/UnicodeGroupProber.cpp +++ b/src/probers/UnicodeGroupProber.cpp @@ -1,151 +1,133 @@ /* -*- C++ -*- -* Copyright (C) 2008 -* -* -* 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. + SPDX-FileCopyrightText: 2008 Wang Kai + + SPDX-License-Identifier: MIT */ #include "UnicodeGroupProber.h" #include #include namespace kencodingprober { UnicodeGroupProber::UnicodeGroupProber(void) { mCodingSM[0] = new nsCodingStateMachine(&UTF8SMModel); mCodingSM[1] = new nsCodingStateMachine(&UCS2LESMModel); mCodingSM[2] = new nsCodingStateMachine(&UCS2BESMModel); mActiveSM = NUM_OF_UNICODE_CHARSETS; mState = eDetecting; mDetectedCharset = "UTF-8"; } UnicodeGroupProber::~UnicodeGroupProber(void) { for (unsigned int i = 0; i < NUM_OF_UNICODE_CHARSETS; i++) { delete mCodingSM[i]; } } void UnicodeGroupProber::Reset(void) { mState = eDetecting; for (unsigned int i = 0; i < NUM_OF_UNICODE_CHARSETS; i++) { mCodingSM[i]->Reset(); } mActiveSM = NUM_OF_UNICODE_CHARSETS; mDetectedCharset = "UTF-8"; } nsProbingState UnicodeGroupProber::HandleData(const char *aBuf, unsigned int aLen) { nsSMState codingState; static bool disableUTF16LE = false; static bool disableUTF16BE = false; double weight_zero; if (mActiveSM <= 0 || aLen < 2) { mState = eNotMe; return mState; } if (!(disableUTF16LE || disableUTF16BE)) { if (aLen % 2 != 0) { disableUTF16LE = true; disableUTF16BE = true; } const uint weight_BOM = sqrt((double)aLen) + aLen / 10.0; uint counts[5] = {0, 0, 0, 0, 0}; for (uint i = 0; i < 5; i++) { counts[i] = std::count(aBuf, aBuf + aLen, char(i)); } weight_zero = (2.0 * (counts[0] + counts[1] + counts[2] + counts[3] + counts[4]) + weight_BOM) / aLen; if (weight_zero < log(1.4142)) { disableUTF16LE = true; disableUTF16BE = true; } if (4 >= aBuf[1] && aBuf[1] >= 0 && QChar::isPrint(static_cast(aBuf[0]))) { disableUTF16BE = true; } else { disableUTF16LE = true; } if (disableUTF16BE) { mActiveSM--; } if (disableUTF16LE) { nsCodingStateMachine *t; t = mCodingSM[1]; mCodingSM[1] = mCodingSM[2]; mCodingSM[2] = t; mActiveSM--; } } for (uint i = 0; i < aLen; ++i) { for (int j = mActiveSM - 1; j >= 0; --j) { //byte is feed to all active state machine codingState = mCodingSM[j]->NextState(aBuf[i]); if (codingState == eError) { //got negative answer for this state machine, make it inactive mActiveSM--; if (mActiveSM == 0) { mState = eNotMe; return mState; } else if (j != (int)mActiveSM) { nsCodingStateMachine *t; t = mCodingSM[mActiveSM]; mCodingSM[mActiveSM] = mCodingSM[j]; mCodingSM[j] = t; } } else if (codingState == eItsMe) { mState = eFoundIt; mDetectedCharset = mCodingSM[j]->GetCodingStateMachine(); return mState; } else if (mState == eDetecting) { mDetectedCharset = mCodingSM[j]->GetCodingStateMachine(); }; } } return mState; } float UnicodeGroupProber::GetConfidence() { if (mState == eFoundIt) { return 0.99f; } else { return 0.0f; } } #ifdef DEBUG_PROBE void UnicodeGroupProber::DumpStatus() { GetConfidence(); for (uint i = 0; i < mActiveSM; i++) { qDebug() << "Unicode group" << mCodingSM[i]->DumpCurrentState() << mCodingSM[i]->GetCodingStateMachine(); } } #endif } diff --git a/src/probers/UnicodeGroupProber.h b/src/probers/UnicodeGroupProber.h index ba63721..a4ff166 100644 --- a/src/probers/UnicodeGroupProber.h +++ b/src/probers/UnicodeGroupProber.h @@ -1,65 +1,47 @@ /* -*- C++ -*- -* Copyright (C) 2008 -* -* -* 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. + SPDX-FileCopyrightText: 2008 Wang Kai + + SPDX-License-Identifier: MIT */ #ifndef UNICODEGROUPPROBER_H #define UNICODEGROUPPROBER_H #include "nsCharSetProber.h" #include "nsCodingStateMachine.h" #define NUM_OF_UNICODE_CHARSETS 3 namespace kencodingprober { class KCODECS_NO_EXPORT UnicodeGroupProber: public nsCharSetProber { public: UnicodeGroupProber(void); ~UnicodeGroupProber(void) override; nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override { return mDetectedCharset; } nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence() override; void SetOpion() override {} #ifdef DEBUG_PROBE void DumpStatus() override; #endif protected: void GetDistribution(unsigned int aCharLen, const char *aStr); nsCodingStateMachine *mCodingSM[NUM_OF_UNICODE_CHARSETS]; unsigned int mActiveSM; nsProbingState mState; const char *mDetectedCharset; }; } #endif /* UNICODEGROUPPROBER_H */ diff --git a/src/probers/nsBig5Prober.cpp b/src/probers/nsBig5Prober.cpp index aa74524..40c0ddc 100644 --- a/src/probers/nsBig5Prober.cpp +++ b/src/probers/nsBig5Prober.cpp @@ -1,82 +1,64 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsBig5Prober.h" namespace kencodingprober { void nsBig5Prober::Reset(void) { mCodingSM->Reset(); mState = eDetecting; mDistributionAnalyser.Reset(); } nsProbingState nsBig5Prober::HandleData(const char *aBuf, unsigned int aLen) { if (aLen == 0) return mState; nsSMState codingState; for (unsigned int i = 0; i < aLen; i++) { codingState = mCodingSM->NextState(aBuf[i]); if (codingState == eError) { mState = eNotMe; break; } if (codingState == eItsMe) { mState = eFoundIt; break; } if (codingState == eStart) { unsigned int charLen = mCodingSM->GetCurrentCharLen(); if (i == 0) { mLastChar[1] = aBuf[0]; mDistributionAnalyser.HandleOneChar(mLastChar, charLen); } else { mDistributionAnalyser.HandleOneChar(aBuf + i - 1, charLen); } } } mLastChar[0] = aBuf[aLen - 1]; if (mState == eDetecting) if (mDistributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) { mState = eFoundIt; } return mState; } float nsBig5Prober::GetConfidence(void) { float distribCf = mDistributionAnalyser.GetConfidence(); return (float)distribCf; } } diff --git a/src/probers/nsBig5Prober.h b/src/probers/nsBig5Prober.h index cb8614c..c17be26 100644 --- a/src/probers/nsBig5Prober.h +++ b/src/probers/nsBig5Prober.h @@ -1,72 +1,54 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsBig5Prober_h__ #define nsBig5Prober_h__ #include "nsCharSetProber.h" #include "nsCodingStateMachine.h" #include "CharDistribution.h" namespace kencodingprober { class KCODECS_NO_EXPORT nsBig5Prober: public nsCharSetProber { public: nsBig5Prober(void) { mCodingSM = new nsCodingStateMachine(&Big5SMModel); Reset(); } ~nsBig5Prober() override { delete mCodingSM; } nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override { return "Big5"; } nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {}; protected: void GetDistribution(unsigned int aCharLen, const char *aStr); nsCodingStateMachine *mCodingSM; nsProbingState mState; //Big5ContextAnalysis mContextAnalyser; Big5DistributionAnalysis mDistributionAnalyser; char mLastChar[2]; }; } #endif /* nsBig5Prober_h__ */ diff --git a/src/probers/nsCharSetProber.cpp b/src/probers/nsCharSetProber.cpp index f88995a..c759b04 100644 --- a/src/probers/nsCharSetProber.cpp +++ b/src/probers/nsCharSetProber.cpp @@ -1,120 +1,102 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsCharSetProber.h" #include namespace kencodingprober { //This filter applies to all scripts which do not use English characters bool nsCharSetProber::FilterWithoutEnglishLetters(const char *aBuf, unsigned int aLen, char **newBuf, unsigned int &newLen) { char *newptr; char *prevPtr, *curPtr; bool meetMSB = false; newptr = *newBuf = (char *)malloc(aLen); if (!newptr) { return false; } for (curPtr = prevPtr = (char *)aBuf; curPtr < aBuf + aLen; ++curPtr) { if (*curPtr & 0x80) { meetMSB = true; } else if (*curPtr < 'A' || (*curPtr > 'Z' && *curPtr < 'a') || *curPtr > 'z') { //current char is a symbol, most likely a punctuation. we treat it as segment delimiter if (meetMSB && curPtr > prevPtr) //this segment contains more than single symbol, and it has upper ASCII, we need to keep it { while (prevPtr < curPtr) { *newptr++ = *prevPtr++; } prevPtr++; *newptr++ = ' '; meetMSB = false; } else { //ignore current segment. (either because it is just a symbol or just an English word) prevPtr = curPtr + 1; } } } if (meetMSB && curPtr > prevPtr) while (prevPtr < curPtr) { *newptr++ = *prevPtr++; } newLen = newptr - *newBuf; return true; } //This filter applies to all scripts which contain both English characters and upper ASCII characters. bool nsCharSetProber::FilterWithEnglishLetters(const char *aBuf, unsigned int aLen, char **newBuf, unsigned int &newLen) { //do filtering to reduce load to probers char *newptr; char *prevPtr, *curPtr; bool isInTag = false; newptr = *newBuf = (char *)malloc(aLen); if (!newptr) { return false; } for (curPtr = prevPtr = (char *)aBuf; curPtr < aBuf + aLen; ++curPtr) { if (*curPtr == '>') { isInTag = false; } else if (*curPtr == '<') { isInTag = true; } if (!(*curPtr & 0x80) && (*curPtr < 'A' || (*curPtr > 'Z' && *curPtr < 'a') || *curPtr > 'z')) { if (curPtr > prevPtr && !isInTag) // Current segment contains more than just a symbol // and it is not inside a tag, keep it. { while (prevPtr < curPtr) { *newptr++ = *prevPtr++; } prevPtr++; *newptr++ = ' '; } else { prevPtr = curPtr + 1; } } } // If the current segment contains more than just a symbol // and it is not inside a tag then keep it. if (!isInTag) while (prevPtr < curPtr) { *newptr++ = *prevPtr++; } newLen = newptr - *newBuf; return true; } } diff --git a/src/probers/nsCharSetProber.h b/src/probers/nsCharSetProber.h index dc8b8a8..dd7c6ff 100644 --- a/src/probers/nsCharSetProber.h +++ b/src/probers/nsCharSetProber.h @@ -1,64 +1,46 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsCharSetProber_h__ #define nsCharSetProber_h__ #include "kencodingprober.h" namespace kencodingprober { typedef enum { eDetecting = 0, //We are still detecting, no sure answer yet, but caller can ask for confidence. eFoundIt = 1, //That's a positive answer eNotMe = 2 //Negative answer } nsProbingState; #define SHORTCUT_THRESHOLD (float)0.95 class KCODECS_NO_EXPORT nsCharSetProber { public: virtual ~nsCharSetProber() {} virtual const char *GetCharSetName() = 0; virtual nsProbingState HandleData(const char *aBuf, unsigned int aLen) = 0; virtual nsProbingState GetState(void) = 0; virtual void Reset(void) = 0; virtual float GetConfidence(void) = 0; virtual void SetOpion() = 0; #ifdef DEBUG_PROBE void DumpStatus() override {}; #endif // Helper functions used in the Latin1 and Group probers. // both functions Allocate a new buffer for newBuf. This buffer should be // freed by the caller using PR_FREEIF. // Both functions return false in case of memory allocation failure. static bool FilterWithoutEnglishLetters(const char *aBuf, unsigned int aLen, char **newBuf, unsigned int &newLen); static bool FilterWithEnglishLetters(const char *aBuf, unsigned int aLen, char **newBuf, unsigned int &newLen); }; } #endif /* nsCharSetProber_h__ */ diff --git a/src/probers/nsCodingStateMachine.h b/src/probers/nsCodingStateMachine.h index 83c824d..d70c269 100644 --- a/src/probers/nsCodingStateMachine.h +++ b/src/probers/nsCodingStateMachine.h @@ -1,126 +1,108 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsCodingStateMachine_h__ #define nsCodingStateMachine_h__ #include "kencodingprober.h" #include "kcodecs_export.h" #include "nsPkgInt.h" namespace kencodingprober { enum { eStart = 0, eError = 1, eItsMe = 2 }; using nsSMState = int; #define GETCLASS(c) GETFROMPCK(((unsigned char)(c)), mModel->classTable) //state machine model typedef struct { nsPkgInt classTable; unsigned int classFactor; nsPkgInt stateTable; const unsigned int *charLenTable; const char *name; } SMModel; class KCODECS_NO_EXPORT nsCodingStateMachine { public: nsCodingStateMachine(const SMModel *sm) { mCurrentState = eStart; mModel = sm; } nsSMState NextState(char c) { //for each byte we get its class KCODECS_NO_EXPORT , if it is first byte, we also get byte length unsigned int byteCls = GETCLASS(c); if (mCurrentState == eStart) { mCurrentBytePos = 0; mCurrentCharLen = mModel->charLenTable[byteCls]; } //from byte's class KCODECS_NO_EXPORT and stateTable, we get its next state mCurrentState = GETFROMPCK(mCurrentState * (mModel->classFactor) + byteCls, mModel->stateTable); mCurrentBytePos++; return mCurrentState; } unsigned int GetCurrentCharLen(void) { return mCurrentCharLen; } void Reset(void) { mCurrentState = eStart; } const char *GetCodingStateMachine() { return mModel->name; } #ifdef DEBUG_PROBE const char *DumpCurrentState() { switch (mCurrentState) { case eStart: return "eStart"; case eError: return "eError"; case eItsMe: return "eItsMe"; default: return "OK"; } } #endif protected: int mCurrentState; unsigned int mCurrentCharLen; unsigned int mCurrentBytePos; const SMModel *mModel; }; extern KCODECS_NO_EXPORT const SMModel UTF8SMModel; extern KCODECS_NO_EXPORT const SMModel Big5SMModel; extern KCODECS_NO_EXPORT const SMModel EUCJPSMModel; extern KCODECS_NO_EXPORT const SMModel EUCKRSMModel; extern KCODECS_NO_EXPORT const SMModel GB18030SMModel; extern KCODECS_NO_EXPORT const SMModel SJISSMModel; extern KCODECS_NO_EXPORT const SMModel UCS2LESMModel; extern KCODECS_NO_EXPORT const SMModel UCS2BESMModel; extern KCODECS_NO_EXPORT const SMModel HZSMModel; extern KCODECS_NO_EXPORT const SMModel ISO2022CNSMModel; extern KCODECS_NO_EXPORT const SMModel ISO2022JPSMModel; extern KCODECS_NO_EXPORT const SMModel ISO2022KRSMModel; } #endif /* nsCodingStateMachine_h__ */ diff --git a/src/probers/nsEUCJPProber.cpp b/src/probers/nsEUCJPProber.cpp index 44b99fe..6d3e066 100644 --- a/src/probers/nsEUCJPProber.cpp +++ b/src/probers/nsEUCJPProber.cpp @@ -1,91 +1,73 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ // for japanese encoding, obeserve characteristic: // 1, kana character (or hankaku?) often have hight frequency of appereance // 2, kana character often exist in group // 3, certain combination of kana is never used in japanese language #include "nsEUCJPProber.h" namespace kencodingprober { void nsEUCJPProber::Reset(void) { mCodingSM->Reset(); mState = eDetecting; mContextAnalyser.Reset(); mDistributionAnalyser.Reset(); } nsProbingState nsEUCJPProber::HandleData(const char *aBuf, unsigned int aLen) { if (aLen == 0) return mState; nsSMState codingState; for (unsigned int i = 0; i < aLen; i++) { codingState = mCodingSM->NextState(aBuf[i]); if (codingState == eError) { mState = eNotMe; break; } if (codingState == eItsMe) { mState = eFoundIt; break; } if (codingState == eStart) { unsigned int charLen = mCodingSM->GetCurrentCharLen(); if (i == 0) { mLastChar[1] = aBuf[0]; mContextAnalyser.HandleOneChar(mLastChar, charLen); mDistributionAnalyser.HandleOneChar(mLastChar, charLen); } else { mContextAnalyser.HandleOneChar(aBuf + i - 1, charLen); mDistributionAnalyser.HandleOneChar(aBuf + i - 1, charLen); } } } mLastChar[0] = aBuf[aLen - 1]; if (mState == eDetecting) if (mContextAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) { mState = eFoundIt; } return mState; } float nsEUCJPProber::GetConfidence(void) { float contxtCf = mContextAnalyser.GetConfidence(); float distribCf = mDistributionAnalyser.GetConfidence(); return (contxtCf > distribCf ? contxtCf : distribCf); } } diff --git a/src/probers/nsEUCJPProber.h b/src/probers/nsEUCJPProber.h index 83ff082..d59f21f 100644 --- a/src/probers/nsEUCJPProber.h +++ b/src/probers/nsEUCJPProber.h @@ -1,76 +1,58 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ // for S-JIS encoding, obeserve characteristic: // 1, kana character (or hankaku?) often have hight frequency of appereance // 2, kana character often exist in group // 3, certain combination of kana is never used in japanese language #ifndef nsEUCJPProber_h__ #define nsEUCJPProber_h__ #include "nsCharSetProber.h" #include "nsCodingStateMachine.h" #include "JpCntx.h" #include "CharDistribution.h" namespace kencodingprober { class KCODECS_NO_EXPORT nsEUCJPProber: public nsCharSetProber { public: nsEUCJPProber(void) { mCodingSM = new nsCodingStateMachine(&EUCJPSMModel); Reset(); } ~nsEUCJPProber(void) override { delete mCodingSM; } nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override { return "EUC-JP"; } nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {}; protected: nsCodingStateMachine *mCodingSM; nsProbingState mState; EUCJPContextAnalysis mContextAnalyser; EUCJPDistributionAnalysis mDistributionAnalyser; char mLastChar[2]; }; } #endif /* nsEUCJPProber_h__ */ diff --git a/src/probers/nsEUCKRProber.cpp b/src/probers/nsEUCKRProber.cpp index a640096..fb60741 100644 --- a/src/probers/nsEUCKRProber.cpp +++ b/src/probers/nsEUCKRProber.cpp @@ -1,85 +1,67 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsEUCKRProber.h" namespace kencodingprober { void nsEUCKRProber::Reset(void) { mCodingSM->Reset(); mState = eDetecting; mDistributionAnalyser.Reset(); //mContextAnalyser.Reset(); } nsProbingState nsEUCKRProber::HandleData(const char *aBuf, unsigned int aLen) { if (aLen == 0) return mState; nsSMState codingState; for (unsigned int i = 0; i < aLen; i++) { codingState = mCodingSM->NextState(aBuf[i]); if (codingState == eError) { mState = eNotMe; break; } if (codingState == eItsMe) { mState = eFoundIt; break; } if (codingState == eStart) { unsigned int charLen = mCodingSM->GetCurrentCharLen(); if (i == 0) { mLastChar[1] = aBuf[0]; mDistributionAnalyser.HandleOneChar(mLastChar, charLen); } else { mDistributionAnalyser.HandleOneChar(aBuf + i - 1, charLen); } } } mLastChar[0] = aBuf[aLen - 1]; if (mState == eDetecting) if (mDistributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) { mState = eFoundIt; } // else // mDistributionAnalyser.HandleData(aBuf, aLen); return mState; } float nsEUCKRProber::GetConfidence(void) { float distribCf = mDistributionAnalyser.GetConfidence(); return (float)distribCf; } } diff --git a/src/probers/nsEUCKRProber.h b/src/probers/nsEUCKRProber.h index 3c41e5b..cef4f1d 100644 --- a/src/probers/nsEUCKRProber.h +++ b/src/probers/nsEUCKRProber.h @@ -1,72 +1,54 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsEUCKRProber_h__ #define nsEUCKRProber_h__ #include "nsCharSetProber.h" #include "nsCodingStateMachine.h" #include "CharDistribution.h" namespace kencodingprober { class KCODECS_NO_EXPORT nsEUCKRProber: public nsCharSetProber { public: nsEUCKRProber(void) { mCodingSM = new nsCodingStateMachine(&EUCKRSMModel); Reset(); } ~nsEUCKRProber(void) override { delete mCodingSM; } nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override { return "EUC-KR"; } nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {} protected: void GetDistribution(unsigned int aCharLen, const char *aStr); nsCodingStateMachine *mCodingSM; nsProbingState mState; //EUCKRContextAnalysis mContextAnalyser; EUCKRDistributionAnalysis mDistributionAnalyser; char mLastChar[2]; }; } #endif /* nsEUCKRProber_h__ */ diff --git a/src/probers/nsEscCharsetProber.cpp b/src/probers/nsEscCharsetProber.cpp index de60ca6..0a2d9a8 100644 --- a/src/probers/nsEscCharsetProber.cpp +++ b/src/probers/nsEscCharsetProber.cpp @@ -1,90 +1,72 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsEscCharsetProber.h" namespace kencodingprober { nsEscCharSetProber::nsEscCharSetProber(void) { mCodingSM[0] = new nsCodingStateMachine(&HZSMModel); mCodingSM[1] = new nsCodingStateMachine(&ISO2022CNSMModel); mCodingSM[2] = new nsCodingStateMachine(&ISO2022JPSMModel); mCodingSM[3] = new nsCodingStateMachine(&ISO2022KRSMModel); mActiveSM = NUM_OF_ESC_CHARSETS; mState = eDetecting; mDetectedCharset = nullptr; } nsEscCharSetProber::~nsEscCharSetProber(void) { for (unsigned int i = 0; i < NUM_OF_ESC_CHARSETS; i++) { delete mCodingSM[i]; } } void nsEscCharSetProber::Reset(void) { mState = eDetecting; for (unsigned int i = 0; i < NUM_OF_ESC_CHARSETS; i++) { mCodingSM[i]->Reset(); } mActiveSM = NUM_OF_ESC_CHARSETS; mDetectedCharset = nullptr; } nsProbingState nsEscCharSetProber::HandleData(const char *aBuf, unsigned int aLen) { nsSMState codingState; int j; unsigned int i; for (i = 0; i < aLen && mState == eDetecting; i++) { for (j = mActiveSM - 1; j >= 0; j--) { //byte is feed to all active state machine codingState = mCodingSM[j]->NextState(aBuf[i]); if (codingState == eError) { //got negative answer for this state machine, make it inactive mActiveSM--; if (mActiveSM == 0) { mState = eNotMe; return mState; } else if (j != (int)mActiveSM) { nsCodingStateMachine *t; t = mCodingSM[mActiveSM]; mCodingSM[mActiveSM] = mCodingSM[j]; mCodingSM[j] = t; } } else if (codingState == eItsMe) { mState = eFoundIt; mDetectedCharset = mCodingSM[j]->GetCodingStateMachine(); return mState; } } } return mState; } } diff --git a/src/probers/nsEscCharsetProber.h b/src/probers/nsEscCharsetProber.h index b559c2f..21e29f7 100644 --- a/src/probers/nsEscCharsetProber.h +++ b/src/probers/nsEscCharsetProber.h @@ -1,65 +1,47 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsEscCharSetProber_h__ #define nsEscCharSetProber_h__ #include "nsCharSetProber.h" #include "nsCodingStateMachine.h" #define NUM_OF_ESC_CHARSETS 4 namespace kencodingprober { class KCODECS_NO_EXPORT nsEscCharSetProber: public nsCharSetProber { public: nsEscCharSetProber(void); ~nsEscCharSetProber(void) override; nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override { return mDetectedCharset; } nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override { return (float)0.99; } void SetOpion() override {} protected: void GetDistribution(unsigned int aCharLen, const char *aStr); nsCodingStateMachine *mCodingSM[NUM_OF_ESC_CHARSETS]; unsigned int mActiveSM; nsProbingState mState; const char *mDetectedCharset; }; } #endif /* nsEscCharSetProber_h__ */ diff --git a/src/probers/nsEscSM.cpp b/src/probers/nsEscSM.cpp index ec134ed..37300bc 100644 --- a/src/probers/nsEscSM.cpp +++ b/src/probers/nsEscSM.cpp @@ -1,249 +1,231 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsCodingStateMachine.h" namespace kencodingprober { static const unsigned int HZ_cls[ 256 / 8 ] = { PCK4BITS(1, 0, 0, 0, 0, 0, 0, 0), // 00 - 07 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 08 - 0f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 10 - 17 PCK4BITS(0, 0, 0, 1, 0, 0, 0, 0), // 18 - 1f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 20 - 27 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 28 - 2f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 30 - 37 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 38 - 3f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 40 - 47 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 48 - 4f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 50 - 57 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 58 - 5f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 60 - 67 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 68 - 6f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 70 - 77 PCK4BITS(0, 0, 0, 4, 0, 5, 2, 0), // 78 - 7f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 80 - 87 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 88 - 8f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 90 - 97 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 98 - 9f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // a0 - a7 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // a8 - af PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // b0 - b7 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // b8 - bf PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // c0 - c7 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // c8 - cf PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // d0 - d7 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // d8 - df PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // e0 - e7 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // e8 - ef PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // f0 - f7 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1) // f8 - ff }; static const unsigned int HZ_st [ 6] = { PCK4BITS(eStart, eError, 3, eStart, eStart, eStart, eError, eError), //00-07 PCK4BITS(eError, eError, eError, eError, eItsMe, eItsMe, eItsMe, eItsMe), //08-0f PCK4BITS(eItsMe, eItsMe, eError, eError, eStart, eStart, 4, eError), //10-17 PCK4BITS(5, eError, 6, eError, 5, 5, 4, eError), //18-1f PCK4BITS(4, eError, 4, 4, 4, eError, 4, eError), //20-27 PCK4BITS(4, eItsMe, eStart, eStart, eStart, eStart, eStart, eStart) //28-2f }; static const unsigned int HZCharLenTable[] = {0, 0, 0, 0, 0, 0}; const SMModel HZSMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, HZ_cls }, 6, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, HZ_st }, HZCharLenTable, "HZ-GB-2312", }; static const unsigned int ISO2022CN_cls [ 256 / 8 ] = { PCK4BITS(2, 0, 0, 0, 0, 0, 0, 0), // 00 - 07 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 08 - 0f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 10 - 17 PCK4BITS(0, 0, 0, 1, 0, 0, 0, 0), // 18 - 1f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 20 - 27 PCK4BITS(0, 3, 0, 0, 0, 0, 0, 0), // 28 - 2f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 30 - 37 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 38 - 3f PCK4BITS(0, 0, 0, 4, 0, 0, 0, 0), // 40 - 47 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 48 - 4f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 50 - 57 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 58 - 5f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 60 - 67 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 68 - 6f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 70 - 77 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 78 - 7f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 80 - 87 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 88 - 8f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 90 - 97 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 98 - 9f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a0 - a7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a8 - af PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b0 - b7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b8 - bf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c0 - c7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c8 - cf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d0 - d7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d8 - df PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // e0 - e7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // e8 - ef PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // f0 - f7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2) // f8 - ff }; static const unsigned int ISO2022CN_st [ 8] = { PCK4BITS(eStart, 3, eError, eStart, eStart, eStart, eStart, eStart), //00-07 PCK4BITS(eStart, eError, eError, eError, eError, eError, eError, eError), //08-0f PCK4BITS(eError, eError, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe), //10-17 PCK4BITS(eItsMe, eItsMe, eItsMe, eError, eError, eError, 4, eError), //18-1f PCK4BITS(eError, eError, eError, eItsMe, eError, eError, eError, eError), //20-27 PCK4BITS(5, 6, eError, eError, eError, eError, eError, eError), //28-2f PCK4BITS(eError, eError, eError, eItsMe, eError, eError, eError, eError), //30-37 PCK4BITS(eError, eError, eError, eError, eError, eItsMe, eError, eStart) //38-3f }; static const unsigned int ISO2022CNCharLenTable[] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; const SMModel ISO2022CNSMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022CN_cls }, 9, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022CN_st }, ISO2022CNCharLenTable, "ISO-2022-CN", }; static const unsigned int ISO2022JP_cls [ 256 / 8 ] = { PCK4BITS(2, 0, 0, 0, 0, 0, 0, 0), // 00 - 07 PCK4BITS(0, 0, 0, 0, 0, 0, 2, 2), // 08 - 0f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 10 - 17 PCK4BITS(0, 0, 0, 1, 0, 0, 0, 0), // 18 - 1f PCK4BITS(0, 0, 0, 0, 7, 0, 0, 0), // 20 - 27 PCK4BITS(3, 0, 0, 0, 0, 0, 0, 0), // 28 - 2f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 30 - 37 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 38 - 3f PCK4BITS(6, 0, 4, 0, 8, 0, 0, 0), // 40 - 47 PCK4BITS(0, 9, 5, 0, 0, 0, 0, 0), // 48 - 4f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 50 - 57 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 58 - 5f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 60 - 67 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 68 - 6f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 70 - 77 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 78 - 7f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 80 - 87 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 88 - 8f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 90 - 97 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 98 - 9f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a0 - a7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a8 - af PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b0 - b7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b8 - bf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c0 - c7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c8 - cf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d0 - d7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d8 - df PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // e0 - e7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // e8 - ef PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // f0 - f7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2) // f8 - ff }; static const unsigned int ISO2022JP_st [ 9] = { PCK4BITS(eStart, 3, eError, eStart, eStart, eStart, eStart, eStart), //00-07 PCK4BITS(eStart, eStart, eError, eError, eError, eError, eError, eError), //08-0f PCK4BITS(eError, eError, eError, eError, eItsMe, eItsMe, eItsMe, eItsMe), //10-17 PCK4BITS(eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eError, eError), //18-1f PCK4BITS(eError, 5, eError, eError, eError, 4, eError, eError), //20-27 PCK4BITS(eError, eError, eError, 6, eItsMe, eError, eItsMe, eError), //28-2f PCK4BITS(eError, eError, eError, eError, eError, eError, eItsMe, eItsMe), //30-37 PCK4BITS(eError, eError, eError, eItsMe, eError, eError, eError, eError), //38-3f PCK4BITS(eError, eError, eError, eError, eItsMe, eError, eStart, eStart) //40-47 }; static const unsigned int ISO2022JPCharLenTable[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const SMModel ISO2022JPSMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022JP_cls }, 10, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022JP_st }, ISO2022JPCharLenTable, "ISO-2022-JP", }; static const unsigned int ISO2022KR_cls [ 256 / 8 ] = { PCK4BITS(2, 0, 0, 0, 0, 0, 0, 0), // 00 - 07 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 08 - 0f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 10 - 17 PCK4BITS(0, 0, 0, 1, 0, 0, 0, 0), // 18 - 1f PCK4BITS(0, 0, 0, 0, 3, 0, 0, 0), // 20 - 27 PCK4BITS(0, 4, 0, 0, 0, 0, 0, 0), // 28 - 2f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 30 - 37 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 38 - 3f PCK4BITS(0, 0, 0, 5, 0, 0, 0, 0), // 40 - 47 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 48 - 4f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 50 - 57 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 58 - 5f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 60 - 67 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 68 - 6f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 70 - 77 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 78 - 7f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 80 - 87 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 88 - 8f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 90 - 97 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 98 - 9f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a0 - a7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a8 - af PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b0 - b7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b8 - bf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c0 - c7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c8 - cf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d0 - d7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d8 - df PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // e0 - e7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // e8 - ef PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // f0 - f7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2) // f8 - ff }; static const unsigned int ISO2022KR_st [ 5] = { PCK4BITS(eStart, 3, eError, eStart, eStart, eStart, eError, eError), //00-07 PCK4BITS(eError, eError, eError, eError, eItsMe, eItsMe, eItsMe, eItsMe), //08-0f PCK4BITS(eItsMe, eItsMe, eError, eError, eError, 4, eError, eError), //10-17 PCK4BITS(eError, eError, eError, eError, 5, eError, eError, eError), //18-1f PCK4BITS(eError, eError, eError, eItsMe, eStart, eStart, eStart, eStart) //20-27 }; static const unsigned int ISO2022KRCharLenTable[] = {0, 0, 0, 0, 0, 0}; const SMModel ISO2022KRSMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022KR_cls }, 6, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, ISO2022KR_st }, ISO2022KRCharLenTable, "ISO-2022-KR", }; } diff --git a/src/probers/nsGB2312Prober.cpp b/src/probers/nsGB2312Prober.cpp index 057da7d..f454a5a 100644 --- a/src/probers/nsGB2312Prober.cpp +++ b/src/probers/nsGB2312Prober.cpp @@ -1,90 +1,72 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ // for S-JIS encoding, obeserve characteristic: // 1, kana character (or hankaku?) often have hight frequency of appereance // 2, kana character often exist in group // 3, certain combination of kana is never used in japanese language #include "nsGB2312Prober.h" namespace kencodingprober { void nsGB18030Prober::Reset(void) { mCodingSM->Reset(); mState = eDetecting; mDistributionAnalyser.Reset(); //mContextAnalyser.Reset(); } nsProbingState nsGB18030Prober::HandleData(const char *aBuf, unsigned int aLen) { if (aLen == 0) return mState; nsSMState codingState; for (unsigned int i = 0; i < aLen; i++) { codingState = mCodingSM->NextState(aBuf[i]); if (codingState == eError) { mState = eNotMe; break; } if (codingState == eItsMe) { mState = eFoundIt; break; } if (codingState == eStart) { unsigned int charLen = mCodingSM->GetCurrentCharLen(); if (i == 0) { mLastChar[1] = aBuf[0]; mDistributionAnalyser.HandleOneChar(mLastChar, charLen); } else { mDistributionAnalyser.HandleOneChar(aBuf + i - 1, charLen); } } } mLastChar[0] = aBuf[aLen - 1]; if (mState == eDetecting) if (mDistributionAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) { mState = eFoundIt; } // else // mDistributionAnalyser.HandleData(aBuf, aLen); return mState; } float nsGB18030Prober::GetConfidence(void) { float distribCf = mDistributionAnalyser.GetConfidence(); return (float)distribCf; } } diff --git a/src/probers/nsGB2312Prober.h b/src/probers/nsGB2312Prober.h index 7632f20..1a00b47 100644 --- a/src/probers/nsGB2312Prober.h +++ b/src/probers/nsGB2312Prober.h @@ -1,74 +1,56 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsGB2312Prober_h__ #define nsGB2312Prober_h__ #include "nsCharSetProber.h" #include "nsCodingStateMachine.h" #include "CharDistribution.h" // We use gb18030 to replace gb2312, because 18030 is a superset. namespace kencodingprober { class KCODECS_NO_EXPORT nsGB18030Prober: public nsCharSetProber { public: nsGB18030Prober(void) { mCodingSM = new nsCodingStateMachine(&GB18030SMModel); Reset(); } ~nsGB18030Prober(void) override { delete mCodingSM; } nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override { return "gb18030"; } nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {} protected: void GetDistribution(unsigned int aCharLen, const char *aStr); nsCodingStateMachine *mCodingSM; nsProbingState mState; //GB2312ContextAnalysis mContextAnalyser; GB2312DistributionAnalysis mDistributionAnalyser; char mLastChar[2]; }; } #endif /* nsGB2312Prober_h__ */ diff --git a/src/probers/nsHebrewProber.cpp b/src/probers/nsHebrewProber.cpp index 5a3c456..1603801 100644 --- a/src/probers/nsHebrewProber.cpp +++ b/src/probers/nsHebrewProber.cpp @@ -1,188 +1,170 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsHebrewProber.h" #include // windows-1255 / ISO-8859-8 code points of interest #define FINAL_KAF ('\xea') #define NORMAL_KAF ('\xeb') #define FINAL_MEM ('\xed') #define NORMAL_MEM ('\xee') #define FINAL_NUN ('\xef') #define NORMAL_NUN ('\xf0') #define FINAL_PE ('\xf3') #define NORMAL_PE ('\xf4') #define FINAL_TSADI ('\xf5') #define NORMAL_TSADI ('\xf6') // Minimum Visual vs Logical final letter score difference. // If the difference is below this, don't rely solely on the final letter score distance. #define MIN_FINAL_CHAR_DISTANCE (5) // Minimum Visual vs Logical model score difference. // If the difference is below this, don't rely at all on the model score distance. #define MIN_MODEL_DISTANCE (0.01) #define VISUAL_HEBREW_NAME ("ISO-8859-8") #define LOGICAL_HEBREW_NAME ("windows-1255") namespace kencodingprober { bool nsHebrewProber::isFinal(char c) { return ((c == FINAL_KAF) || (c == FINAL_MEM) || (c == FINAL_NUN) || (c == FINAL_PE) || (c == FINAL_TSADI)); } bool nsHebrewProber::isNonFinal(char c) { return ((c == NORMAL_KAF) || (c == NORMAL_MEM) || (c == NORMAL_NUN) || (c == NORMAL_PE)); // The normal Tsadi is not a good Non-Final letter due to words like // 'lechotet' (to chat) containing an apostrophe after the tsadi. This // apostrophe is converted to a space in FilterWithoutEnglishLetters causing // the Non-Final tsadi to appear at an end of a word even though this is not // the case in the original text. // The letters Pe and Kaf rarely display a related behavior of not being a // good Non-Final letter. Words like 'Pop', 'Winamp' and 'Mubarak' for // example legally end with a Non-Final Pe or Kaf. However, the benefit of // these letters as Non-Final letters outweighs the damage since these words // are quite rare. } /** HandleData * Final letter analysis for logical-visual decision. * Look for evidence that the received buffer is either logical Hebrew or * visual Hebrew. * The following cases are checked: * 1) A word longer than 1 letter, ending with a final letter. This is an * indication that the text is laid out "naturally" since the final letter * really appears at the end. +1 for logical score. * 2) A word longer than 1 letter, ending with a Non-Final letter. In normal * Hebrew, words ending with Kaf, Mem, Nun, Pe or Tsadi, should not end with * the Non-Final form of that letter. Exceptions to this rule are mentioned * above in isNonFinal(). This is an indication that the text is laid out * backwards. +1 for visual score * 3) A word longer than 1 letter, starting with a final letter. Final letters * should not appear at the beginning of a word. This is an indication that * the text is laid out backwards. +1 for visual score. * * The visual score and logical score are accumulated throughout the text and * are finally checked against each other in GetCharSetName(). * No checking for final letters in the middle of words is done since that case * is not an indication for either Logical or Visual text. * * The input buffer should not contain any white spaces that are not (' ') * or any low-ascii punctuation marks. */ nsProbingState nsHebrewProber::HandleData(const char *aBuf, unsigned int aLen) { // Both model probers say it's not them. No reason to continue. if (GetState() == eNotMe) { return eNotMe; } const char *curPtr, *endPtr = aBuf + aLen; char cur; for (curPtr = (char *)aBuf; curPtr < endPtr; ++curPtr) { cur = *curPtr; if (cur == ' ') { // We stand on a space - a word just ended if (mBeforePrev != ' ') { // *(curPtr-2) was not a space so prev is not a 1 letter word if (isFinal(mPrev)) { // case (1) [-2:not space][-1:final letter][cur:space] ++mFinalCharLogicalScore; } else if (isNonFinal(mPrev)) { // case (2) [-2:not space][-1:Non-Final letter][cur:space] ++mFinalCharVisualScore; } } } else { // Not standing on a space if ((mBeforePrev == ' ') && (isFinal(mPrev)) && (cur != ' ')) { // case (3) [-2:space][-1:final letter][cur:not space] ++mFinalCharVisualScore; } } mBeforePrev = mPrev; mPrev = cur; } // Forever detecting, till the end or until both model probers return eNotMe (handled above). return eDetecting; } // Make the decision: is it Logical or Visual? const char *nsHebrewProber::GetCharSetName() { // If the final letter score distance is dominant enough, rely on it. int finalsub = mFinalCharLogicalScore - mFinalCharVisualScore; if (finalsub >= MIN_FINAL_CHAR_DISTANCE) { return LOGICAL_HEBREW_NAME; } if (finalsub <= -(MIN_FINAL_CHAR_DISTANCE)) { return VISUAL_HEBREW_NAME; } // It's not dominant enough, try to rely on the model scores instead. float modelsub = mLogicalProb->GetConfidence() - mVisualProb->GetConfidence(); if (modelsub > MIN_MODEL_DISTANCE) { return LOGICAL_HEBREW_NAME; } if (modelsub < -(MIN_MODEL_DISTANCE)) { return VISUAL_HEBREW_NAME; } // Still no good, back to final letter distance, maybe it'll save the day. if (finalsub < 0) { return VISUAL_HEBREW_NAME; } // (finalsub > 0 - Logical) or (don't know what to do) default to Logical. return LOGICAL_HEBREW_NAME; } void nsHebrewProber::Reset(void) { mFinalCharLogicalScore = 0; mFinalCharVisualScore = 0; // mPrev and mBeforePrev are initialized to space in order to simulate a word // delimiter at the beginning of the data mPrev = ' '; mBeforePrev = ' '; } nsProbingState nsHebrewProber::GetState(void) { // Remain active as long as any of the model probers are active. if ((mLogicalProb->GetState() == eNotMe) && (mVisualProb->GetState() == eNotMe)) { return eNotMe; } return eDetecting; } #ifdef DEBUG_PROBE void nsHebrewProber::DumpStatus() { printf(" HEB: %d - %d [Logical-Visual score]\r\n", mFinalCharLogicalScore, mFinalCharVisualScore); } #endif } diff --git a/src/probers/nsHebrewProber.h b/src/probers/nsHebrewProber.h index 631673c..6f7e666 100644 --- a/src/probers/nsHebrewProber.h +++ b/src/probers/nsHebrewProber.h @@ -1,174 +1,156 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsHebrewProber_h__ #define nsHebrewProber_h__ #include "nsSBCharSetProber.h" namespace kencodingprober { // This prober doesn't actually recognize a language or a charset. // It is a helper prober for the use of the Hebrew model probers class KCODECS_NO_EXPORT nsHebrewProber: public nsCharSetProber { public: nsHebrewProber(void) : mLogicalProb(nullptr), mVisualProb(nullptr) { Reset(); } ~nsHebrewProber(void) override {} nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override; void Reset(void) override; nsProbingState GetState(void) override; float GetConfidence(void) override { return (float)0.0; } void SetOpion() override {} void SetModelProbers(nsCharSetProber *logicalPrb, nsCharSetProber *visualPrb) { mLogicalProb = logicalPrb; mVisualProb = visualPrb; } #ifdef DEBUG_PROBE void DumpStatus() override; #endif protected: static bool isFinal(char c); static bool isNonFinal(char c); int mFinalCharLogicalScore, mFinalCharVisualScore; // The two last characters seen in the previous buffer. char mPrev, mBeforePrev; // These probers are owned by the group prober. nsCharSetProber *mLogicalProb, *mVisualProb; }; } /** * ** General ideas of the Hebrew charset recognition ** * * Four main charsets exist in Hebrew: * "ISO-8859-8" - Visual Hebrew * "windows-1255" - Logical Hebrew * "ISO-8859-8-I" - Logical Hebrew * "x-mac-hebrew" - ?? Logical Hebrew ?? * * Both "ISO" charsets use a completely identical set of code points, whereas * "windows-1255" and "x-mac-hebrew" are two different proper supersets of * these code points. windows-1255 defines additional characters in the range * 0x80-0x9F as some misc punctuation marks as well as some Hebrew-specific * diacritics and additional 'Yiddish' ligature letters in the range 0xc0-0xd6. * x-mac-hebrew defines similar additional code points but with a different * mapping. * * As far as an average Hebrew text with no diacritics is concerned, all four * charsets are identical with respect to code points. Meaning that for the * main Hebrew alphabet, all four map the same values to all 27 Hebrew letters * (including final letters). * * The dominant difference between these charsets is their directionality. * "Visual" directionality means that the text is ordered as if the renderer is * not aware of a BIDI rendering algorithm. The renderer sees the text and * draws it from left to right. The text itself when ordered naturally is read * backwards. A buffer of Visual Hebrew generally looks like so: * "[last word of first line spelled backwards] [whole line ordered backwards * and spelled backwards] [first word of first line spelled backwards] * [end of line] [last word of second line] ... etc' " * adding punctuation marks, numbers and English text to visual text is * naturally also "visual" and from left to right. * * "Logical" directionality means the text is ordered "naturally" according to * the order it is read. It is the responsibility of the renderer to display * the text from right to left. A BIDI algorithm is used to place general * punctuation marks, numbers and English text in the text. * * Texts in x-mac-hebrew are almost impossible to find on the Internet. From * what little evidence I could find, it seems that its general directionality * is Logical. * * To sum up all of the above, the Hebrew probing mechanism knows about two * charsets: * Visual Hebrew - "ISO-8859-8" - backwards text - Words and sentences are * backwards while line order is natural. For charset recognition purposes * the line order is unimportant (In fact, for this implementation, even * word order is unimportant). * Logical Hebrew - "windows-1255" - normal, naturally ordered text. * * "ISO-8859-8-I" is a subset of windows-1255 and doesn't need to be * specifically identified. * "x-mac-hebrew" is also identified as windows-1255. A text in x-mac-hebrew * that contain special punctuation marks or diacritics is displayed with * some unconverted characters showing as question marks. This problem might * be corrected using another model prober for x-mac-hebrew. Due to the fact * that x-mac-hebrew texts are so rare, writing another model prober isn't * worth the effort and performance hit. * * *** The Prober *** * * The prober is divided between two nsSBCharSetProbers and an nsHebrewProber, * all of which are managed, created, fed data, inquired and deleted by the * nsSBCSGroupProber. The two nsSBCharSetProbers identify that the text is in * fact some kind of Hebrew, Logical or Visual. The final decision about which * one is it is made by the nsHebrewProber by combining final-letter scores * with the scores of the two nsSBCharSetProbers to produce a final answer. * * The nsSBCSGroupProber is responsible for stripping the original text of HTML * tags, English characters, numbers, low-ASCII punctuation characters, spaces * and new lines. It reduces any sequence of such characters to a single space. * The buffer fed to each prober in the SBCS group prober is pure text in * high-ASCII. * The two nsSBCharSetProbers (model probers) share the same language model: * Win1255Model. * The first nsSBCharSetProber uses the model normally as any other * nsSBCharSetProber does, to recognize windows-1255, upon which this model was * built. The second nsSBCharSetProber is told to make the pair-of-letter * lookup in the language model backwards. This in practice exactly simulates * a visual Hebrew model using the windows-1255 logical Hebrew model. * * The nsHebrewProber is not using any language model. All it does is look for * final-letter evidence suggesting the text is either logical Hebrew or visual * Hebrew. Disjointed from the model probers, the results of the nsHebrewProber * alone are meaningless. nsHebrewProber always returns 0.00 as confidence * since it never identifies a charset by itself. Instead, the pointer to the * nsHebrewProber is passed to the model probers as a helper "Name Prober". * When the Group prober receives a positive identification from any prober, * it asks for the name of the charset identified. If the prober queried is a * Hebrew model prober, the model prober forwards the call to the * nsHebrewProber to make the final decision. In the nsHebrewProber, the * decision is made according to the final-letters scores maintained and Both * model probers scores. The answer is returned in the form of the name of the * charset identified, either "windows-1255" or "ISO-8859-8". * */ #endif /* nsHebrewProber_h__ */ diff --git a/src/probers/nsLatin1Prober.cpp b/src/probers/nsLatin1Prober.cpp index 496877f..c60a127 100644 --- a/src/probers/nsLatin1Prober.cpp +++ b/src/probers/nsLatin1Prober.cpp @@ -1,169 +1,151 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsLatin1Prober.h" #include #include #define UDF 0 // undefined #define OTH 1 //other #define ASC 2 // ascii capital letter #define ASS 3 // ascii small letter #define ACV 4 // accent capital vowel #define ACO 5 // accent capital other #define ASV 6 // accent small vowel #define ASO 7 // accent small other #define CLASS_NUM 8 // total classes namespace kencodingprober { static const unsigned char Latin1_CharToClass[] = { OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 00 - 07 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 08 - 0F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 10 - 17 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 18 - 1F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 20 - 27 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 28 - 2F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 30 - 37 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 38 - 3F OTH, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 40 - 47 ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 48 - 4F ASC, ASC, ASC, ASC, ASC, ASC, ASC, ASC, // 50 - 57 ASC, ASC, ASC, OTH, OTH, OTH, OTH, OTH, // 58 - 5F OTH, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 60 - 67 ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 68 - 6F ASS, ASS, ASS, ASS, ASS, ASS, ASS, ASS, // 70 - 77 ASS, ASS, ASS, OTH, OTH, OTH, OTH, OTH, // 78 - 7F OTH, UDF, OTH, ASO, OTH, OTH, OTH, OTH, // 80 - 87 OTH, OTH, ACO, OTH, ACO, UDF, ACO, UDF, // 88 - 8F UDF, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // 90 - 97 OTH, OTH, ASO, OTH, ASO, UDF, ASO, ACO, // 98 - 9F OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // A0 - A7 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // A8 - AF OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // B0 - B7 OTH, OTH, OTH, OTH, OTH, OTH, OTH, OTH, // B8 - BF ACV, ACV, ACV, ACV, ACV, ACV, ACO, ACO, // C0 - C7 ACV, ACV, ACV, ACV, ACV, ACV, ACV, ACV, // C8 - CF ACO, ACO, ACV, ACV, ACV, ACV, ACV, OTH, // D0 - D7 ACV, ACV, ACV, ACV, ACV, ACO, ACO, ACO, // D8 - DF ASV, ASV, ASV, ASV, ASV, ASV, ASO, ASO, // E0 - E7 ASV, ASV, ASV, ASV, ASV, ASV, ASV, ASV, // E8 - EF ASO, ASO, ASV, ASV, ASV, ASV, ASV, OTH, // F0 - F7 ASV, ASV, ASV, ASV, ASV, ASO, ASO, ASO, // F8 - FF }; /* 0 : illegal 1 : very unlikely 2 : normal 3 : very likely */ static const unsigned char Latin1ClassModel[] = { /* UDF OTH ASC ASS ACV ACO ASV ASO */ /*UDF*/ 0, 0, 0, 0, 0, 0, 0, 0, /*OTH*/ 0, 3, 3, 3, 3, 3, 3, 3, /*ASC*/ 0, 3, 3, 3, 3, 3, 3, 3, /*ASS*/ 0, 3, 3, 3, 1, 1, 3, 3, /*ACV*/ 0, 3, 3, 3, 1, 2, 1, 2, /*ACO*/ 0, 3, 3, 3, 3, 3, 3, 3, /*ASV*/ 0, 3, 1, 3, 1, 1, 1, 3, /*ASO*/ 0, 3, 1, 3, 1, 1, 3, 3, }; void nsLatin1Prober::Reset(void) { mState = eDetecting; mLastCharClass = OTH; for (int i = 0; i < FREQ_CAT_NUM; i++) { mFreqCounter[i] = 0; } } nsProbingState nsLatin1Prober::HandleData(const char *aBuf, unsigned int aLen) { char *newBuf1 = nullptr; unsigned int newLen1 = 0; if (!FilterWithEnglishLetters(aBuf, aLen, &newBuf1, newLen1)) { newBuf1 = (char *)aBuf; newLen1 = aLen; } unsigned char charClass; unsigned char freq; for (unsigned int i = 0; i < newLen1; i++) { charClass = Latin1_CharToClass[(unsigned char)newBuf1[i]]; freq = Latin1ClassModel[mLastCharClass * CLASS_NUM + charClass]; if (freq == 0) { mState = eNotMe; break; } mFreqCounter[freq]++; mLastCharClass = charClass; } if (newBuf1 != aBuf) { free(newBuf1); } return mState; } float nsLatin1Prober::GetConfidence(void) { if (mState == eNotMe) { return 0.01f; } float confidence; unsigned int total = 0; for (int i = 0; i < FREQ_CAT_NUM; i++) { total += mFreqCounter[i]; } if (!total) { confidence = 0.0f; } else { confidence = mFreqCounter[3] * 1.0f / total; confidence -= mFreqCounter[1] * 20.0f / total; } if (confidence < 0.0f) { confidence = 0.0f; } // lower the confidence of latin1 so that other more accurate detector // can take priority. confidence *= 0.50f; return confidence; } #ifdef DEBUG_PROBE void nsLatin1Prober::DumpStatus() { printf(" Latin1Prober: %1.3f [%s]\r\n", GetConfidence(), GetCharSetName()); } #endif } diff --git a/src/probers/nsLatin1Prober.h b/src/probers/nsLatin1Prober.h index b4a755e..5150705 100644 --- a/src/probers/nsLatin1Prober.h +++ b/src/probers/nsLatin1Prober.h @@ -1,67 +1,49 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsLatin1Prober_h__ #define nsLatin1Prober_h__ #include "nsCharSetProber.h" #define FREQ_CAT_NUM 4 namespace kencodingprober { class KCODECS_NO_EXPORT nsLatin1Prober: public nsCharSetProber { public: nsLatin1Prober(void) { Reset(); } ~nsLatin1Prober(void) override {} nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override { return "windows-1252"; } nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {} #ifdef DEBUG_PROBE void DumpStatus() override; #endif protected: nsProbingState mState; char mLastCharClass; unsigned int mFreqCounter[FREQ_CAT_NUM]; }; } #endif /* nsLatin1Prober_h__ */ diff --git a/src/probers/nsMBCSGroupProber.cpp b/src/probers/nsMBCSGroupProber.cpp index 67403c7..23b2d87 100644 --- a/src/probers/nsMBCSGroupProber.cpp +++ b/src/probers/nsMBCSGroupProber.cpp @@ -1,182 +1,164 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsMBCSGroupProber.h" #include #include namespace kencodingprober { #ifdef DEBUG_PROBE static const char *const ProberName[] = { "Unicode", "SJIS", "EUCJP", "GB18030", "EUCKR", "Big5", }; #endif nsMBCSGroupProber::nsMBCSGroupProber() { mProbers[0] = new UnicodeGroupProber(); mProbers[1] = new nsSJISProber(); mProbers[2] = new nsEUCJPProber(); mProbers[3] = new nsGB18030Prober(); mProbers[4] = new nsEUCKRProber(); mProbers[5] = new nsBig5Prober(); Reset(); } nsMBCSGroupProber::~nsMBCSGroupProber() { for (unsigned int i = 0; i < NUM_OF_PROBERS; i++) { delete mProbers[i]; } } const char *nsMBCSGroupProber::GetCharSetName() { if (mBestGuess == -1) { GetConfidence(); if (mBestGuess == -1) { mBestGuess = 0; } } return mProbers[mBestGuess]->GetCharSetName(); } void nsMBCSGroupProber::Reset(void) { mActiveNum = 0; for (unsigned int i = 0; i < NUM_OF_PROBERS; i++) { if (mProbers[i]) { mProbers[i]->Reset(); mIsActive[i] = true; ++mActiveNum; } else { mIsActive[i] = false; } } mBestGuess = -1; mState = eDetecting; } nsProbingState nsMBCSGroupProber::HandleData(const char *aBuf, unsigned int aLen) { nsProbingState st; unsigned int i; //do filtering to reduce load to probers char *highbyteBuf; char *hptr; bool keepNext = true; //assume previous is not ascii, it will do no harm except add some noise hptr = highbyteBuf = (char *)malloc(aLen); if (!hptr) { return mState; } for (i = 0; i < aLen; ++i) { if (aBuf[i] & 0x80) { *hptr++ = aBuf[i]; keepNext = true; } else { //if previous is highbyte, keep this even it is a ASCII if (keepNext) { *hptr++ = aBuf[i]; keepNext = false; } } } for (i = 0; i < NUM_OF_PROBERS; ++i) { if (!mIsActive[i]) { continue; } st = mProbers[i]->HandleData(highbyteBuf, hptr - highbyteBuf); if (st == eFoundIt) { mBestGuess = i; mState = eFoundIt; break; } else if (st == eNotMe) { mIsActive[i] = false; mActiveNum--; if (mActiveNum <= 0) { mState = eNotMe; break; } } } free(highbyteBuf); return mState; } float nsMBCSGroupProber::GetConfidence(void) { unsigned int i; float bestConf = 0.0, cf; switch (mState) { case eFoundIt: return (float)0.99; case eNotMe: return (float)0.01; default: for (i = 0; i < NUM_OF_PROBERS; ++i) { if (!mIsActive[i]) { continue; } cf = mProbers[i]->GetConfidence(); if (bestConf < cf) { bestConf = cf; mBestGuess = i; } } } return bestConf; } #ifdef DEBUG_PROBE void nsMBCSGroupProber::DumpStatus() { unsigned int i; float cf; GetConfidence(); for (i = 0; i < NUM_OF_PROBERS; i++) { if (!mIsActive[i]) { printf(" MBCS inactive: [%s] (confidence is too low).\r\n", ProberName[i]); } else { cf = mProbers[i]->GetConfidence(); printf(" MBCS %1.3f: [%s]\r\n", cf, ProberName[i]); } } } #endif } diff --git a/src/probers/nsMBCSGroupProber.h b/src/probers/nsMBCSGroupProber.h index 64af5c6..4b1a622 100644 --- a/src/probers/nsMBCSGroupProber.h +++ b/src/probers/nsMBCSGroupProber.h @@ -1,67 +1,49 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsMBCSGroupProber_h__ #define nsMBCSGroupProber_h__ #include "nsSJISProber.h" #include "UnicodeGroupProber.h" #include "nsEUCJPProber.h" #include "nsGB2312Prober.h" #include "nsEUCKRProber.h" #include "nsBig5Prober.h" #define NUM_OF_PROBERS 6 namespace kencodingprober { class KCODECS_NO_EXPORT nsMBCSGroupProber: public nsCharSetProber { public: nsMBCSGroupProber(); ~nsMBCSGroupProber() override; nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override; nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {} #ifdef DEBUG_PROBE void DumpStatus() override; #endif protected: nsProbingState mState; nsCharSetProber *mProbers[NUM_OF_PROBERS]; bool mIsActive[NUM_OF_PROBERS]; int mBestGuess; unsigned int mActiveNum; }; } #endif /* nsMBCSGroupProber_h__ */ diff --git a/src/probers/nsMBCSSM.cpp b/src/probers/nsMBCSSM.cpp index fae8ec1..3a3ba04 100644 --- a/src/probers/nsMBCSSM.cpp +++ b/src/probers/nsMBCSSM.cpp @@ -1,551 +1,533 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsCodingStateMachine.h" /* Modification from frank tang's original work: . 0x00 is allowed as a legal character. Since some web pages contains this char in text stream. */ // BIG5 namespace kencodingprober { static const unsigned int BIG5_cls [ 256 / 8 ] = { //PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 00 - 07 //allow 0x00 as legal value PCK4BITS(1, 1, 1, 1, 1, 1, 0, 0), // 08 - 0f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 10 - 17 PCK4BITS(1, 1, 1, 0, 1, 1, 1, 1), // 18 - 1f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 20 - 27 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 28 - 2f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 30 - 37 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 38 - 3f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 40 - 47 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 48 - 4f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 50 - 57 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 58 - 5f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 60 - 67 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 68 - 6f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 70 - 77 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 1), // 78 - 7f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 80 - 87 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 88 - 8f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 90 - 97 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 98 - 9f PCK4BITS(4, 3, 3, 3, 3, 3, 3, 3), // a0 - a7 PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // a8 - af PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // b0 - b7 PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // b8 - bf PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // c0 - c7 PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // c8 - cf PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // d0 - d7 PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // d8 - df PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // e0 - e7 PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // e8 - ef PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // f0 - f7 PCK4BITS(3, 3, 3, 3, 3, 3, 3, 0) // f8 - ff }; static const unsigned int BIG5_st [ 3] = { PCK4BITS(eError, eStart, eStart, 3, eError, eError, eError, eError), //00-07 PCK4BITS(eError, eError, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eError), //08-0f PCK4BITS(eError, eStart, eStart, eStart, eStart, eStart, eStart, eStart) //10-17 }; static const unsigned int Big5CharLenTable[] = {0, 1, 1, 2, 0}; const SMModel Big5SMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, BIG5_cls }, 5, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, BIG5_st }, Big5CharLenTable, "Big5", }; static const unsigned int EUCJP_cls [ 256 / 8 ] = { //PCK4BITS(5,4,4,4,4,4,4,4), // 00 - 07 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 00 - 07 PCK4BITS(4, 4, 4, 4, 4, 4, 5, 5), // 08 - 0f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 10 - 17 PCK4BITS(4, 4, 4, 5, 4, 4, 4, 4), // 18 - 1f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 20 - 27 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 28 - 2f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 30 - 37 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 38 - 3f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 40 - 47 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 48 - 4f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 50 - 57 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 58 - 5f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 60 - 67 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 68 - 6f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 70 - 77 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 78 - 7f PCK4BITS(5, 5, 5, 5, 5, 5, 5, 5), // 80 - 87 PCK4BITS(5, 5, 5, 5, 5, 5, 1, 3), // 88 - 8f PCK4BITS(5, 5, 5, 5, 5, 5, 5, 5), // 90 - 97 PCK4BITS(5, 5, 5, 5, 5, 5, 5, 5), // 98 - 9f PCK4BITS(5, 2, 2, 2, 2, 2, 2, 2), // a0 - a7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a8 - af PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b0 - b7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b8 - bf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c0 - c7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c8 - cf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d0 - d7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d8 - df PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // e0 - e7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // e8 - ef PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // f0 - f7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 5) // f8 - ff }; static const unsigned int EUCJP_st [ 5] = { PCK4BITS(3, 4, 3, 5, eStart, eError, eError, eError), //00-07 PCK4BITS(eError, eError, eError, eError, eItsMe, eItsMe, eItsMe, eItsMe), //08-0f PCK4BITS(eItsMe, eItsMe, eStart, eError, eStart, eError, eError, eError), //10-17 PCK4BITS(eError, eError, eStart, eError, eError, eError, 3, eError), //18-1f PCK4BITS(3, eError, eError, eError, eStart, eStart, eStart, eStart) //20-27 }; static const unsigned int EUCJPCharLenTable[] = {2, 2, 2, 3, 1, 0}; const SMModel EUCJPSMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCJP_cls }, 6, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCJP_st }, EUCJPCharLenTable, "EUC-JP", }; static const unsigned int EUCKR_cls [ 256 / 8 ] = { //PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 00 - 07 PCK4BITS(1, 1, 1, 1, 1, 1, 0, 0), // 08 - 0f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 10 - 17 PCK4BITS(1, 1, 1, 0, 1, 1, 1, 1), // 18 - 1f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 20 - 27 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 28 - 2f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 30 - 37 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 38 - 3f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 40 - 47 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 48 - 4f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 50 - 57 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 58 - 5f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 60 - 67 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 68 - 6f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 70 - 77 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 78 - 7f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 80 - 87 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 88 - 8f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 90 - 97 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 98 - 9f PCK4BITS(0, 2, 2, 2, 2, 2, 2, 2), // a0 - a7 PCK4BITS(2, 2, 2, 2, 2, 3, 3, 3), // a8 - af PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b0 - b7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b8 - bf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c0 - c7 PCK4BITS(2, 3, 2, 2, 2, 2, 2, 2), // c8 - cf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d0 - d7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d8 - df PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // e0 - e7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // e8 - ef PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // f0 - f7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 0) // f8 - ff }; static const unsigned int EUCKR_st [ 2] = { PCK4BITS(eError, eStart, 3, eError, eError, eError, eError, eError), //00-07 PCK4BITS(eItsMe, eItsMe, eItsMe, eItsMe, eError, eError, eStart, eStart) //08-0f }; static const unsigned int EUCKRCharLenTable[] = {0, 1, 2, 0}; const SMModel EUCKRSMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCKR_cls }, 4, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, EUCKR_st }, EUCKRCharLenTable, "EUC-KR", }; /* obsolete GB2312 by gb18030 static unsigned int GB2312_cls [ 256 / 8 ] = { //PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 PCK4BITS(1,1,1,1,1,1,1,1), // 00 - 07 PCK4BITS(1,1,1,1,1,1,0,0), // 08 - 0f PCK4BITS(1,1,1,1,1,1,1,1), // 10 - 17 PCK4BITS(1,1,1,0,1,1,1,1), // 18 - 1f PCK4BITS(1,1,1,1,1,1,1,1), // 20 - 27 PCK4BITS(1,1,1,1,1,1,1,1), // 28 - 2f PCK4BITS(1,1,1,1,1,1,1,1), // 30 - 37 PCK4BITS(1,1,1,1,1,1,1,1), // 38 - 3f PCK4BITS(1,1,1,1,1,1,1,1), // 40 - 47 PCK4BITS(1,1,1,1,1,1,1,1), // 48 - 4f PCK4BITS(1,1,1,1,1,1,1,1), // 50 - 57 PCK4BITS(1,1,1,1,1,1,1,1), // 58 - 5f PCK4BITS(1,1,1,1,1,1,1,1), // 60 - 67 PCK4BITS(1,1,1,1,1,1,1,1), // 68 - 6f PCK4BITS(1,1,1,1,1,1,1,1), // 70 - 77 PCK4BITS(1,1,1,1,1,1,1,1), // 78 - 7f PCK4BITS(1,0,0,0,0,0,0,0), // 80 - 87 PCK4BITS(0,0,0,0,0,0,0,0), // 88 - 8f PCK4BITS(0,0,0,0,0,0,0,0), // 90 - 97 PCK4BITS(0,0,0,0,0,0,0,0), // 98 - 9f PCK4BITS(0,2,2,2,2,2,2,2), // a0 - a7 PCK4BITS(2,2,3,3,3,3,3,3), // a8 - af PCK4BITS(2,2,2,2,2,2,2,2), // b0 - b7 PCK4BITS(2,2,2,2,2,2,2,2), // b8 - bf PCK4BITS(2,2,2,2,2,2,2,2), // c0 - c7 PCK4BITS(2,2,2,2,2,2,2,2), // c8 - cf PCK4BITS(2,2,2,2,2,2,2,2), // d0 - d7 PCK4BITS(2,2,2,2,2,2,2,2), // d8 - df PCK4BITS(2,2,2,2,2,2,2,2), // e0 - e7 PCK4BITS(2,2,2,2,2,2,2,2), // e8 - ef PCK4BITS(2,2,2,2,2,2,2,2), // f0 - f7 PCK4BITS(2,2,2,2,2,2,2,0) // f8 - ff }; static unsigned int GB2312_st [ 2] = { PCK4BITS(eError,eStart, 3,eError,eError,eError,eError,eError),//00-07 PCK4BITS(eItsMe,eItsMe,eItsMe,eItsMe,eError,eError,eStart,eStart) //08-0f }; static const unsigned int GB2312CharLenTable[] = {0, 1, 2, 0}; SMModel GB2312SMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, GB2312_cls }, 4, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, GB2312_st }, GB2312CharLenTable, "GB2312", }; */ // the following state machine data was created by perl script in // intl/chardet/tools. It should be the same as in PSM detector. static const unsigned int GB18030_cls [ 256 / 8 ] = { PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 00 - 07 PCK4BITS(1, 1, 1, 1, 1, 1, 0, 0), // 08 - 0f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 10 - 17 PCK4BITS(1, 1, 1, 0, 1, 1, 1, 1), // 18 - 1f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 20 - 27 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 28 - 2f PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // 30 - 37 PCK4BITS(3, 3, 1, 1, 1, 1, 1, 1), // 38 - 3f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 40 - 47 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 48 - 4f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 50 - 57 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 58 - 5f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 60 - 67 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 68 - 6f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 70 - 77 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 4), // 78 - 7f PCK4BITS(5, 6, 6, 6, 6, 6, 6, 6), // 80 - 87 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // 88 - 8f PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // 90 - 97 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // 98 - 9f PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // a0 - a7 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // a8 - af PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // b0 - b7 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // b8 - bf PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // c0 - c7 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // c8 - cf PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // d0 - d7 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // d8 - df PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // e0 - e7 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // e8 - ef PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // f0 - f7 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 0) // f8 - ff }; static const unsigned int GB18030_st [ 6] = { PCK4BITS(eError, eStart, eStart, eStart, eStart, eStart, 3, eError), //00-07 PCK4BITS(eError, eError, eError, eError, eError, eError, eItsMe, eItsMe), //08-0f PCK4BITS(eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eError, eError, eStart), //10-17 PCK4BITS(4, eError, eStart, eStart, eError, eError, eError, eError), //18-1f PCK4BITS(eError, eError, 5, eError, eError, eError, eItsMe, eError), //20-27 PCK4BITS(eError, eError, eStart, eStart, eStart, eStart, eStart, eStart) //28-2f }; // To be accurate, the length of class 6 can be either 2 or 4. // But it is not necessary to discriminate between the two since // it is used for frequency analysis only, and we are validing // each code range there as well. So it is safe to set it to be // 2 here. static const unsigned int GB18030CharLenTable[] = {0, 1, 1, 1, 1, 1, 2}; const SMModel GB18030SMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, GB18030_cls }, 7, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, GB18030_st }, GB18030CharLenTable, "GB18030", }; // sjis static const unsigned int SJIS_cls [ 256 / 8 ] = { //PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 00 - 07 PCK4BITS(1, 1, 1, 1, 1, 1, 0, 0), // 08 - 0f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 10 - 17 PCK4BITS(1, 1, 1, 0, 1, 1, 1, 1), // 18 - 1f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 20 - 27 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 28 - 2f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 30 - 37 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 38 - 3f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 40 - 47 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 48 - 4f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 50 - 57 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 58 - 5f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 60 - 67 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 68 - 6f PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // 70 - 77 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 1), // 78 - 7f PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // 80 - 87 PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // 88 - 8f PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // 90 - 97 PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // 98 - 9f //0xa0 is illegal in sjis encoding, but some pages does //contain such byte. We need to be more error forgiven. PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a0 - a7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // a8 - af PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b0 - b7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // b8 - bf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c0 - c7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // c8 - cf PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d0 - d7 PCK4BITS(2, 2, 2, 2, 2, 2, 2, 2), // d8 - df PCK4BITS(3, 3, 3, 3, 3, 3, 3, 3), // e0 - e7 PCK4BITS(3, 3, 3, 3, 3, 4, 4, 4), // e8 - ef PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // f0 - f7 PCK4BITS(4, 4, 4, 4, 4, 0, 0, 0) // f8 - ff }; static const unsigned int SJIS_st [ 3] = { PCK4BITS(eError, eStart, eStart, 3, eError, eError, eError, eError), //00-07 PCK4BITS(eError, eError, eError, eError, eItsMe, eItsMe, eItsMe, eItsMe), //08-0f PCK4BITS(eItsMe, eItsMe, eError, eError, eStart, eStart, eStart, eStart) //10-17 }; static const unsigned int SJISCharLenTable[] = {0, 1, 1, 2, 0, 0}; const SMModel SJISSMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, SJIS_cls }, 6, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, SJIS_st }, SJISCharLenTable, "Shift_JIS", }; static const unsigned int UCS2BE_cls [ 256 / 8 ] = { PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 00 - 07 PCK4BITS(0, 0, 1, 0, 0, 2, 0, 0), // 08 - 0f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 10 - 17 PCK4BITS(0, 0, 0, 3, 0, 0, 0, 0), // 18 - 1f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 20 - 27 PCK4BITS(0, 3, 3, 3, 3, 3, 0, 0), // 28 - 2f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 30 - 37 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 38 - 3f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 40 - 47 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 48 - 4f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 50 - 57 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 58 - 5f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 60 - 67 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 68 - 6f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 70 - 77 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 78 - 7f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 80 - 87 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 88 - 8f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 90 - 97 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 98 - 9f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // a0 - a7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // a8 - af PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // b0 - b7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // b8 - bf PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // c0 - c7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // c8 - cf PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // d0 - d7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // d8 - df PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // e0 - e7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // e8 - ef PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // f0 - f7 PCK4BITS(0, 0, 0, 0, 0, 0, 4, 5) // f8 - ff }; static const unsigned int UCS2BE_st [ 7] = { PCK4BITS(5, 7, 7, eError, 4, 3, eError, eError), //00-07 PCK4BITS(eError, eError, eError, eError, eItsMe, eItsMe, eItsMe, eItsMe), //08-0f PCK4BITS(eItsMe, eItsMe, 6, 6, 6, 6, eError, eError), //10-17 PCK4BITS(6, 6, 6, 6, 6, eItsMe, 6, 6), //18-1f PCK4BITS(6, 6, 6, 6, 5, 7, 7, eError), //20-27 PCK4BITS(5, 8, 6, 6, eError, 6, 6, 6), //28-2f PCK4BITS(6, 6, 6, 6, eError, eError, eStart, eStart) //30-37 }; static const unsigned int UCS2BECharLenTable[] = {2, 2, 2, 0, 2, 2}; const SMModel UCS2BESMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, UCS2BE_cls }, 6, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, UCS2BE_st }, UCS2BECharLenTable, "UTF-16BE", }; static const unsigned int UCS2LE_cls [ 256 / 8 ] = { PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 00 - 07 PCK4BITS(0, 0, 1, 0, 0, 2, 0, 0), // 08 - 0f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 10 - 17 PCK4BITS(0, 0, 0, 3, 0, 0, 0, 0), // 18 - 1f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 20 - 27 PCK4BITS(0, 3, 3, 3, 3, 3, 0, 0), // 28 - 2f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 30 - 37 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 38 - 3f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 40 - 47 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 48 - 4f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 50 - 57 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 58 - 5f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 60 - 67 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 68 - 6f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 70 - 77 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 78 - 7f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 80 - 87 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 88 - 8f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 90 - 97 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // 98 - 9f PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // a0 - a7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // a8 - af PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // b0 - b7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // b8 - bf PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // c0 - c7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // c8 - cf PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // d0 - d7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // d8 - df PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // e0 - e7 PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // e8 - ef PCK4BITS(0, 0, 0, 0, 0, 0, 0, 0), // f0 - f7 PCK4BITS(0, 0, 0, 0, 0, 0, 4, 5) // f8 - ff }; static const unsigned int UCS2LE_st [ 7] = { PCK4BITS(6, 6, 7, 6, 4, 3, eError, eError), //00-07 PCK4BITS(eError, eError, eError, eError, eItsMe, eItsMe, eItsMe, eItsMe), //08-0f PCK4BITS(eItsMe, eItsMe, 5, 5, 5, eError, eItsMe, eError), //10-17 PCK4BITS(5, 5, 5, eError, 5, eError, 6, 6), //18-1f PCK4BITS(7, 6, 8, 8, 5, 5, 5, eError), //20-27 PCK4BITS(5, 5, 5, eError, eError, eError, 5, 5), //28-2f PCK4BITS(5, 5, 5, eError, 5, eError, eStart, eStart) //30-37 }; static const unsigned int UCS2LECharLenTable[] = {2, 2, 2, 2, 2, 2}; const SMModel UCS2LESMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, UCS2LE_cls }, 6, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, UCS2LE_st }, UCS2LECharLenTable, "UTF-16LE", }; static const unsigned int UTF8_cls [ 256 / 8 ] = { //PCK4BITS(0,1,1,1,1,1,1,1), // 00 - 07 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 00 - 07 //allow 0x00 as a legal value PCK4BITS(1, 1, 1, 1, 1, 1, 0, 0), // 08 - 0f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 10 - 17 PCK4BITS(1, 1, 1, 0, 1, 1, 1, 1), // 18 - 1f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 20 - 27 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 28 - 2f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 30 - 37 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 38 - 3f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 40 - 47 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 48 - 4f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 50 - 57 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 58 - 5f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 60 - 67 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 68 - 6f PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 70 - 77 PCK4BITS(1, 1, 1, 1, 1, 1, 1, 1), // 78 - 7f PCK4BITS(2, 2, 2, 2, 3, 3, 3, 3), // 80 - 87 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 88 - 8f PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 90 - 97 PCK4BITS(4, 4, 4, 4, 4, 4, 4, 4), // 98 - 9f PCK4BITS(5, 5, 5, 5, 5, 5, 5, 5), // a0 - a7 PCK4BITS(5, 5, 5, 5, 5, 5, 5, 5), // a8 - af PCK4BITS(5, 5, 5, 5, 5, 5, 5, 5), // b0 - b7 PCK4BITS(5, 5, 5, 5, 5, 5, 5, 5), // b8 - bf PCK4BITS(0, 0, 6, 6, 6, 6, 6, 6), // c0 - c7 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // c8 - cf PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // d0 - d7 PCK4BITS(6, 6, 6, 6, 6, 6, 6, 6), // d8 - df PCK4BITS(7, 8, 8, 8, 8, 8, 8, 8), // e0 - e7 PCK4BITS(8, 8, 8, 8, 8, 9, 8, 8), // e8 - ef PCK4BITS(10, 11, 11, 11, 11, 11, 11, 11), // f0 - f7 PCK4BITS(12, 13, 13, 13, 14, 15, 0, 0) // f8 - ff }; static const unsigned int UTF8_st [ 26] = { PCK4BITS(eError, eStart, eError, eError, eError, eError, 12, 10), //00-07 PCK4BITS(9, 11, 8, 7, 6, 5, 4, 3), //08-0f PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //10-17 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //18-1f PCK4BITS(eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe), //20-27 PCK4BITS(eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe, eItsMe), //28-2f PCK4BITS(eError, eError, 5, 5, 5, 5, eError, eError), //30-37 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //38-3f PCK4BITS(eError, eError, eError, 5, 5, 5, eError, eError), //40-47 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //48-4f PCK4BITS(eError, eError, 7, 7, 7, 7, eError, eError), //50-57 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //58-5f PCK4BITS(eError, eError, eError, eError, 7, 7, eError, eError), //60-67 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //68-6f PCK4BITS(eError, eError, 9, 9, 9, 9, eError, eError), //70-77 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //78-7f PCK4BITS(eError, eError, eError, eError, eError, 9, eError, eError), //80-87 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //88-8f PCK4BITS(eError, eError, 12, 12, 12, 12, eError, eError), //90-97 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //98-9f PCK4BITS(eError, eError, eError, eError, eError, 12, eError, eError), //a0-a7 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //a8-af PCK4BITS(eError, eError, 12, 12, 12, eError, eError, eError), //b0-b7 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError), //b8-bf PCK4BITS(eError, eError, eStart, eStart, eStart, eStart, eError, eError), //c0-c7 PCK4BITS(eError, eError, eError, eError, eError, eError, eError, eError) //c8-cf }; static const unsigned int UTF8CharLenTable[] = {0, 1, 0, 0, 0, 0, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6 }; const SMModel UTF8SMModel = { {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, UTF8_cls }, 16, {eIdxSft4bits, eSftMsk4bits, eBitSft4bits, eUnitMsk4bits, UTF8_st }, UTF8CharLenTable, "UTF-8", }; } diff --git a/src/probers/nsPkgInt.h b/src/probers/nsPkgInt.h index ad8514a..bf78b42 100644 --- a/src/probers/nsPkgInt.h +++ b/src/probers/nsPkgInt.h @@ -1,77 +1,59 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef nsPkgInt_h__ #define nsPkgInt_h__ namespace kencodingprober { typedef enum { eIdxSft4bits = 3, eIdxSft8bits = 2, eIdxSft16bits = 1 } nsIdxSft; typedef enum { eSftMsk4bits = 7, eSftMsk8bits = 3, eSftMsk16bits = 1 } nsSftMsk; typedef enum { eBitSft4bits = 2, eBitSft8bits = 3, eBitSft16bits = 4 } nsBitSft; typedef enum { eUnitMsk4bits = 0x0000000FL, eUnitMsk8bits = 0x000000FFL, eUnitMsk16bits = 0x0000FFFFL } nsUnitMsk; typedef struct nsPkgInt { nsIdxSft idxsft; nsSftMsk sftmsk; nsBitSft bitsft; nsUnitMsk unitmsk; const unsigned int *data; } nsPkgInt; } #define PCK16BITS(a,b) ((unsigned int)(((b) << 16) | (a))) #define PCK8BITS(a,b,c,d) PCK16BITS( ((unsigned int)(((b) << 8) | (a))), \ ((unsigned int)(((d) << 8) | (c)))) #define PCK4BITS(a,b,c,d,e,f,g,h) PCK8BITS( ((unsigned int)(((b) << 4) | (a))), \ ((unsigned int)(((d) << 4) | (c))), \ ((unsigned int)(((f) << 4) | (e))), \ ((unsigned int)(((h) << 4) | (g))) ) #define GETFROMPCK(i, c) \ (((((c).data)[(i)>>(c).idxsft])>>(((i)&(c).sftmsk)<<(c).bitsft))&(c).unitmsk) #endif /* nsPkgInt_h__ */ diff --git a/src/probers/nsSBCSGroupProber.cpp b/src/probers/nsSBCSGroupProber.cpp index 40e2552..f71151a 100644 --- a/src/probers/nsSBCSGroupProber.cpp +++ b/src/probers/nsSBCSGroupProber.cpp @@ -1,204 +1,186 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsSBCSGroupProber.h" #include "nsSBCharSetProber.h" #include "nsHebrewProber.h" #include "UnicodeGroupProber.h" #include #include namespace kencodingprober { nsSBCSGroupProber::nsSBCSGroupProber() { mProbers[0] = new nsSingleByteCharSetProber(&Win1251Model); mProbers[1] = new nsSingleByteCharSetProber(&Koi8rModel); mProbers[2] = new nsSingleByteCharSetProber(&Latin5Model); mProbers[3] = new nsSingleByteCharSetProber(&MacCyrillicModel); mProbers[4] = new nsSingleByteCharSetProber(&Ibm866Model); mProbers[5] = new nsSingleByteCharSetProber(&Ibm855Model); mProbers[6] = new nsSingleByteCharSetProber(&Latin7Model); mProbers[7] = new nsSingleByteCharSetProber(&Win1253Model); mProbers[8] = new nsSingleByteCharSetProber(&Latin5BulgarianModel); mProbers[9] = new nsSingleByteCharSetProber(&Win1251BulgarianModel); nsHebrewProber *hebprober = new nsHebrewProber(); // Notice: Any change in these indexes - 10,11,12 must be reflected // in the code below as well. mProbers[10] = hebprober; mProbers[11] = new nsSingleByteCharSetProber(&Win1255Model, false, hebprober); // Logical Hebrew mProbers[12] = new nsSingleByteCharSetProber(&Win1255Model, true, hebprober); // Visual Hebrew mProbers[13] = new UnicodeGroupProber(); // Tell the Hebrew prober about the logical and visual probers if (mProbers[10] && mProbers[11] && mProbers[12]) { // all are not null hebprober->SetModelProbers(mProbers[11], mProbers[12]); } else { // One or more is null. avoid any Hebrew probing, null them all for (unsigned int i = 10; i <= 12; ++i) { delete mProbers[i]; mProbers[i] = nullptr; } } // disable latin2 before latin1 is available, otherwise all latin1 // will be detected as latin2 because of their similarity. //mProbers[10] = new nsSingleByteCharSetProber(&Latin2HungarianModel); //mProbers[11] = new nsSingleByteCharSetProber(&Win1250HungarianModel); Reset(); } nsSBCSGroupProber::~nsSBCSGroupProber() { for (unsigned int i = 0; i < NUM_OF_SBCS_PROBERS; i++) { delete mProbers[i]; } } const char *nsSBCSGroupProber::GetCharSetName() { //if we have no answer yet if (mBestGuess == -1) { GetConfidence(); //no charset seems positive if (mBestGuess == -1) //we will use default. { mBestGuess = 0; } } return mProbers[mBestGuess]->GetCharSetName(); } void nsSBCSGroupProber::Reset(void) { mActiveNum = 0; for (unsigned int i = 0; i < NUM_OF_SBCS_PROBERS; i++) { if (mProbers[i]) { // not null mProbers[i]->Reset(); mIsActive[i] = true; ++mActiveNum; } else { mIsActive[i] = false; } } mBestGuess = -1; mState = eDetecting; } nsProbingState nsSBCSGroupProber::HandleData(const char *aBuf, unsigned int aLen) { nsProbingState st; unsigned int i; char *newBuf1 = nullptr; unsigned int newLen1 = 0; //apply filter to original buffer, and we got new buffer back //depend on what script it is, we will feed them the new buffer //we got after applying proper filter //this is done without any consideration to KeepEnglishLetters //of each prober since as of now, there are no probers here which //recognize languages with English characters. if (!FilterWithoutEnglishLetters(aBuf, aLen, &newBuf1, newLen1)) { goto done; } if (newLen1 == 0) { goto done; // Nothing to see here, move on. } for (i = 0; i < NUM_OF_SBCS_PROBERS; ++i) { if (!mIsActive[i]) { continue; } st = mProbers[i]->HandleData(newBuf1, newLen1); if (st == eFoundIt) { mBestGuess = i; mState = eFoundIt; break; } else if (st == eNotMe) { mIsActive[i] = false; mActiveNum--; if (mActiveNum <= 0) { mState = eNotMe; break; } } } done: free(newBuf1); return mState; } float nsSBCSGroupProber::GetConfidence(void) { unsigned int i; float bestConf = 0.0, cf; switch (mState) { case eFoundIt: return (float)0.99; //sure yes case eNotMe: return (float)0.01; //sure no default: for (i = 0; i < NUM_OF_SBCS_PROBERS; ++i) { if (!mIsActive[i]) { continue; } cf = mProbers[i]->GetConfidence(); if (bestConf < cf) { bestConf = cf; mBestGuess = i; } } } return bestConf; } #ifdef DEBUG_PROBE void nsSBCSGroupProber::DumpStatus() { unsigned int i; float cf; cf = GetConfidence(); printf(" SBCS Group Prober --------begin status \r\n"); for (i = 0; i < NUM_OF_SBCS_PROBERS; i++) { if (!mIsActive[i]) { printf(" inactive: [%s] (i.e. confidence is too low).\r\n", mProbers[i]->GetCharSetName()); } else { mProbers[i]->DumpStatus(); } } printf(" SBCS Group found best match [%s] confidence %f.\r\n", mProbers[mBestGuess]->GetCharSetName(), cf); } #endif } diff --git a/src/probers/nsSBCSGroupProber.h b/src/probers/nsSBCSGroupProber.h index f5cd87a..518b3a2 100644 --- a/src/probers/nsSBCSGroupProber.h +++ b/src/probers/nsSBCSGroupProber.h @@ -1,76 +1,48 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Universal charset detector code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 2001 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Shy Shalom - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ +/* + The Original Code is Mozilla Universal charset detector code. + + SPDX-FileCopyrightText: 2001 Netscape Communications Corporation + SPDX-FileContributor: Shy Shalom + + SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later OR LGPL-2.1-or-later +*/ #ifndef nsSBCSGroupProber_h__ #define nsSBCSGroupProber_h__ #include "nsCharSetProber.h" #define NUM_OF_SBCS_PROBERS 14 namespace kencodingprober { class KCODECS_NO_EXPORT nsSBCSGroupProber: public nsCharSetProber { public: nsSBCSGroupProber(); ~nsSBCSGroupProber() override; nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override; nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {} #ifdef DEBUG_PROBE void DumpStatus() override; #endif protected: nsProbingState mState; nsCharSetProber *mProbers[NUM_OF_SBCS_PROBERS]; bool mIsActive[NUM_OF_SBCS_PROBERS]; int mBestGuess; unsigned int mActiveNum; }; } #endif /* nsSBCSGroupProber_h__ */ diff --git a/src/probers/nsSBCharSetProber.cpp b/src/probers/nsSBCharSetProber.cpp index 12a4348..daf1dfd 100644 --- a/src/probers/nsSBCharSetProber.cpp +++ b/src/probers/nsSBCharSetProber.cpp @@ -1,121 +1,103 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #include "nsSBCharSetProber.h" #include namespace kencodingprober { nsProbingState nsSingleByteCharSetProber::HandleData(const char *aBuf, unsigned int aLen) { unsigned char order; for (unsigned int i = 0; i < aLen; i++) { order = mModel->charToOrderMap[(unsigned char)aBuf[i]]; if (order < SYMBOL_CAT_ORDER) { mTotalChar++; } if (order < SAMPLE_SIZE) { mFreqChar++; if (mLastOrder < SAMPLE_SIZE) { mTotalSeqs++; if (!mReversed) { ++(mSeqCounters[(int)mModel->precedenceMatrix[mLastOrder * SAMPLE_SIZE + order]]); } else { // reverse the order of the letters in the lookup ++(mSeqCounters[(int)mModel->precedenceMatrix[order * SAMPLE_SIZE + mLastOrder]]); } } } mLastOrder = order; } if (mState == eDetecting) if (mTotalSeqs > SB_ENOUGH_REL_THRESHOLD) { float cf = GetConfidence(); if (cf > POSITIVE_SHORTCUT_THRESHOLD) { mState = eFoundIt; } else if (cf < NEGATIVE_SHORTCUT_THRESHOLD) { mState = eNotMe; } } return mState; } void nsSingleByteCharSetProber::Reset(void) { mState = eDetecting; mLastOrder = 255; for (unsigned int i = 0; i < NUMBER_OF_SEQ_CAT; i++) { mSeqCounters[i] = 0; } mTotalSeqs = 0; mTotalChar = 0; mFreqChar = 0; } //#define NEGATIVE_APPROACH 1 float nsSingleByteCharSetProber::GetConfidence(void) { #ifdef NEGATIVE_APPROACH if (mTotalSeqs > 0) if (mTotalSeqs > mSeqCounters[NEGATIVE_CAT] * 10) { return ((float)(mTotalSeqs - mSeqCounters[NEGATIVE_CAT] * 10)) / mTotalSeqs * mFreqChar / mTotalChar; } return (float)0.01; #else //POSITIVE_APPROACH float r; if (mTotalSeqs > 0) { r = ((float)1.0) * mSeqCounters[POSITIVE_CAT] / mTotalSeqs / mModel->mTypicalPositiveRatio; r = r * mFreqChar / mTotalChar; if (r >= (float)1.00) { r = (float)0.99; } return r; } return (float)0.01; #endif } const char *nsSingleByteCharSetProber::GetCharSetName() { if (!mNameProber) { return mModel->charsetName; } return mNameProber->GetCharSetName(); } #ifdef DEBUG_PROBE void nsSingleByteCharSetProber::DumpStatus() { printf(" SBCS: %1.3f [%s]\r\n", GetConfidence(), GetCharSetName()); } #endif } diff --git a/src/probers/nsSBCharSetProber.h b/src/probers/nsSBCharSetProber.h index 388f5c1..1e559fe 100644 --- a/src/probers/nsSBCharSetProber.h +++ b/src/probers/nsSBCharSetProber.h @@ -1,123 +1,105 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ #ifndef NSSBCHARSETPROBER_H #define NSSBCHARSETPROBER_H #include "nsCharSetProber.h" #define SAMPLE_SIZE 64 #define SB_ENOUGH_REL_THRESHOLD 1024 #define POSITIVE_SHORTCUT_THRESHOLD (float)0.95 #define NEGATIVE_SHORTCUT_THRESHOLD (float)0.05 #define SYMBOL_CAT_ORDER 250 #define NUMBER_OF_SEQ_CAT 4 #define POSITIVE_CAT (NUMBER_OF_SEQ_CAT-1) #define NEGATIVE_CAT 0 namespace kencodingprober { typedef struct { const unsigned char *charToOrderMap; // [256] table use to find a char's order const char *precedenceMatrix; // [SAMPLE_SIZE][SAMPLE_SIZE]; table to find a 2-char sequence's frequency float mTypicalPositiveRatio; // = freqSeqs / totalSeqs bool keepEnglishLetter; // says if this script contains English characters (not implemented) const char *charsetName; } SequenceModel; class KCODECS_NO_EXPORT nsSingleByteCharSetProber : public nsCharSetProber { public: nsSingleByteCharSetProber(const SequenceModel *model) : mModel(model), mReversed(false), mNameProber(nullptr) { Reset(); } nsSingleByteCharSetProber(const SequenceModel *model, bool reversed, nsCharSetProber *nameProber) : mModel(model), mReversed(reversed), mNameProber(nameProber) { Reset(); } const char *GetCharSetName() override; nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {} // This feature is not implemented yet. any current language model // contain this parameter as false. No one is looking at this // parameter or calling this method. // Moreover, the nsSBCSGroupProber which calls the HandleData of this // prober has a hard-coded call to FilterWithoutEnglishLetters which gets rid // of the English letters. bool KeepEnglishLetters() { return mModel->keepEnglishLetter; } // (not implemented) #ifdef DEBUG_PROBE void DumpStatus() override; #endif protected: nsProbingState mState; const SequenceModel *mModel; const bool mReversed; // true if we need to reverse every pair in the model lookup //char order of last character unsigned char mLastOrder; unsigned int mTotalSeqs; unsigned int mSeqCounters[NUMBER_OF_SEQ_CAT]; unsigned int mTotalChar; //characters that fall in our sampling range unsigned int mFreqChar; // Optional auxiliary prober for name decision. created and destroyed by the GroupProber nsCharSetProber *mNameProber; }; extern const SequenceModel Koi8rModel; extern const SequenceModel Win1251Model; extern const SequenceModel Latin5Model; extern const SequenceModel MacCyrillicModel; extern const SequenceModel Ibm866Model; extern const SequenceModel Ibm855Model; extern const SequenceModel Latin7Model; extern const SequenceModel Win1253Model; extern const SequenceModel Latin5BulgarianModel; extern const SequenceModel Win1251BulgarianModel; extern const SequenceModel Latin2HungarianModel; extern const SequenceModel Win1250HungarianModel; extern const SequenceModel Win1255Model; } #endif /* NSSBCHARSETPROBER_H */ diff --git a/src/probers/nsSJISProber.cpp b/src/probers/nsSJISProber.cpp index 8468297..57d8aec 100644 --- a/src/probers/nsSJISProber.cpp +++ b/src/probers/nsSJISProber.cpp @@ -1,90 +1,72 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MIT */ // for S-JIS encoding, obeserve characteristic: // 1, kana character (or hankaku?) often have hight frequency of appereance // 2, kana character often exist in group // 3, certain combination of kana is never used in japanese language #include "nsSJISProber.h" namespace kencodingprober { void nsSJISProber::Reset(void) { mCodingSM->Reset(); mState = eDetecting; mContextAnalyser.Reset(); mDistributionAnalyser.Reset(); } nsProbingState nsSJISProber::HandleData(const char *aBuf, unsigned int aLen) { if (aLen == 0) return mState; nsSMState codingState; for (unsigned int i = 0; i < aLen; i++) { codingState = mCodingSM->NextState(aBuf[i]); if (codingState == eError) { mState = eNotMe; break; } if (codingState == eItsMe) { mState = eFoundIt; break; } if (codingState == eStart) { unsigned int charLen = mCodingSM->GetCurrentCharLen(); if (i == 0) { mLastChar[1] = aBuf[0]; mContextAnalyser.HandleOneChar(mLastChar + 2 - charLen, charLen); mDistributionAnalyser.HandleOneChar(mLastChar, charLen); } else { mContextAnalyser.HandleOneChar(aBuf + i + 1 - charLen, charLen); mDistributionAnalyser.HandleOneChar(aBuf + i - 1, charLen); } } } mLastChar[0] = aBuf[aLen - 1]; if (mState == eDetecting) if (mContextAnalyser.GotEnoughData() && GetConfidence() > SHORTCUT_THRESHOLD) { mState = eFoundIt; } return mState; } float nsSJISProber::GetConfidence(void) { float contxtCf = mContextAnalyser.GetConfidence(); float distribCf = mDistributionAnalyser.GetConfidence(); return (contxtCf > distribCf ? contxtCf : distribCf); } } diff --git a/src/probers/nsSJISProber.h b/src/probers/nsSJISProber.h index c868df0..3c2b5a8 100644 --- a/src/probers/nsSJISProber.h +++ b/src/probers/nsSJISProber.h @@ -1,90 +1,62 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ +/* + The Original Code is mozilla.org code. + + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + + SPDX-License-Identifier: MPL-1.1 OR GPL-2.0-or-later OR LGPL-2.1-or-later +*/ // for S-JIS encoding, obeserve characteristic: // 1, kana character (or hankaku?) often have hight frequency of appereance // 2, kana character often exist in group // 3, certain combination of kana is never used in japanese language #ifndef nsSJISProber_h__ #define nsSJISProber_h__ #include "nsCharSetProber.h" #include "nsCodingStateMachine.h" #include "JpCntx.h" #include "CharDistribution.h" namespace kencodingprober { class KCODECS_NO_EXPORT nsSJISProber: public nsCharSetProber { public: nsSJISProber(void) { mCodingSM = new nsCodingStateMachine(&SJISSMModel); Reset(); } ~nsSJISProber(void) override { delete mCodingSM; } nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override { return "Shift_JIS"; } nsProbingState GetState(void) override { return mState; } void Reset(void) override; float GetConfidence(void) override; void SetOpion() override {}; protected: nsCodingStateMachine *mCodingSM; nsProbingState mState; SJISContextAnalysis mContextAnalyser; SJISDistributionAnalysis mDistributionAnalyser; char mLastChar[2]; }; } #endif /* nsSJISProber_h__ */ diff --git a/src/probers/nsUniversalDetector.cpp b/src/probers/nsUniversalDetector.cpp index 8c7ee5a..7f30e28 100644 --- a/src/probers/nsUniversalDetector.cpp +++ b/src/probers/nsUniversalDetector.cpp @@ -1,242 +1,225 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* Copyright (C) 2008 -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + SPDX-FileCopyrightText: 2008 Wang Kai + + SPDX-License-Identifier: MIT */ #include "nsUniversalDetector.h" #include "nsMBCSGroupProber.h" #include "nsSBCSGroupProber.h" #include "nsEscCharsetProber.h" #include "nsLatin1Prober.h" namespace kencodingprober { nsUniversalDetector::nsUniversalDetector() { mDone = false; mBestGuess = -1; //illegal value as signal mInTag = false; mEscCharSetProber = nullptr; mStart = true; mDetectedCharset = nullptr; mGotData = false; mInputState = ePureAscii; mLastChar = '\0'; unsigned int i; for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++) { mCharSetProbers[i] = nullptr; } } nsUniversalDetector::~nsUniversalDetector() { for (int i = 0; i < NUM_OF_CHARSET_PROBERS; i++) { delete mCharSetProbers[i]; } delete mEscCharSetProber; } void nsUniversalDetector::Reset() { mDone = false; mBestGuess = -1; //illegal value as signal mInTag = false; mStart = true; mDetectedCharset = nullptr; mGotData = false; mInputState = ePureAscii; mLastChar = '\0'; if (mEscCharSetProber) { mEscCharSetProber->Reset(); } unsigned int i; for (i = 0; i < NUM_OF_CHARSET_PROBERS; i++) if (mCharSetProbers[i]) { mCharSetProbers[i]->Reset(); } } //--------------------------------------------------------------------- #define SHORTCUT_THRESHOLD (float)0.95 #define MINIMUM_THRESHOLD (float)0.20 nsProbingState nsUniversalDetector::HandleData(const char *aBuf, unsigned int aLen) { if (mDone) { return eFoundIt; } if (aLen > 0) { mGotData = true; } unsigned int i; for (i = 0; i < aLen; i++) { //other than 0xa0, if every othe character is ascii, the page is ascii if (aBuf[i] & '\x80' && aBuf[i] != '\xA0') { //Since many Ascii only page contains NBSP //we got a non-ascii byte (high-byte) if (mInputState != eHighbyte) { //adjust state mInputState = eHighbyte; //kill mEscCharSetProber if it is active delete mEscCharSetProber; mEscCharSetProber = nullptr; //start multibyte and singlebyte charset prober if (nullptr == mCharSetProbers[0]) { mCharSetProbers[0] = new nsMBCSGroupProber; } if (nullptr == mCharSetProbers[1]) { mCharSetProbers[1] = new nsSBCSGroupProber; } if (nullptr == mCharSetProbers[2]) { mCharSetProbers[2] = new nsLatin1Prober; } } } else { //ok, just pure ascii so far if (ePureAscii == mInputState && (aBuf[i] == '\033' || (aBuf[i] == '{' && mLastChar == '~'))) { //found escape character or HZ "~{" mInputState = eEscAscii; } mLastChar = aBuf[i]; } } nsProbingState st = eDetecting; switch (mInputState) { case eEscAscii: if (nullptr == mEscCharSetProber) { mEscCharSetProber = new nsEscCharSetProber; } st = mEscCharSetProber->HandleData(aBuf, aLen); if (st == eFoundIt) { mDone = true; mDetectedCharset = mEscCharSetProber->GetCharSetName(); } break; case eHighbyte: for (i = 0; i < NUM_OF_CHARSET_PROBERS; ++i) { st = mCharSetProbers[i]->HandleData(aBuf, aLen); if (st == eFoundIt) { mDone = true; mDetectedCharset = mCharSetProbers[i]->GetCharSetName(); } } break; default: //pure ascii mDetectedCharset = "UTF-8"; } return st; } //--------------------------------------------------------------------- const char *nsUniversalDetector::GetCharSetName() { if (mDetectedCharset) { return mDetectedCharset; } switch (mInputState) { case eHighbyte: { float proberConfidence; float maxProberConfidence = (float)0.0; int maxProber = 0; for (int i = 0; i < NUM_OF_CHARSET_PROBERS; i++) { proberConfidence = mCharSetProbers[i]->GetConfidence(); if (proberConfidence > maxProberConfidence) { maxProberConfidence = proberConfidence; maxProber = i; } } //do not report anything because we are not confident of it, that's in fact a negative answer if (maxProberConfidence > MINIMUM_THRESHOLD) { return mCharSetProbers[maxProber]->GetCharSetName(); } } case eEscAscii: break; default: // pure ascii ; } return "UTF-8"; } //--------------------------------------------------------------------- float nsUniversalDetector::GetConfidence() { if (!mGotData) { // we haven't got any data yet, return immediately // caller program sometimes call DataEnd before anything has been sent to detector return MINIMUM_THRESHOLD; } if (mDetectedCharset) { return 0.99f; } switch (mInputState) { case eHighbyte: { float proberConfidence; float maxProberConfidence = (float)0.0; int maxProber = 0; for (int i = 0; i < NUM_OF_CHARSET_PROBERS; i++) { proberConfidence = mCharSetProbers[i]->GetConfidence(); if (proberConfidence > maxProberConfidence) { maxProberConfidence = proberConfidence; maxProber = i; } } //do not report anything because we are not confident of it, that's in fact a negative answer if (maxProberConfidence > MINIMUM_THRESHOLD) { return mCharSetProbers[maxProber]->GetConfidence(); } } case eEscAscii: break; default: // pure ascii ; } return MINIMUM_THRESHOLD; } nsProbingState nsUniversalDetector::GetState() { if (mDone) { return eFoundIt; } else { return eDetecting; } } } diff --git a/src/probers/nsUniversalDetector.h b/src/probers/nsUniversalDetector.h index 6c0337d..6338b02 100644 --- a/src/probers/nsUniversalDetector.h +++ b/src/probers/nsUniversalDetector.h @@ -1,68 +1,51 @@ /* -*- C++ -*- -* Copyright (C) 1998 -* Copyright (C) 2008 -* -* 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. + SPDX-FileCopyrightText: 1998 Netscape Communications Corporation + SPDX-FileCopyrightText: 2008 Wang Kai + + SPDX-License-Identifier: MIT */ #ifndef nsUniversalDetector_h__ #define nsUniversalDetector_h__ #include "nsCharSetProber.h" #define NUM_OF_CHARSET_PROBERS 3 namespace kencodingprober { typedef enum { ePureAscii = 0, eEscAscii = 1, eHighbyte = 2 } nsInputState; class KCODECS_NO_EXPORT nsUniversalDetector: public nsCharSetProber { public: nsUniversalDetector(); ~nsUniversalDetector() override; nsProbingState HandleData(const char *aBuf, unsigned int aLen) override; const char *GetCharSetName() override; void Reset(void) override; float GetConfidence(void) override; nsProbingState GetState() override; void SetOpion() override {} protected: nsInputState mInputState; bool mDone; bool mInTag; bool mStart; bool mGotData; char mLastChar; const char *mDetectedCharset; int mBestGuess; nsCharSetProber *mCharSetProbers[NUM_OF_CHARSET_PROBERS]; nsCharSetProber *mEscCharSetProber; }; } #endif diff --git a/src/probers/tables/Big5Freq.tab b/src/probers/tables/Big5Freq.tab index 89d4559..5980ef5 100644 --- a/src/probers/tables/Big5Freq.tab +++ b/src/probers/tables/Big5Freq.tab @@ -1,931 +1,913 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 + + SPDX-License-Identifier: MIT */ // Big5 frequency table -// by Taiwan's Mandarin Promotion Council +// by Taiwan's Mandarin Promotion Council // /****************************************************************************** * 128 --> 0.42261 * 256 --> 0.57851 * 512 --> 0.74851 * 1024 --> 0.89384 * 2048 --> 0.97583 * * Idea Distribution Ratio = 0.74851/(1-0.74851) =2.98 * Random Distribution Ration = 512/(5401-512)=0.105 - * + * * Typical Distribution Ratio about 25% of Ideal one, still much higher than RDR *****************************************************************************/ #define BIG5_TYPICAL_DISTRIBUTION_RATIO (float)0.75 -//Char to FreqOrder table , +//Char to FreqOrder table , #define BIG5_TABLE_SIZE 5376 static const short Big5CharToFreqOrder[] = { 1,1801,1506, 255,1431, 198, 9, 82, 6,5008, 177, 202,3681,1256,2821, 110, // 16 3814, 33,3274, 261, 76, 44,2114, 16,2946,2187,1176, 659,3971, 26,3451,2653, // 32 1198,3972,3350,4202, 410,2215, 302, 590, 361,1964, 8, 204, 58,4510,5009,1932, // 48 63,5010,5011, 317,1614, 75, 222, 159,4203,2417,1480,5012,3555,3091, 224,2822, // 64 3682, 3, 10,3973,1471, 29,2787,1135,2866,1940, 873, 130,3275,1123, 312,5013, // 80 4511,2052, 507, 252, 682,5014, 142,1915, 124, 206,2947, 34,3556,3204, 64, 604, // 96 5015,2501,1977,1978, 155,1991, 645, 641,1606,5016,3452, 337, 72, 406,5017, 80, // 112 630, 238,3205,1509, 263, 939,1092,2654, 756,1440,1094,3453, 449, 69,2987, 591, // 128 179,2096, 471, 115,2035,1844, 60, 50,2988, 134, 806,1869, 734,2036,3454, 180, // 144 995,1607, 156, 537,2907, 688,5018, 319,1305, 779,2145, 514,2379, 298,4512, 359, // 160 2502, 90,2716,1338, 663, 11, 906,1099,2553, 20,2441, 182, 532,1716,5019, 732, // 176 1376,4204,1311,1420,3206, 25,2317,1056, 113, 399, 382,1950, 242,3455,2474, 529, // 192 3276, 475,1447,3683,5020, 117, 21, 656, 810,1297,2300,2334,3557,5021, 126,4205, // 208 706, 456, 150, 613,4513, 71,1118,2037,4206, 145,3092, 85, 835, 486,2115,1246, // 224 1426, 428, 727,1285,1015, 800, 106, 623, 303,1281,5022,2128,2359, 347,3815, 221, // 240 3558,3135,5023,1956,1153,4207, 83, 296,1199,3093, 192, 624, 93,5024, 822,1898, // 256 2823,3136, 795,2065, 991,1554,1542,1592, 27, 43,2867, 859, 139,1456, 860,4514, // 272 437, 712,3974, 164,2397,3137, 695, 211,3037,2097, 195,3975,1608,3559,3560,3684, // 288 3976, 234, 811,2989,2098,3977,2233,1441,3561,1615,2380, 668,2077,1638, 305, 228, // 304 1664,4515, 467, 415,5025, 262,2099,1593, 239, 108, 300, 200,1033, 512,1247,2078, // 320 5026,5027,2176,3207,3685,2682, 593, 845,1062,3277, 88,1723,2038,3978,1951, 212, // 336 266, 152, 149, 468,1899,4208,4516, 77, 187,5028,3038, 37, 5,2990,5029,3979, // 352 5030,5031, 39,2524,4517,2908,3208,2079, 55, 148, 74,4518, 545, 483,1474,1029, // 368 1665, 217,1870,1531,3138,1104,2655,4209, 24, 172,3562, 900,3980,3563,3564,4519, // 384 32,1408,2824,1312, 329, 487,2360,2251,2717, 784,2683, 4,3039,3351,1427,1789, // 400 188, 109, 499,5032,3686,1717,1790, 888,1217,3040,4520,5033,3565,5034,3352,1520, // 416 3687,3981, 196,1034, 775,5035,5036, 929,1816, 249, 439, 38,5037,1063,5038, 794, // 432 3982,1435,2301, 46, 178,3278,2066,5039,2381,5040, 214,1709,4521, 804, 35, 707, // 448 324,3688,1601,2554, 140, 459,4210,5041,5042,1365, 839, 272, 978,2262,2580,3456, // 464 2129,1363,3689,1423, 697, 100,3094, 48, 70,1231, 495,3139,2196,5043,1294,5044, // 480 2080, 462, 586,1042,3279, 853, 256, 988, 185,2382,3457,1698, 434,1084,5045,3458, // 496 314,2625,2788,4522,2335,2336, 569,2285, 637,1817,2525, 757,1162,1879,1616,3459, // 512 287,1577,2116, 768,4523,1671,2868,3566,2526,1321,3816, 909,2418,5046,4211, 933, // 528 3817,4212,2053,2361,1222,4524, 765,2419,1322, 786,4525,5047,1920,1462,1677,2909, // 544 1699,5048,4526,1424,2442,3140,3690,2600,3353,1775,1941,3460,3983,4213, 309,1369, // 560 1130,2825, 364,2234,1653,1299,3984,3567,3985,3986,2656, 525,1085,3041, 902,2001, // 576 1475, 964,4527, 421,1845,1415,1057,2286, 940,1364,3141, 376,4528,4529,1381, 7, // 592 2527, 983,2383, 336,1710,2684,1846, 321,3461, 559,1131,3042,2752,1809,1132,1313, // 608 265,1481,1858,5049, 352,1203,2826,3280, 167,1089, 420,2827, 776, 792,1724,3568, // 624 4214,2443,3281,5050,4215,5051, 446, 229, 333,2753, 901,3818,1200,1557,4530,2657, // 640 1921, 395,2754,2685,3819,4216,1836, 125, 916,3209,2626,4531,5052,5053,3820,5054, // 656 5055,5056,4532,3142,3691,1133,2555,1757,3462,1510,2318,1409,3569,5057,2146, 438, // 672 2601,2910,2384,3354,1068, 958,3043, 461, 311,2869,2686,4217,1916,3210,4218,1979, // 688 383, 750,2755,2627,4219, 274, 539, 385,1278,1442,5058,1154,1965, 384, 561, 210, // 704 98,1295,2556,3570,5059,1711,2420,1482,3463,3987,2911,1257, 129,5060,3821, 642, // 720 523,2789,2790,2658,5061, 141,2235,1333, 68, 176, 441, 876, 907,4220, 603,2602, // 736 710, 171,3464, 404, 549, 18,3143,2398,1410,3692,1666,5062,3571,4533,2912,4534, // 752 5063,2991, 368,5064, 146, 366, 99, 871,3693,1543, 748, 807,1586,1185, 22,2263, // 768 379,3822,3211,5065,3212, 505,1942,2628,1992,1382,2319,5066, 380,2362, 218, 702, // 784 1818,1248,3465,3044,3572,3355,3282,5067,2992,3694, 930,3283,3823,5068, 59,5069, // 800 585, 601,4221, 497,3466,1112,1314,4535,1802,5070,1223,1472,2177,5071, 749,1837, // 816 690,1900,3824,1773,3988,1476, 429,1043,1791,2236,2117, 917,4222, 447,1086,1629, // 832 5072, 556,5073,5074,2021,1654, 844,1090, 105, 550, 966,1758,2828,1008,1783, 686, // 848 1095,5075,2287, 793,1602,5076,3573,2603,4536,4223,2948,2302,4537,3825, 980,2503, // 864 544, 353, 527,4538, 908,2687,2913,5077, 381,2629,1943,1348,5078,1341,1252, 560, // 880 3095,5079,3467,2870,5080,2054, 973, 886,2081, 143,4539,5081,5082, 157,3989, 496, // 896 4224, 57, 840, 540,2039,4540,4541,3468,2118,1445, 970,2264,1748,1966,2082,4225, // 912 3144,1234,1776,3284,2829,3695, 773,1206,2130,1066,2040,1326,3990,1738,1725,4226, // 928 279,3145, 51,1544,2604, 423,1578,2131,2067, 173,4542,1880,5083,5084,1583, 264, // 944 610,3696,4543,2444, 280, 154,5085,5086,5087,1739, 338,1282,3096, 693,2871,1411, // 960 1074,3826,2445,5088,4544,5089,5090,1240, 952,2399,5091,2914,1538,2688, 685,1483, // 976 4227,2475,1436, 953,4228,2055,4545, 671,2400, 79,4229,2446,3285, 608, 567,2689, // 992 3469,4230,4231,1691, 393,1261,1792,2401,5092,4546,5093,5094,5095,5096,1383,1672, // 1008 3827,3213,1464, 522,1119, 661,1150, 216, 675,4547,3991,1432,3574, 609,4548,2690, // 1024 2402,5097,5098,5099,4232,3045, 0,5100,2476, 315, 231,2447, 301,3356,4549,2385, // 1040 5101, 233,4233,3697,1819,4550,4551,5102, 96,1777,1315,2083,5103, 257,5104,1810, // 1056 3698,2718,1139,1820,4234,2022,1124,2164,2791,1778,2659,5105,3097, 363,1655,3214, // 1072 5106,2993,5107,5108,5109,3992,1567,3993, 718, 103,3215, 849,1443, 341,3357,2949, // 1088 1484,5110,1712, 127, 67, 339,4235,2403, 679,1412, 821,5111,5112, 834, 738, 351, // 1104 2994,2147, 846, 235,1497,1881, 418,1993,3828,2719, 186,1100,2148,2756,3575,1545, // 1120 1355,2950,2872,1377, 583,3994,4236,2581,2995,5113,1298,3699,1078,2557,3700,2363, // 1136 78,3829,3830, 267,1289,2100,2002,1594,4237, 348, 369,1274,2197,2178,1838,4552, // 1152 1821,2830,3701,2757,2288,2003,4553,2951,2758, 144,3358, 882,4554,3995,2759,3470, // 1168 4555,2915,5114,4238,1726, 320,5115,3996,3046, 788,2996,5116,2831,1774,1327,2873, // 1184 3997,2832,5117,1306,4556,2004,1700,3831,3576,2364,2660, 787,2023, 506, 824,3702, // 1200 534, 323,4557,1044,3359,2024,1901, 946,3471,5118,1779,1500,1678,5119,1882,4558, // 1216 165, 243,4559,3703,2528, 123, 683,4239, 764,4560, 36,3998,1793, 589,2916, 816, // 1232 626,1667,3047,2237,1639,1555,1622,3832,3999,5120,4000,2874,1370,1228,1933, 891, // 1248 2084,2917, 304,4240,5121, 292,2997,2720,3577, 691,2101,4241,1115,4561, 118, 662, // 1264 5122, 611,1156, 854,2386,1316,2875, 2, 386, 515,2918,5123,5124,3286, 868,2238, // 1280 1486, 855,2661, 785,2216,3048,5125,1040,3216,3578,5126,3146, 448,5127,1525,5128, // 1296 2165,4562,5129,3833,5130,4242,2833,3579,3147, 503, 818,4001,3148,1568, 814, 676, // 1312 1444, 306,1749,5131,3834,1416,1030, 197,1428, 805,2834,1501,4563,5132,5133,5134, // 1328 1994,5135,4564,5136,5137,2198, 13,2792,3704,2998,3149,1229,1917,5138,3835,2132, // 1344 5139,4243,4565,2404,3580,5140,2217,1511,1727,1120,5141,5142, 646,3836,2448, 307, // 1360 5143,5144,1595,3217,5145,5146,5147,3705,1113,1356,4002,1465,2529,2530,5148, 519, // 1376 5149, 128,2133, 92,2289,1980,5150,4003,1512, 342,3150,2199,5151,2793,2218,1981, // 1392 3360,4244, 290,1656,1317, 789, 827,2365,5152,3837,4566, 562, 581,4004,5153, 401, // 1408 4567,2252, 94,4568,5154,1399,2794,5155,1463,2025,4569,3218,1944,5156, 828,1105, // 1424 4245,1262,1394,5157,4246, 605,4570,5158,1784,2876,5159,2835, 819,2102, 578,2200, // 1440 2952,5160,1502, 436,3287,4247,3288,2836,4005,2919,3472,3473,5161,2721,2320,5162, // 1456 5163,2337,2068, 23,4571, 193, 826,3838,2103, 699,1630,4248,3098, 390,1794,1064, // 1472 3581,5164,1579,3099,3100,1400,5165,4249,1839,1640,2877,5166,4572,4573, 137,4250, // 1488 598,3101,1967, 780, 104, 974,2953,5167, 278, 899, 253, 402, 572, 504, 493,1339, // 1504 5168,4006,1275,4574,2582,2558,5169,3706,3049,3102,2253, 565,1334,2722, 863, 41, // 1520 5170,5171,4575,5172,1657,2338, 19, 463,2760,4251, 606,5173,2999,3289,1087,2085, // 1536 1323,2662,3000,5174,1631,1623,1750,4252,2691,5175,2878, 791,2723,2663,2339, 232, // 1552 2421,5176,3001,1498,5177,2664,2630, 755,1366,3707,3290,3151,2026,1609, 119,1918, // 1568 3474, 862,1026,4253,5178,4007,3839,4576,4008,4577,2265,1952,2477,5179,1125, 817, // 1584 4254,4255,4009,1513,1766,2041,1487,4256,3050,3291,2837,3840,3152,5180,5181,1507, // 1600 5182,2692, 733, 40,1632,1106,2879, 345,4257, 841,2531, 230,4578,3002,1847,3292, // 1616 3475,5183,1263, 986,3476,5184, 735, 879, 254,1137, 857, 622,1300,1180,1388,1562, // 1632 4010,4011,2954, 967,2761,2665,1349, 592,2134,1692,3361,3003,1995,4258,1679,4012, // 1648 1902,2188,5185, 739,3708,2724,1296,1290,5186,4259,2201,2202,1922,1563,2605,2559, // 1664 1871,2762,3004,5187, 435,5188, 343,1108, 596, 17,1751,4579,2239,3477,3709,5189, // 1680 4580, 294,3582,2955,1693, 477, 979, 281,2042,3583, 643,2043,3710,2631,2795,2266, // 1696 1031,2340,2135,2303,3584,4581, 367,1249,2560,5190,3585,5191,4582,1283,3362,2005, // 1712 240,1762,3363,4583,4584, 836,1069,3153, 474,5192,2149,2532, 268,3586,5193,3219, // 1728 1521,1284,5194,1658,1546,4260,5195,3587,3588,5196,4261,3364,2693,1685,4262, 961, // 1744 1673,2632, 190,2006,2203,3841,4585,4586,5197, 570,2504,3711,1490,5198,4587,2633, // 1760 3293,1957,4588, 584,1514, 396,1045,1945,5199,4589,1968,2449,5200,5201,4590,4013, // 1776 619,5202,3154,3294, 215,2007,2796,2561,3220,4591,3221,4592, 763,4263,3842,4593, // 1792 5203,5204,1958,1767,2956,3365,3712,1174, 452,1477,4594,3366,3155,5205,2838,1253, // 1808 2387,2189,1091,2290,4264, 492,5206, 638,1169,1825,2136,1752,4014, 648, 926,1021, // 1824 1324,4595, 520,4596, 997, 847,1007, 892,4597,3843,2267,1872,3713,2405,1785,4598, // 1840 1953,2957,3103,3222,1728,4265,2044,3714,4599,2008,1701,3156,1551, 30,2268,4266, // 1856 5207,2027,4600,3589,5208, 501,5209,4267, 594,3478,2166,1822,3590,3479,3591,3223, // 1872 829,2839,4268,5210,1680,3157,1225,4269,5211,3295,4601,4270,3158,2341,5212,4602, // 1888 4271,5213,4015,4016,5214,1848,2388,2606,3367,5215,4603, 374,4017, 652,4272,4273, // 1904 375,1140, 798,5216,5217,5218,2366,4604,2269, 546,1659, 138,3051,2450,4605,5219, // 1920 2254, 612,1849, 910, 796,3844,1740,1371, 825,3845,3846,5220,2920,2562,5221, 692, // 1936 444,3052,2634, 801,4606,4274,5222,1491, 244,1053,3053,4275,4276, 340,5223,4018, // 1952 1041,3005, 293,1168, 87,1357,5224,1539, 959,5225,2240, 721, 694,4277,3847, 219, // 1968 1478, 644,1417,3368,2666,1413,1401,1335,1389,4019,5226,5227,3006,2367,3159,1826, // 1984 730,1515, 184,2840, 66,4607,5228,1660,2958, 246,3369, 378,1457, 226,3480, 975, // 2000 4020,2959,1264,3592, 674, 696,5229, 163,5230,1141,2422,2167, 713,3593,3370,4608, // 2016 4021,5231,5232,1186, 15,5233,1079,1070,5234,1522,3224,3594, 276,1050,2725, 758, // 2032 1126, 653,2960,3296,5235,2342, 889,3595,4022,3104,3007, 903,1250,4609,4023,3481, // 2048 3596,1342,1681,1718, 766,3297, 286, 89,2961,3715,5236,1713,5237,2607,3371,3008, // 2064 5238,2962,2219,3225,2880,5239,4610,2505,2533, 181, 387,1075,4024, 731,2190,3372, // 2080 5240,3298, 310, 313,3482,2304, 770,4278, 54,3054, 189,4611,3105,3848,4025,5241, // 2096 1230,1617,1850, 355,3597,4279,4612,3373, 111,4280,3716,1350,3160,3483,3055,4281, // 2112 2150,3299,3598,5242,2797,4026,4027,3009, 722,2009,5243,1071, 247,1207,2343,2478, // 2128 1378,4613,2010, 864,1437,1214,4614, 373,3849,1142,2220, 667,4615, 442,2763,2563, // 2144 3850,4028,1969,4282,3300,1840, 837, 170,1107, 934,1336,1883,5244,5245,2119,4283, // 2160 2841, 743,1569,5246,4616,4284, 582,2389,1418,3484,5247,1803,5248, 357,1395,1729, // 2176 3717,3301,2423,1564,2241,5249,3106,3851,1633,4617,1114,2086,4285,1532,5250, 482, // 2192 2451,4618,5251,5252,1492, 833,1466,5253,2726,3599,1641,2842,5254,1526,1272,3718, // 2208 4286,1686,1795, 416,2564,1903,1954,1804,5255,3852,2798,3853,1159,2321,5256,2881, // 2224 4619,1610,1584,3056,2424,2764, 443,3302,1163,3161,5257,5258,4029,5259,4287,2506, // 2240 3057,4620,4030,3162,2104,1647,3600,2011,1873,4288,5260,4289, 431,3485,5261, 250, // 2256 97, 81,4290,5262,1648,1851,1558, 160, 848,5263, 866, 740,1694,5264,2204,2843, // 2272 3226,4291,4621,3719,1687, 950,2479, 426, 469,3227,3720,3721,4031,5265,5266,1188, // 2288 424,1996, 861,3601,4292,3854,2205,2694, 168,1235,3602,4293,5267,2087,1674,4622, // 2304 3374,3303, 220,2565,1009,5268,3855, 670,3010, 332,1208, 717,5269,5270,3603,2452, // 2320 4032,3375,5271, 513,5272,1209,2882,3376,3163,4623,1080,5273,5274,5275,5276,2534, // 2336 3722,3604, 815,1587,4033,4034,5277,3605,3486,3856,1254,4624,1328,3058,1390,4035, // 2352 1741,4036,3857,4037,5278, 236,3858,2453,3304,5279,5280,3723,3859,1273,3860,4625, // 2368 5281, 308,5282,4626, 245,4627,1852,2480,1307,2583, 430, 715,2137,2454,5283, 270, // 2384 199,2883,4038,5284,3606,2727,1753, 761,1754, 725,1661,1841,4628,3487,3724,5285, // 2400 5286, 587, 14,3305, 227,2608, 326, 480,2270, 943,2765,3607, 291, 650,1884,5287, // 2416 1702,1226, 102,1547, 62,3488, 904,4629,3489,1164,4294,5288,5289,1224,1548,2766, // 2432 391, 498,1493,5290,1386,1419,5291,2056,1177,4630, 813, 880,1081,2368, 566,1145, // 2448 4631,2291,1001,1035,2566,2609,2242, 394,1286,5292,5293,2069,5294, 86,1494,1730, // 2464 4039, 491,1588, 745, 897,2963, 843,3377,4040,2767,2884,3306,1768, 998,2221,2070, // 2480 397,1827,1195,1970,3725,3011,3378, 284,5295,3861,2507,2138,2120,1904,5296,4041, // 2496 2151,4042,4295,1036,3490,1905, 114,2567,4296, 209,1527,5297,5298,2964,2844,2635, // 2512 2390,2728,3164, 812,2568,5299,3307,5300,1559, 737,1885,3726,1210, 885, 28,2695, // 2528 3608,3862,5301,4297,1004,1780,4632,5302, 346,1982,2222,2696,4633,3863,1742, 797, // 2544 1642,4043,1934,1072,1384,2152, 896,4044,3308,3727,3228,2885,3609,5303,2569,1959, // 2560 4634,2455,1786,5304,5305,5306,4045,4298,1005,1308,3728,4299,2729,4635,4636,1528, // 2576 2610, 161,1178,4300,1983, 987,4637,1101,4301, 631,4046,1157,3229,2425,1343,1241, // 2592 1016,2243,2570, 372, 877,2344,2508,1160, 555,1935, 911,4047,5307, 466,1170, 169, // 2608 1051,2921,2697,3729,2481,3012,1182,2012,2571,1251,2636,5308, 992,2345,3491,1540, // 2624 2730,1201,2071,2406,1997,2482,5309,4638, 528,1923,2191,1503,1874,1570,2369,3379, // 2640 3309,5310, 557,1073,5311,1828,3492,2088,2271,3165,3059,3107, 767,3108,2799,4639, // 2656 1006,4302,4640,2346,1267,2179,3730,3230, 778,4048,3231,2731,1597,2667,5312,4641, // 2672 5313,3493,5314,5315,5316,3310,2698,1433,3311, 131, 95,1504,4049, 723,4303,3166, // 2688 1842,3610,2768,2192,4050,2028,2105,3731,5317,3013,4051,1218,5318,3380,3232,4052, // 2704 4304,2584, 248,1634,3864, 912,5319,2845,3732,3060,3865, 654, 53,5320,3014,5321, // 2720 1688,4642, 777,3494,1032,4053,1425,5322, 191, 820,2121,2846, 971,4643, 931,3233, // 2736 135, 664, 783,3866,1998, 772,2922,1936,4054,3867,4644,2923,3234, 282,2732, 640, // 2752 1372,3495,1127, 922, 325,3381,5323,5324, 711,2045,5325,5326,4055,2223,2800,1937, // 2768 4056,3382,2224,2255,3868,2305,5327,4645,3869,1258,3312,4057,3235,2139,2965,4058, // 2784 4059,5328,2225, 258,3236,4646, 101,1227,5329,3313,1755,5330,1391,3314,5331,2924, // 2800 2057, 893,5332,5333,5334,1402,4305,2347,5335,5336,3237,3611,5337,5338, 878,1325, // 2816 1781,2801,4647, 259,1385,2585, 744,1183,2272,4648,5339,4060,2509,5340, 684,1024, // 2832 4306,5341, 472,3612,3496,1165,3315,4061,4062, 322,2153, 881, 455,1695,1152,1340, // 2848 660, 554,2154,4649,1058,4650,4307, 830,1065,3383,4063,4651,1924,5342,1703,1919, // 2864 5343, 932,2273, 122,5344,4652, 947, 677,5345,3870,2637, 297,1906,1925,2274,4653, // 2880 2322,3316,5346,5347,4308,5348,4309, 84,4310, 112, 989,5349, 547,1059,4064, 701, // 2896 3613,1019,5350,4311,5351,3497, 942, 639, 457,2306,2456, 993,2966, 407, 851, 494, // 2912 4654,3384, 927,5352,1237,5353,2426,3385, 573,4312, 680, 921,2925,1279,1875, 285, // 2928 790,1448,1984, 719,2168,5354,5355,4655,4065,4066,1649,5356,1541, 563,5357,1077, // 2944 5358,3386,3061,3498, 511,3015,4067,4068,3733,4069,1268,2572,3387,3238,4656,4657, // 2960 5359, 535,1048,1276,1189,2926,2029,3167,1438,1373,2847,2967,1134,2013,5360,4313, // 2976 1238,2586,3109,1259,5361, 700,5362,2968,3168,3734,4314,5363,4315,1146,1876,1907, // 2992 4658,2611,4070, 781,2427, 132,1589, 203, 147, 273,2802,2407, 898,1787,2155,4071, // 3008 4072,5364,3871,2803,5365,5366,4659,4660,5367,3239,5368,1635,3872, 965,5369,1805, // 3024 2699,1516,3614,1121,1082,1329,3317,4073,1449,3873, 65,1128,2848,2927,2769,1590, // 3040 3874,5370,5371, 12,2668, 45, 976,2587,3169,4661, 517,2535,1013,1037,3240,5372, // 3056 3875,2849,5373,3876,5374,3499,5375,2612, 614,1999,2323,3877,3110,2733,2638,5376, // 3072 2588,4316, 599,1269,5377,1811,3735,5378,2700,3111, 759,1060, 489,1806,3388,3318, // 3088 1358,5379,5380,2391,1387,1215,2639,2256, 490,5381,5382,4317,1759,2392,2348,5383, // 3104 4662,3878,1908,4074,2640,1807,3241,4663,3500,3319,2770,2349, 874,5384,5385,3501, // 3120 3736,1859, 91,2928,3737,3062,3879,4664,5386,3170,4075,2669,5387,3502,1202,1403, // 3136 3880,2969,2536,1517,2510,4665,3503,2511,5388,4666,5389,2701,1886,1495,1731,4076, // 3152 2370,4667,5390,2030,5391,5392,4077,2702,1216, 237,2589,4318,2324,4078,3881,4668, // 3168 4669,2703,3615,3504, 445,4670,5393,5394,5395,5396,2771, 61,4079,3738,1823,4080, // 3184 5397, 687,2046, 935, 925, 405,2670, 703,1096,1860,2734,4671,4081,1877,1367,2704, // 3200 3389, 918,2106,1782,2483, 334,3320,1611,1093,4672, 564,3171,3505,3739,3390, 945, // 3216 2641,2058,4673,5398,1926, 872,4319,5399,3506,2705,3112, 349,4320,3740,4082,4674, // 3232 3882,4321,3741,2156,4083,4675,4676,4322,4677,2408,2047, 782,4084, 400, 251,4323, // 3248 1624,5400,5401, 277,3742, 299,1265, 476,1191,3883,2122,4324,4325,1109, 205,5402, // 3264 2590,1000,2157,3616,1861,5403,5404,5405,4678,5406,4679,2573, 107,2484,2158,4085, // 3280 3507,3172,5407,1533, 541,1301, 158, 753,4326,2886,3617,5408,1696, 370,1088,4327, // 3296 4680,3618, 579, 327, 440, 162,2244, 269,1938,1374,3508, 968,3063, 56,1396,3113, // 3312 2107,3321,3391,5409,1927,2159,4681,3016,5410,3619,5411,5412,3743,4682,2485,5413, // 3328 2804,5414,1650,4683,5415,2613,5416,5417,4086,2671,3392,1149,3393,4087,3884,4088, // 3344 5418,1076, 49,5419, 951,3242,3322,3323, 450,2850, 920,5420,1812,2805,2371,4328, // 3360 1909,1138,2372,3885,3509,5421,3243,4684,1910,1147,1518,2428,4685,3886,5422,4686, // 3376 2393,2614, 260,1796,3244,5423,5424,3887,3324, 708,5425,3620,1704,5426,3621,1351, // 3392 1618,3394,3017,1887, 944,4329,3395,4330,3064,3396,4331,5427,3744, 422, 413,1714, // 3408 3325, 500,2059,2350,4332,2486,5428,1344,1911, 954,5429,1668,5430,5431,4089,2409, // 3424 4333,3622,3888,4334,5432,2307,1318,2512,3114, 133,3115,2887,4687, 629, 31,2851, // 3440 2706,3889,4688, 850, 949,4689,4090,2970,1732,2089,4335,1496,1853,5433,4091, 620, // 3456 3245, 981,1242,3745,3397,1619,3746,1643,3326,2140,2457,1971,1719,3510,2169,5434, // 3472 3246,5435,5436,3398,1829,5437,1277,4690,1565,2048,5438,1636,3623,3116,5439, 869, // 3488 2852, 655,3890,3891,3117,4092,3018,3892,1310,3624,4691,5440,5441,5442,1733, 558, // 3504 4692,3747, 335,1549,3065,1756,4336,3748,1946,3511,1830,1291,1192, 470,2735,2108, // 3520 2806, 913,1054,4093,5443,1027,5444,3066,4094,4693, 982,2672,3399,3173,3512,3247, // 3536 3248,1947,2807,5445, 571,4694,5446,1831,5447,3625,2591,1523,2429,5448,2090, 984, // 3552 4695,3749,1960,5449,3750, 852, 923,2808,3513,3751, 969,1519, 999,2049,2325,1705, // 3568 5450,3118, 615,1662, 151, 597,4095,2410,2326,1049, 275,4696,3752,4337, 568,3753, // 3584 3626,2487,4338,3754,5451,2430,2275, 409,3249,5452,1566,2888,3514,1002, 769,2853, // 3600 194,2091,3174,3755,2226,3327,4339, 628,1505,5453,5454,1763,2180,3019,4096, 521, // 3616 1161,2592,1788,2206,2411,4697,4097,1625,4340,4341, 412, 42,3119, 464,5455,2642, // 3632 4698,3400,1760,1571,2889,3515,2537,1219,2207,3893,2643,2141,2373,4699,4700,3328, // 3648 1651,3401,3627,5456,5457,3628,2488,3516,5458,3756,5459,5460,2276,2092, 460,5461, // 3664 4701,5462,3020, 962, 588,3629, 289,3250,2644,1116, 52,5463,3067,1797,5464,5465, // 3680 5466,1467,5467,1598,1143,3757,4342,1985,1734,1067,4702,1280,3402, 465,4703,1572, // 3696 510,5468,1928,2245,1813,1644,3630,5469,4704,3758,5470,5471,2673,1573,1534,5472, // 3712 5473, 536,1808,1761,3517,3894,3175,2645,5474,5475,5476,4705,3518,2929,1912,2809, // 3728 5477,3329,1122, 377,3251,5478, 360,5479,5480,4343,1529, 551,5481,2060,3759,1769, // 3744 2431,5482,2930,4344,3330,3120,2327,2109,2031,4706,1404, 136,1468,1479, 672,1171, // 3760 3252,2308, 271,3176,5483,2772,5484,2050, 678,2736, 865,1948,4707,5485,2014,4098, // 3776 2971,5486,2737,2227,1397,3068,3760,4708,4709,1735,2931,3403,3631,5487,3895, 509, // 3792 2854,2458,2890,3896,5488,5489,3177,3178,4710,4345,2538,4711,2309,1166,1010, 552, // 3808 681,1888,5490,5491,2972,2973,4099,1287,1596,1862,3179, 358, 453, 736, 175, 478, // 3824 1117, 905,1167,1097,5492,1854,1530,5493,1706,5494,2181,3519,2292,3761,3520,3632, // 3840 4346,2093,4347,5495,3404,1193,2489,4348,1458,2193,2208,1863,1889,1421,3331,2932, // 3856 3069,2182,3521, 595,2123,5496,4100,5497,5498,4349,1707,2646, 223,3762,1359, 751, // 3872 3121, 183,3522,5499,2810,3021, 419,2374, 633, 704,3897,2394, 241,5500,5501,5502, // 3888 838,3022,3763,2277,2773,2459,3898,1939,2051,4101,1309,3122,2246,1181,5503,1136, // 3904 2209,3899,2375,1446,4350,2310,4712,5504,5505,4351,1055,2615, 484,3764,5506,4102, // 3920 625,4352,2278,3405,1499,4353,4103,5507,4104,4354,3253,2279,2280,3523,5508,5509, // 3936 2774, 808,2616,3765,3406,4105,4355,3123,2539, 526,3407,3900,4356, 955,5510,1620, // 3952 4357,2647,2432,5511,1429,3766,1669,1832, 994, 928,5512,3633,1260,5513,5514,5515, // 3968 1949,2293, 741,2933,1626,4358,2738,2460, 867,1184, 362,3408,1392,5516,5517,4106, // 3984 4359,1770,1736,3254,2934,4713,4714,1929,2707,1459,1158,5518,3070,3409,2891,1292, // 4000 1930,2513,2855,3767,1986,1187,2072,2015,2617,4360,5519,2574,2514,2170,3768,2490, // 4016 3332,5520,3769,4715,5521,5522, 666,1003,3023,1022,3634,4361,5523,4716,1814,2257, // 4032 574,3901,1603, 295,1535, 705,3902,4362, 283, 858, 417,5524,5525,3255,4717,4718, // 4048 3071,1220,1890,1046,2281,2461,4107,1393,1599, 689,2575, 388,4363,5526,2491, 802, // 4064 5527,2811,3903,2061,1405,2258,5528,4719,3904,2110,1052,1345,3256,1585,5529, 809, // 4080 5530,5531,5532, 575,2739,3524, 956,1552,1469,1144,2328,5533,2329,1560,2462,3635, // 4096 3257,4108, 616,2210,4364,3180,2183,2294,5534,1833,5535,3525,4720,5536,1319,3770, // 4112 3771,1211,3636,1023,3258,1293,2812,5537,5538,5539,3905, 607,2311,3906, 762,2892, // 4128 1439,4365,1360,4721,1485,3072,5540,4722,1038,4366,1450,2062,2648,4367,1379,4723, // 4144 2593,5541,5542,4368,1352,1414,2330,2935,1172,5543,5544,3907,3908,4724,1798,1451, // 4160 5545,5546,5547,5548,2936,4109,4110,2492,2351, 411,4111,4112,3637,3333,3124,4725, // 4176 1561,2674,1452,4113,1375,5549,5550, 47,2974, 316,5551,1406,1591,2937,3181,5552, // 4192 1025,2142,3125,3182, 354,2740, 884,2228,4369,2412, 508,3772, 726,3638, 996,2433, // 4208 3639, 729,5553, 392,2194,1453,4114,4726,3773,5554,5555,2463,3640,2618,1675,2813, // 4224 919,2352,2975,2353,1270,4727,4115, 73,5556,5557, 647,5558,3259,2856,2259,1550, // 4240 1346,3024,5559,1332, 883,3526,5560,5561,5562,5563,3334,2775,5564,1212, 831,1347, // 4256 4370,4728,2331,3909,1864,3073, 720,3910,4729,4730,3911,5565,4371,5566,5567,4731, // 4272 5568,5569,1799,4732,3774,2619,4733,3641,1645,2376,4734,5570,2938, 669,2211,2675, // 4288 2434,5571,2893,5572,5573,1028,3260,5574,4372,2413,5575,2260,1353,5576,5577,4735, // 4304 3183, 518,5578,4116,5579,4373,1961,5580,2143,4374,5581,5582,3025,2354,2355,3912, // 4320 516,1834,1454,4117,2708,4375,4736,2229,2620,1972,1129,3642,5583,2776,5584,2976, // 4336 1422, 577,1470,3026,1524,3410,5585,5586, 432,4376,3074,3527,5587,2594,1455,2515, // 4352 2230,1973,1175,5588,1020,2741,4118,3528,4737,5589,2742,5590,1743,1361,3075,3529, // 4368 2649,4119,4377,4738,2295, 895, 924,4378,2171, 331,2247,3076, 166,1627,3077,1098, // 4384 5591,1232,2894,2231,3411,4739, 657, 403,1196,2377, 542,3775,3412,1600,4379,3530, // 4400 5592,4740,2777,3261, 576, 530,1362,4741,4742,2540,2676,3776,4120,5593, 842,3913, // 4416 5594,2814,2032,1014,4121, 213,2709,3413, 665, 621,4380,5595,3777,2939,2435,5596, // 4432 2436,3335,3643,3414,4743,4381,2541,4382,4744,3644,1682,4383,3531,1380,5597, 724, // 4448 2282, 600,1670,5598,1337,1233,4745,3126,2248,5599,1621,4746,5600, 651,4384,5601, // 4464 1612,4385,2621,5602,2857,5603,2743,2312,3078,5604, 716,2464,3079, 174,1255,2710, // 4480 4122,3645, 548,1320,1398, 728,4123,1574,5605,1891,1197,3080,4124,5606,3081,3082, // 4496 3778,3646,3779, 747,5607, 635,4386,4747,5608,5609,5610,4387,5611,5612,4748,5613, // 4512 3415,4749,2437, 451,5614,3780,2542,2073,4388,2744,4389,4125,5615,1764,4750,5616, // 4528 4390, 350,4751,2283,2395,2493,5617,4391,4126,2249,1434,4127, 488,4752, 458,4392, // 4544 4128,3781, 771,1330,2396,3914,2576,3184,2160,2414,1553,2677,3185,4393,5618,2494, // 4560 2895,2622,1720,2711,4394,3416,4753,5619,2543,4395,5620,3262,4396,2778,5621,2016, // 4576 2745,5622,1155,1017,3782,3915,5623,3336,2313, 201,1865,4397,1430,5624,4129,5625, // 4592 5626,5627,5628,5629,4398,1604,5630, 414,1866, 371,2595,4754,4755,3532,2017,3127, // 4608 4756,1708, 960,4399, 887, 389,2172,1536,1663,1721,5631,2232,4130,2356,2940,1580, // 4624 5632,5633,1744,4757,2544,4758,4759,5634,4760,5635,2074,5636,4761,3647,3417,2896, // 4640 4400,5637,4401,2650,3418,2815, 673,2712,2465, 709,3533,4131,3648,4402,5638,1148, // 4656 502, 634,5639,5640,1204,4762,3649,1575,4763,2623,3783,5641,3784,3128, 948,3263, // 4672 121,1745,3916,1110,5642,4403,3083,2516,3027,4132,3785,1151,1771,3917,1488,4133, // 4688 1987,5643,2438,3534,5644,5645,2094,5646,4404,3918,1213,1407,2816, 531,2746,2545, // 4704 3264,1011,1537,4764,2779,4405,3129,1061,5647,3786,3787,1867,2897,5648,2018, 120, // 4720 4406,4407,2063,3650,3265,2314,3919,2678,3419,1955,4765,4134,5649,3535,1047,2713, // 4736 1266,5650,1368,4766,2858, 649,3420,3920,2546,2747,1102,2859,2679,5651,5652,2000, // 4752 5653,1111,3651,2977,5654,2495,3921,3652,2817,1855,3421,3788,5655,5656,3422,2415, // 4768 2898,3337,3266,3653,5657,2577,5658,3654,2818,4135,1460, 856,5659,3655,5660,2899, // 4784 2978,5661,2900,3922,5662,4408, 632,2517, 875,3923,1697,3924,2296,5663,5664,4767, // 4800 3028,1239, 580,4768,4409,5665, 914, 936,2075,1190,4136,1039,2124,5666,5667,5668, // 4816 5669,3423,1473,5670,1354,4410,3925,4769,2173,3084,4137, 915,3338,4411,4412,3339, // 4832 1605,1835,5671,2748, 398,3656,4413,3926,4138, 328,1913,2860,4139,3927,1331,4414, // 4848 3029, 937,4415,5672,3657,4140,4141,3424,2161,4770,3425, 524, 742, 538,3085,1012, // 4864 5673,5674,3928,2466,5675, 658,1103, 225,3929,5676,5677,4771,5678,4772,5679,3267, // 4880 1243,5680,4142, 963,2250,4773,5681,2714,3658,3186,5682,5683,2596,2332,5684,4774, // 4896 5685,5686,5687,3536, 957,3426,2547,2033,1931,2941,2467, 870,2019,3659,1746,2780, // 4912 2781,2439,2468,5688,3930,5689,3789,3130,3790,3537,3427,3791,5690,1179,3086,5691, // 4928 3187,2378,4416,3792,2548,3188,3131,2749,4143,5692,3428,1556,2549,2297, 977,2901, // 4944 2034,4144,1205,3429,5693,1765,3430,3189,2125,1271, 714,1689,4775,3538,5694,2333, // 4960 3931, 533,4417,3660,2184, 617,5695,2469,3340,3539,2315,5696,5697,3190,5698,5699, // 4976 3932,1988, 618, 427,2651,3540,3431,5700,5701,1244,1690,5702,2819,4418,4776,5703, // 4992 3541,4777,5704,2284,1576, 473,3661,4419,3432, 972,5705,3662,5706,3087,5707,5708, // 5008 4778,4779,5709,3793,4145,4146,5710, 153,4780, 356,5711,1892,2902,4420,2144, 408, // 5024 803,2357,5712,3933,5713,4421,1646,2578,2518,4781,4782,3934,5714,3935,4422,5715, // 5040 2416,3433, 752,5716,5717,1962,3341,2979,5718, 746,3030,2470,4783,4423,3794, 698, // 5056 4784,1893,4424,3663,2550,4785,3664,3936,5719,3191,3434,5720,1824,1302,4147,2715, // 5072 3937,1974,4425,5721,4426,3192, 823,1303,1288,1236,2861,3542,4148,3435, 774,3938, // 5088 5722,1581,4786,1304,2862,3939,4787,5723,2440,2162,1083,3268,4427,4149,4428, 344, // 5104 1173, 288,2316, 454,1683,5724,5725,1461,4788,4150,2597,5726,5727,4789, 985, 894, // 5120 5728,3436,3193,5729,1914,2942,3795,1989,5730,2111,1975,5731,4151,5732,2579,1194, // 5136 425,5733,4790,3194,1245,3796,4429,5734,5735,2863,5736, 636,4791,1856,3940, 760, // 5152 1800,5737,4430,2212,1508,4792,4152,1894,1684,2298,5738,5739,4793,4431,4432,2213, // 5168 479,5740,5741, 832,5742,4153,2496,5743,2980,2497,3797, 990,3132, 627,1815,2652, // 5184 4433,1582,4434,2126,2112,3543,4794,5744, 799,4435,3195,5745,4795,2113,1737,3031, // 5200 1018, 543, 754,4436,3342,1676,4796,4797,4154,4798,1489,5746,3544,5747,2624,2903, // 5216 4155,5748,5749,2981,5750,5751,5752,5753,3196,4799,4800,2185,1722,5754,3269,3270, // 5232 1843,3665,1715, 481, 365,1976,1857,5755,5756,1963,2498,4801,5757,2127,3666,3271, // 5248 433,1895,2064,2076,5758, 602,2750,5759,5760,5761,5762,5763,3032,1628,3437,5764, // 5264 3197,4802,4156,2904,4803,2519,5765,2551,2782,5766,5767,5768,3343,4804,2905,5769, // 5280 4805,5770,2864,4806,4807,1221,2982,4157,2520,5771,5772,5773,1868,1990,5774,5775, // 5296 5776,1896,5777,5778,4808,1897,4158, 318,5779,2095,4159,4437,5780,5781, 485,5782, // 5312 938,3941, 553,2680, 116,5783,3942,3667,5784,3545,2681,2783,3438,3344,2820,5785, // 5328 3668,2943,4160,1747,2944,2983,5786,5787, 207,5788,4809,5789,4810,2521,5790,3033, // 5344 890,3669,3943,5791,1878,3798,3439,5792,2186,2358,3440,1652,5793,5794,5795, 941, // 5360 2299, 208,3546,4161,2020, 330,4438,3944,2906,2499,3799,4439,4811,5796,5797,5798, // 5376 //last 512 -/*************************************************************************************** +/*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 2522,1613,4812,5799,3345,3945,2523,5800,4162,5801,1637,4163,2471,4813,3946,5802, // 5392 2500,3034,3800,5803,5804,2195,4814,5805,2163,5806,5807,5808,5809,5810,5811,5812, // 5408 5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828, // 5424 5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844, // 5440 5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856,5857,5858,5859,5860, // 5456 5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872,5873,5874,5875,5876, // 5472 5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888,5889,5890,5891,5892, // 5488 5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905,5906,5907,5908, // 5504 5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920,5921,5922,5923,5924, // 5520 5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936,5937,5938,5939,5940, // 5536 5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952,5953,5954,5955,5956, // 5552 5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968,5969,5970,5971,5972, // 5568 5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984,5985,5986,5987,5988, // 5584 5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004, // 5600 6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020, // 5616 6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032,6033,6034,6035,6036, // 5632 6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052, // 5648 6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068, // 5664 6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084, // 5680 6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100, // 5696 6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116, // 5712 6117,6118,6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,6132, // 5728 6133,6134,6135,6136,6137,6138,6139,6140,6141,6142,6143,6144,6145,6146,6147,6148, // 5744 6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163,6164, // 5760 6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179,6180, // 5776 6181,6182,6183,6184,6185,6186,6187,6188,6189,6190,6191,6192,6193,6194,6195,6196, // 5792 6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210,6211,6212, // 5808 6213,6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,3670,6224,6225,6226,6227, // 5824 6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241,6242,6243, // 5840 6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,6254,6255,6256,6257,6258,6259, // 5856 6260,6261,6262,6263,6264,6265,6266,6267,6268,6269,6270,6271,6272,6273,6274,6275, // 5872 6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,4815,6286,6287,6288,6289,6290, // 5888 6291,6292,4816,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,6303,6304,6305, // 5904 6306,6307,6308,6309,6310,6311,4817,4818,6312,6313,6314,6315,6316,6317,6318,4819, // 5920 6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333,6334, // 5936 6335,6336,6337,4820,6338,6339,6340,6341,6342,6343,6344,6345,6346,6347,6348,6349, // 5952 6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363,6364,6365, // 5968 6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379,6380,6381, // 5984 6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395,6396,6397, // 6000 6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,3441,6411,6412, // 6016 6413,6414,6415,6416,6417,6418,6419,6420,6421,6422,6423,6424,6425,4440,6426,6427, // 6032 6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,6439,6440,6441,6442,6443, // 6048 6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,4821,6455,6456,6457,6458, // 6064 6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472,6473,6474, // 6080 6475,6476,6477,3947,3948,6478,6479,6480,6481,3272,4441,6482,6483,6484,6485,4442, // 6096 6486,6487,6488,6489,6490,6491,6492,6493,6494,6495,6496,4822,6497,6498,6499,6500, // 6112 6501,6502,6503,6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516, // 6128 6517,6518,6519,6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532, // 6144 6533,6534,6535,6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548, // 6160 6549,6550,6551,6552,6553,6554,6555,6556,2784,6557,4823,6558,6559,6560,6561,6562, // 6176 6563,6564,6565,6566,6567,6568,6569,3949,6570,6571,6572,4824,6573,6574,6575,6576, // 6192 6577,6578,6579,6580,6581,6582,6583,4825,6584,6585,6586,3950,2785,6587,6588,6589, // 6208 6590,6591,6592,6593,6594,6595,6596,6597,6598,6599,6600,6601,6602,6603,6604,6605, // 6224 6606,6607,6608,6609,6610,6611,6612,4826,6613,6614,6615,4827,6616,6617,6618,6619, // 6240 6620,6621,6622,6623,6624,6625,4164,6626,6627,6628,6629,6630,6631,6632,6633,6634, // 6256 3547,6635,4828,6636,6637,6638,6639,6640,6641,6642,3951,2984,6643,6644,6645,6646, // 6272 6647,6648,6649,4165,6650,4829,6651,6652,4830,6653,6654,6655,6656,6657,6658,6659, // 6288 6660,6661,6662,4831,6663,6664,6665,6666,6667,6668,6669,6670,6671,4166,6672,4832, // 6304 3952,6673,6674,6675,6676,4833,6677,6678,6679,4167,6680,6681,6682,3198,6683,6684, // 6320 6685,6686,6687,6688,6689,6690,6691,6692,6693,6694,6695,6696,6697,4834,6698,6699, // 6336 6700,6701,6702,6703,6704,6705,6706,6707,6708,6709,6710,6711,6712,6713,6714,6715, // 6352 6716,6717,6718,6719,6720,6721,6722,6723,6724,6725,6726,6727,6728,6729,6730,6731, // 6368 6732,6733,6734,4443,6735,6736,6737,6738,6739,6740,6741,6742,6743,6744,6745,4444, // 6384 6746,6747,6748,6749,6750,6751,6752,6753,6754,6755,6756,6757,6758,6759,6760,6761, // 6400 6762,6763,6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777, // 6416 6778,6779,6780,6781,4168,6782,6783,3442,6784,6785,6786,6787,6788,6789,6790,6791, // 6432 4169,6792,6793,6794,6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806, // 6448 6807,6808,6809,6810,6811,4835,6812,6813,6814,4445,6815,6816,4446,6817,6818,6819, // 6464 6820,6821,6822,6823,6824,6825,6826,6827,6828,6829,6830,6831,6832,6833,6834,6835, // 6480 3548,6836,6837,6838,6839,6840,6841,6842,6843,6844,6845,6846,4836,6847,6848,6849, // 6496 6850,6851,6852,6853,6854,3953,6855,6856,6857,6858,6859,6860,6861,6862,6863,6864, // 6512 6865,6866,6867,6868,6869,6870,6871,6872,6873,6874,6875,6876,6877,3199,6878,6879, // 6528 6880,6881,6882,4447,6883,6884,6885,6886,6887,6888,6889,6890,6891,6892,6893,6894, // 6544 6895,6896,6897,6898,6899,6900,6901,6902,6903,6904,4170,6905,6906,6907,6908,6909, // 6560 6910,6911,6912,6913,6914,6915,6916,6917,6918,6919,6920,6921,6922,6923,6924,6925, // 6576 6926,6927,4837,6928,6929,6930,6931,6932,6933,6934,6935,6936,3346,6937,6938,4838, // 6592 6939,6940,6941,4448,6942,6943,6944,6945,6946,4449,6947,6948,6949,6950,6951,6952, // 6608 6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966,6967,6968, // 6624 6969,6970,6971,6972,6973,6974,6975,6976,6977,6978,6979,6980,6981,6982,6983,6984, // 6640 6985,6986,6987,6988,6989,6990,6991,6992,6993,6994,3671,6995,6996,6997,6998,4839, // 6656 6999,7000,7001,7002,3549,7003,7004,7005,7006,7007,7008,7009,7010,7011,7012,7013, // 6672 7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027,7028,7029, // 6688 7030,4840,7031,7032,7033,7034,7035,7036,7037,7038,4841,7039,7040,7041,7042,7043, // 6704 7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058,7059, // 6720 7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,2985,7071,7072,7073,7074, // 6736 7075,7076,7077,7078,7079,7080,4842,7081,7082,7083,7084,7085,7086,7087,7088,7089, // 6752 7090,7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105, // 6768 7106,7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,4450,7119,7120, // 6784 7121,7122,7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136, // 6800 7137,7138,7139,7140,7141,7142,7143,4843,7144,7145,7146,7147,7148,7149,7150,7151, // 6816 7152,7153,7154,7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167, // 6832 7168,7169,7170,7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183, // 6848 7184,7185,7186,7187,7188,4171,4172,7189,7190,7191,7192,7193,7194,7195,7196,7197, // 6864 7198,7199,7200,7201,7202,7203,7204,7205,7206,7207,7208,7209,7210,7211,7212,7213, // 6880 7214,7215,7216,7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229, // 6896 7230,7231,7232,7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245, // 6912 7246,7247,7248,7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261, // 6928 7262,7263,7264,7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277, // 6944 7278,7279,7280,7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293, // 6960 7294,7295,7296,4844,7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308, // 6976 7309,7310,7311,7312,7313,7314,7315,7316,4451,7317,7318,7319,7320,7321,7322,7323, // 6992 7324,7325,7326,7327,7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339, // 7008 7340,7341,7342,7343,7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,4173,7354, // 7024 7355,4845,7356,7357,7358,7359,7360,7361,7362,7363,7364,7365,7366,7367,7368,7369, // 7040 7370,7371,7372,7373,7374,7375,7376,7377,7378,7379,7380,7381,7382,7383,7384,7385, // 7056 7386,7387,7388,4846,7389,7390,7391,7392,7393,7394,7395,7396,7397,7398,7399,7400, // 7072 7401,7402,7403,7404,7405,3672,7406,7407,7408,7409,7410,7411,7412,7413,7414,7415, // 7088 7416,7417,7418,7419,7420,7421,7422,7423,7424,7425,7426,7427,7428,7429,7430,7431, // 7104 7432,7433,7434,7435,7436,7437,7438,7439,7440,7441,7442,7443,7444,7445,7446,7447, // 7120 7448,7449,7450,7451,7452,7453,4452,7454,3200,7455,7456,7457,7458,7459,7460,7461, // 7136 7462,7463,7464,7465,7466,7467,7468,7469,7470,7471,7472,7473,7474,4847,7475,7476, // 7152 7477,3133,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487,7488,7489,7490,7491, // 7168 7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,3347,7503,7504,7505,7506, // 7184 7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519,7520,7521,4848, // 7200 7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535,7536,7537, // 7216 7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,3801,4849,7550,7551, // 7232 7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, // 7248 7568,7569,3035,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582, // 7264 7583,7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598, // 7280 7599,7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614, // 7296 7615,7616,4850,7617,7618,3802,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628, // 7312 7629,7630,7631,7632,4851,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643, // 7328 7644,7645,7646,7647,7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659, // 7344 7660,7661,7662,7663,7664,7665,7666,7667,7668,7669,7670,4453,7671,7672,7673,7674, // 7360 7675,7676,7677,7678,7679,7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690, // 7376 7691,7692,7693,7694,7695,7696,7697,3443,7698,7699,7700,7701,7702,4454,7703,7704, // 7392 7705,7706,7707,7708,7709,7710,7711,7712,7713,2472,7714,7715,7716,7717,7718,7719, // 7408 7720,7721,7722,7723,7724,7725,7726,7727,7728,7729,7730,7731,3954,7732,7733,7734, // 7424 7735,7736,7737,7738,7739,7740,7741,7742,7743,7744,7745,7746,7747,7748,7749,7750, // 7440 3134,7751,7752,4852,7753,7754,7755,4853,7756,7757,7758,7759,7760,4174,7761,7762, // 7456 7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,7777,7778, // 7472 7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791,7792,7793,7794, // 7488 7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,4854,7806,7807,7808,7809, // 7504 7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824,7825, // 7520 4855,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, // 7536 7841,7842,7843,7844,7845,7846,7847,3955,7848,7849,7850,7851,7852,7853,7854,7855, // 7552 7856,7857,7858,7859,7860,3444,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870, // 7568 7871,7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886, // 7584 7887,7888,7889,7890,7891,4175,7892,7893,7894,7895,7896,4856,4857,7897,7898,7899, // 7600 7900,2598,7901,7902,7903,7904,7905,7906,7907,7908,4455,7909,7910,7911,7912,7913, // 7616 7914,3201,7915,7916,7917,7918,7919,7920,7921,4858,7922,7923,7924,7925,7926,7927, // 7632 7928,7929,7930,7931,7932,7933,7934,7935,7936,7937,7938,7939,7940,7941,7942,7943, // 7648 7944,7945,7946,7947,7948,7949,7950,7951,7952,7953,7954,7955,7956,7957,7958,7959, // 7664 7960,7961,7962,7963,7964,7965,7966,7967,7968,7969,7970,7971,7972,7973,7974,7975, // 7680 7976,7977,7978,7979,7980,7981,4859,7982,7983,7984,7985,7986,7987,7988,7989,7990, // 7696 7991,7992,7993,7994,7995,7996,4860,7997,7998,7999,8000,8001,8002,8003,8004,8005, // 7712 8006,8007,8008,8009,8010,8011,8012,8013,8014,8015,8016,4176,8017,8018,8019,8020, // 7728 8021,8022,8023,4861,8024,8025,8026,8027,8028,8029,8030,8031,8032,8033,8034,8035, // 7744 8036,4862,4456,8037,8038,8039,8040,4863,8041,8042,8043,8044,8045,8046,8047,8048, // 7760 8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063,8064, // 7776 8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079,8080, // 7792 8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095,8096, // 7808 8097,8098,8099,4864,4177,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110, // 7824 8111,8112,8113,8114,8115,8116,8117,8118,8119,8120,4178,8121,8122,8123,8124,8125, // 7840 8126,8127,8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141, // 7856 8142,8143,8144,8145,4865,4866,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155, // 7872 8156,8157,8158,8159,8160,8161,8162,8163,8164,8165,4179,8166,8167,8168,8169,8170, // 7888 8171,8172,8173,8174,8175,8176,8177,8178,8179,8180,8181,4457,8182,8183,8184,8185, // 7904 8186,8187,8188,8189,8190,8191,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201, // 7920 8202,8203,8204,8205,8206,8207,8208,8209,8210,8211,8212,8213,8214,8215,8216,8217, // 7936 8218,8219,8220,8221,8222,8223,8224,8225,8226,8227,8228,8229,8230,8231,8232,8233, // 7952 8234,8235,8236,8237,8238,8239,8240,8241,8242,8243,8244,8245,8246,8247,8248,8249, // 7968 8250,8251,8252,8253,8254,8255,8256,3445,8257,8258,8259,8260,8261,8262,4458,8263, // 7984 8264,8265,8266,8267,8268,8269,8270,8271,8272,4459,8273,8274,8275,8276,3550,8277, // 8000 8278,8279,8280,8281,8282,8283,8284,8285,8286,8287,8288,8289,4460,8290,8291,8292, // 8016 8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303,8304,8305,8306,8307,4867, // 8032 8308,8309,8310,8311,8312,3551,8313,8314,8315,8316,8317,8318,8319,8320,8321,8322, // 8048 8323,8324,8325,8326,4868,8327,8328,8329,8330,8331,8332,8333,8334,8335,8336,8337, // 8064 8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351,8352,8353, // 8080 8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,4869,4461,8364,8365,8366,8367, // 8096 8368,8369,8370,4870,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382, // 8112 8383,8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398, // 8128 8399,8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,4871,8411,8412,8413, // 8144 8414,8415,8416,8417,8418,8419,8420,8421,8422,4462,8423,8424,8425,8426,8427,8428, // 8160 8429,8430,8431,8432,8433,2986,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443, // 8176 8444,8445,8446,8447,8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459, // 8192 8460,8461,8462,8463,8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475, // 8208 8476,8477,8478,4180,8479,8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490, // 8224 8491,8492,8493,8494,8495,8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506, // 8240 8507,8508,8509,8510,8511,8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522, // 8256 8523,8524,8525,8526,8527,8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538, // 8272 8539,8540,8541,8542,8543,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554, // 8288 8555,8556,8557,8558,8559,8560,8561,8562,8563,8564,4872,8565,8566,8567,8568,8569, // 8304 8570,8571,8572,8573,4873,8574,8575,8576,8577,8578,8579,8580,8581,8582,8583,8584, // 8320 8585,8586,8587,8588,8589,8590,8591,8592,8593,8594,8595,8596,8597,8598,8599,8600, // 8336 8601,8602,8603,8604,8605,3803,8606,8607,8608,8609,8610,8611,8612,8613,4874,3804, // 8352 8614,8615,8616,8617,8618,8619,8620,8621,3956,8622,8623,8624,8625,8626,8627,8628, // 8368 8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,2865,8639,8640,8641,8642,8643, // 8384 8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655,8656,4463,8657,8658, // 8400 8659,4875,4876,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671,8672, // 8416 8673,8674,8675,8676,8677,8678,8679,8680,8681,4464,8682,8683,8684,8685,8686,8687, // 8432 8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, // 8448 8704,8705,8706,8707,8708,8709,2261,8710,8711,8712,8713,8714,8715,8716,8717,8718, // 8464 8719,8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,4181, // 8480 8734,8735,8736,8737,8738,8739,8740,8741,8742,8743,8744,8745,8746,8747,8748,8749, // 8496 8750,8751,8752,8753,8754,8755,8756,8757,8758,8759,8760,8761,8762,8763,4877,8764, // 8512 8765,8766,8767,8768,8769,8770,8771,8772,8773,8774,8775,8776,8777,8778,8779,8780, // 8528 8781,8782,8783,8784,8785,8786,8787,8788,4878,8789,4879,8790,8791,8792,4880,8793, // 8544 8794,8795,8796,8797,8798,8799,8800,8801,4881,8802,8803,8804,8805,8806,8807,8808, // 8560 8809,8810,8811,8812,8813,8814,8815,3957,8816,8817,8818,8819,8820,8821,8822,8823, // 8576 8824,8825,8826,8827,8828,8829,8830,8831,8832,8833,8834,8835,8836,8837,8838,8839, // 8592 8840,8841,8842,8843,8844,8845,8846,8847,4882,8848,8849,8850,8851,8852,8853,8854, // 8608 8855,8856,8857,8858,8859,8860,8861,8862,8863,8864,8865,8866,8867,8868,8869,8870, // 8624 8871,8872,8873,8874,8875,8876,8877,8878,8879,8880,8881,8882,8883,8884,3202,8885, // 8640 8886,8887,8888,8889,8890,8891,8892,8893,8894,8895,8896,8897,8898,8899,8900,8901, // 8656 8902,8903,8904,8905,8906,8907,8908,8909,8910,8911,8912,8913,8914,8915,8916,8917, // 8672 8918,8919,8920,8921,8922,8923,8924,4465,8925,8926,8927,8928,8929,8930,8931,8932, // 8688 4883,8933,8934,8935,8936,8937,8938,8939,8940,8941,8942,8943,2214,8944,8945,8946, // 8704 8947,8948,8949,8950,8951,8952,8953,8954,8955,8956,8957,8958,8959,8960,8961,8962, // 8720 8963,8964,8965,4884,8966,8967,8968,8969,8970,8971,8972,8973,8974,8975,8976,8977, // 8736 8978,8979,8980,8981,8982,8983,8984,8985,8986,8987,8988,8989,8990,8991,8992,4885, // 8752 8993,8994,8995,8996,8997,8998,8999,9000,9001,9002,9003,9004,9005,9006,9007,9008, // 8768 9009,9010,9011,9012,9013,9014,9015,9016,9017,9018,9019,9020,9021,4182,9022,9023, // 8784 9024,9025,9026,9027,9028,9029,9030,9031,9032,9033,9034,9035,9036,9037,9038,9039, // 8800 9040,9041,9042,9043,9044,9045,9046,9047,9048,9049,9050,9051,9052,9053,9054,9055, // 8816 9056,9057,9058,9059,9060,9061,9062,9063,4886,9064,9065,9066,9067,9068,9069,4887, // 8832 9070,9071,9072,9073,9074,9075,9076,9077,9078,9079,9080,9081,9082,9083,9084,9085, // 8848 9086,9087,9088,9089,9090,9091,9092,9093,9094,9095,9096,9097,9098,9099,9100,9101, // 8864 9102,9103,9104,9105,9106,9107,9108,9109,9110,9111,9112,9113,9114,9115,9116,9117, // 8880 9118,9119,9120,9121,9122,9123,9124,9125,9126,9127,9128,9129,9130,9131,9132,9133, // 8896 9134,9135,9136,9137,9138,9139,9140,9141,3958,9142,9143,9144,9145,9146,9147,9148, // 8912 9149,9150,9151,4888,9152,9153,9154,9155,9156,9157,9158,9159,9160,9161,9162,9163, // 8928 9164,9165,9166,9167,9168,9169,9170,9171,9172,9173,9174,9175,4889,9176,9177,9178, // 8944 9179,9180,9181,9182,9183,9184,9185,9186,9187,9188,9189,9190,9191,9192,9193,9194, // 8960 9195,9196,9197,9198,9199,9200,9201,9202,9203,4890,9204,9205,9206,9207,9208,9209, // 8976 9210,9211,9212,9213,9214,9215,9216,9217,9218,9219,9220,9221,9222,4466,9223,9224, // 8992 9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,9239,9240, // 9008 9241,9242,9243,9244,9245,4891,9246,9247,9248,9249,9250,9251,9252,9253,9254,9255, // 9024 9256,9257,4892,9258,9259,9260,9261,4893,4894,9262,9263,9264,9265,9266,9267,9268, // 9040 9269,9270,9271,9272,9273,4467,9274,9275,9276,9277,9278,9279,9280,9281,9282,9283, // 9056 9284,9285,3673,9286,9287,9288,9289,9290,9291,9292,9293,9294,9295,9296,9297,9298, // 9072 9299,9300,9301,9302,9303,9304,9305,9306,9307,9308,9309,9310,9311,9312,9313,9314, // 9088 9315,9316,9317,9318,9319,9320,9321,9322,4895,9323,9324,9325,9326,9327,9328,9329, // 9104 9330,9331,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345, // 9120 9346,9347,4468,9348,9349,9350,9351,9352,9353,9354,9355,9356,9357,9358,9359,9360, // 9136 9361,9362,9363,9364,9365,9366,9367,9368,9369,9370,9371,9372,9373,4896,9374,4469, // 9152 9375,9376,9377,9378,9379,4897,9380,9381,9382,9383,9384,9385,9386,9387,9388,9389, // 9168 9390,9391,9392,9393,9394,9395,9396,9397,9398,9399,9400,9401,9402,9403,9404,9405, // 9184 9406,4470,9407,2751,9408,9409,3674,3552,9410,9411,9412,9413,9414,9415,9416,9417, // 9200 9418,9419,9420,9421,4898,9422,9423,9424,9425,9426,9427,9428,9429,3959,9430,9431, // 9216 9432,9433,9434,9435,9436,4471,9437,9438,9439,9440,9441,9442,9443,9444,9445,9446, // 9232 9447,9448,9449,9450,3348,9451,9452,9453,9454,9455,9456,9457,9458,9459,9460,9461, // 9248 9462,9463,9464,9465,9466,9467,9468,9469,9470,9471,9472,4899,9473,9474,9475,9476, // 9264 9477,4900,9478,9479,9480,9481,9482,9483,9484,9485,9486,9487,9488,3349,9489,9490, // 9280 9491,9492,9493,9494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506, // 9296 9507,9508,9509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,4901,9521, // 9312 9522,9523,9524,9525,9526,4902,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536, // 9328 9537,9538,9539,9540,9541,9542,9543,9544,9545,9546,9547,9548,9549,9550,9551,9552, // 9344 9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,9564,9565,9566,9567,9568, // 9360 9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,9579,9580,9581,9582,9583,9584, // 9376 3805,9585,9586,9587,9588,9589,9590,9591,9592,9593,9594,9595,9596,9597,9598,9599, // 9392 9600,9601,9602,4903,9603,9604,9605,9606,9607,4904,9608,9609,9610,9611,9612,9613, // 9408 9614,4905,9615,9616,9617,9618,9619,9620,9621,9622,9623,9624,9625,9626,9627,9628, // 9424 9629,9630,9631,9632,4906,9633,9634,9635,9636,9637,9638,9639,9640,9641,9642,9643, // 9440 4907,9644,9645,9646,9647,9648,9649,9650,9651,9652,9653,9654,9655,9656,9657,9658, // 9456 9659,9660,9661,9662,9663,9664,9665,9666,9667,9668,9669,9670,9671,9672,4183,9673, // 9472 9674,9675,9676,9677,4908,9678,9679,9680,9681,4909,9682,9683,9684,9685,9686,9687, // 9488 9688,9689,9690,4910,9691,9692,9693,3675,9694,9695,9696,2945,9697,9698,9699,9700, // 9504 9701,9702,9703,9704,9705,4911,9706,9707,9708,9709,9710,9711,9712,9713,9714,9715, // 9520 9716,9717,9718,9719,9720,9721,9722,9723,9724,9725,9726,9727,9728,9729,9730,9731, // 9536 9732,9733,9734,9735,4912,9736,9737,9738,9739,9740,4913,9741,9742,9743,9744,9745, // 9552 9746,9747,9748,9749,9750,9751,9752,9753,9754,9755,9756,9757,9758,4914,9759,9760, // 9568 9761,9762,9763,9764,9765,9766,9767,9768,9769,9770,9771,9772,9773,9774,9775,9776, // 9584 9777,9778,9779,9780,9781,9782,4915,9783,9784,9785,9786,9787,9788,9789,9790,9791, // 9600 9792,9793,4916,9794,9795,9796,9797,9798,9799,9800,9801,9802,9803,9804,9805,9806, // 9616 9807,9808,9809,9810,9811,9812,9813,9814,9815,9816,9817,9818,9819,9820,9821,9822, // 9632 9823,9824,9825,9826,9827,9828,9829,9830,9831,9832,9833,9834,9835,9836,9837,9838, // 9648 9839,9840,9841,9842,9843,9844,9845,9846,9847,9848,9849,9850,9851,9852,9853,9854, // 9664 9855,9856,9857,9858,9859,9860,9861,9862,9863,9864,9865,9866,9867,9868,4917,9869, // 9680 9870,9871,9872,9873,9874,9875,9876,9877,9878,9879,9880,9881,9882,9883,9884,9885, // 9696 9886,9887,9888,9889,9890,9891,9892,4472,9893,9894,9895,9896,9897,3806,9898,9899, // 9712 9900,9901,9902,9903,9904,9905,9906,9907,9908,9909,9910,9911,9912,9913,9914,4918, // 9728 9915,9916,9917,4919,9918,9919,9920,9921,4184,9922,9923,9924,9925,9926,9927,9928, // 9744 9929,9930,9931,9932,9933,9934,9935,9936,9937,9938,9939,9940,9941,9942,9943,9944, // 9760 9945,9946,4920,9947,9948,9949,9950,9951,9952,9953,9954,9955,4185,9956,9957,9958, // 9776 9959,9960,9961,9962,9963,9964,9965,4921,9966,9967,9968,4473,9969,9970,9971,9972, // 9792 9973,9974,9975,9976,9977,4474,9978,9979,9980,9981,9982,9983,9984,9985,9986,9987, // 9808 9988,9989,9990,9991,9992,9993,9994,9995,9996,9997,9998,9999,10000,10001,10002,10003, // 9824 10004,10005,10006,10007,10008,10009,10010,10011,10012,10013,10014,10015,10016,10017,10018,10019, // 9840 10020,10021,4922,10022,4923,10023,10024,10025,10026,10027,10028,10029,10030,10031,10032,10033, // 9856 10034,10035,10036,10037,10038,10039,10040,10041,10042,10043,10044,10045,10046,10047,10048,4924, // 9872 10049,10050,10051,10052,10053,10054,10055,10056,10057,10058,10059,10060,10061,10062,10063,10064, // 9888 10065,10066,10067,10068,10069,10070,10071,10072,10073,10074,10075,10076,10077,10078,10079,10080, // 9904 10081,10082,10083,10084,10085,10086,10087,4475,10088,10089,10090,10091,10092,10093,10094,10095, // 9920 10096,10097,4476,10098,10099,10100,10101,10102,10103,10104,10105,10106,10107,10108,10109,10110, // 9936 10111,2174,10112,10113,10114,10115,10116,10117,10118,10119,10120,10121,10122,10123,10124,10125, // 9952 10126,10127,10128,10129,10130,10131,10132,10133,10134,10135,10136,10137,10138,10139,10140,3807, // 9968 4186,4925,10141,10142,10143,10144,10145,10146,10147,4477,4187,10148,10149,10150,10151,10152, // 9984 10153,4188,10154,10155,10156,10157,10158,10159,10160,10161,4926,10162,10163,10164,10165,10166, //10000 10167,10168,10169,10170,10171,10172,10173,10174,10175,10176,10177,10178,10179,10180,10181,10182, //10016 10183,10184,10185,10186,10187,10188,10189,10190,10191,10192,3203,10193,10194,10195,10196,10197, //10032 10198,10199,10200,4478,10201,10202,10203,10204,4479,10205,10206,10207,10208,10209,10210,10211, //10048 10212,10213,10214,10215,10216,10217,10218,10219,10220,10221,10222,10223,10224,10225,10226,10227, //10064 10228,10229,10230,10231,10232,10233,10234,4927,10235,10236,10237,10238,10239,10240,10241,10242, //10080 10243,10244,10245,10246,10247,10248,10249,10250,10251,10252,10253,10254,10255,10256,10257,10258, //10096 10259,10260,10261,10262,10263,10264,10265,10266,10267,10268,10269,10270,10271,10272,10273,4480, //10112 4928,4929,10274,10275,10276,10277,10278,10279,10280,10281,10282,10283,10284,10285,10286,10287, //10128 10288,10289,10290,10291,10292,10293,10294,10295,10296,10297,10298,10299,10300,10301,10302,10303, //10144 10304,10305,10306,10307,10308,10309,10310,10311,10312,10313,10314,10315,10316,10317,10318,10319, //10160 10320,10321,10322,10323,10324,10325,10326,10327,10328,10329,10330,10331,10332,10333,10334,4930, //10176 10335,10336,10337,10338,10339,10340,10341,10342,4931,10343,10344,10345,10346,10347,10348,10349, //10192 10350,10351,10352,10353,10354,10355,3088,10356,2786,10357,10358,10359,10360,4189,10361,10362, //10208 10363,10364,10365,10366,10367,10368,10369,10370,10371,10372,10373,10374,10375,4932,10376,10377, //10224 10378,10379,10380,10381,10382,10383,10384,10385,10386,10387,10388,10389,10390,10391,10392,4933, //10240 10393,10394,10395,4934,10396,10397,10398,10399,10400,10401,10402,10403,10404,10405,10406,10407, //10256 10408,10409,10410,10411,10412,3446,10413,10414,10415,10416,10417,10418,10419,10420,10421,10422, //10272 10423,4935,10424,10425,10426,10427,10428,10429,10430,4936,10431,10432,10433,10434,10435,10436, //10288 10437,10438,10439,10440,10441,10442,10443,4937,10444,10445,10446,10447,4481,10448,10449,10450, //10304 10451,10452,10453,10454,10455,10456,10457,10458,10459,10460,10461,10462,10463,10464,10465,10466, //10320 10467,10468,10469,10470,10471,10472,10473,10474,10475,10476,10477,10478,10479,10480,10481,10482, //10336 10483,10484,10485,10486,10487,10488,10489,10490,10491,10492,10493,10494,10495,10496,10497,10498, //10352 10499,10500,10501,10502,10503,10504,10505,4938,10506,10507,10508,10509,10510,2552,10511,10512, //10368 10513,10514,10515,10516,3447,10517,10518,10519,10520,10521,10522,10523,10524,10525,10526,10527, //10384 10528,10529,10530,10531,10532,10533,10534,10535,10536,10537,10538,10539,10540,10541,10542,10543, //10400 4482,10544,4939,10545,10546,10547,10548,10549,10550,10551,10552,10553,10554,10555,10556,10557, //10416 10558,10559,10560,10561,10562,10563,10564,10565,10566,10567,3676,4483,10568,10569,10570,10571, //10432 10572,3448,10573,10574,10575,10576,10577,10578,10579,10580,10581,10582,10583,10584,10585,10586, //10448 10587,10588,10589,10590,10591,10592,10593,10594,10595,10596,10597,10598,10599,10600,10601,10602, //10464 10603,10604,10605,10606,10607,10608,10609,10610,10611,10612,10613,10614,10615,10616,10617,10618, //10480 10619,10620,10621,10622,10623,10624,10625,10626,10627,4484,10628,10629,10630,10631,10632,4940, //10496 10633,10634,10635,10636,10637,10638,10639,10640,10641,10642,10643,10644,10645,10646,10647,10648, //10512 10649,10650,10651,10652,10653,10654,10655,10656,4941,10657,10658,10659,2599,10660,10661,10662, //10528 10663,10664,10665,10666,3089,10667,10668,10669,10670,10671,10672,10673,10674,10675,10676,10677, //10544 10678,10679,10680,4942,10681,10682,10683,10684,10685,10686,10687,10688,10689,10690,10691,10692, //10560 10693,10694,10695,10696,10697,4485,10698,10699,10700,10701,10702,10703,10704,4943,10705,3677, //10576 10706,10707,10708,10709,10710,10711,10712,4944,10713,10714,10715,10716,10717,10718,10719,10720, //10592 10721,10722,10723,10724,10725,10726,10727,10728,4945,10729,10730,10731,10732,10733,10734,10735, //10608 10736,10737,10738,10739,10740,10741,10742,10743,10744,10745,10746,10747,10748,10749,10750,10751, //10624 10752,10753,10754,10755,10756,10757,10758,10759,10760,10761,4946,10762,10763,10764,10765,10766, //10640 10767,4947,4948,10768,10769,10770,10771,10772,10773,10774,10775,10776,10777,10778,10779,10780, //10656 10781,10782,10783,10784,10785,10786,10787,10788,10789,10790,10791,10792,10793,10794,10795,10796, //10672 10797,10798,10799,10800,10801,10802,10803,10804,10805,10806,10807,10808,10809,10810,10811,10812, //10688 10813,10814,10815,10816,10817,10818,10819,10820,10821,10822,10823,10824,10825,10826,10827,10828, //10704 10829,10830,10831,10832,10833,10834,10835,10836,10837,10838,10839,10840,10841,10842,10843,10844, //10720 10845,10846,10847,10848,10849,10850,10851,10852,10853,10854,10855,10856,10857,10858,10859,10860, //10736 10861,10862,10863,10864,10865,10866,10867,10868,10869,10870,10871,10872,10873,10874,10875,10876, //10752 10877,10878,4486,10879,10880,10881,10882,10883,10884,10885,4949,10886,10887,10888,10889,10890, //10768 10891,10892,10893,10894,10895,10896,10897,10898,10899,10900,10901,10902,10903,10904,10905,10906, //10784 10907,10908,10909,10910,10911,10912,10913,10914,10915,10916,10917,10918,10919,4487,10920,10921, //10800 10922,10923,10924,10925,10926,10927,10928,10929,10930,10931,10932,4950,10933,10934,10935,10936, //10816 10937,10938,10939,10940,10941,10942,10943,10944,10945,10946,10947,10948,10949,4488,10950,10951, //10832 10952,10953,10954,10955,10956,10957,10958,10959,4190,10960,10961,10962,10963,10964,10965,10966, //10848 10967,10968,10969,10970,10971,10972,10973,10974,10975,10976,10977,10978,10979,10980,10981,10982, //10864 10983,10984,10985,10986,10987,10988,10989,10990,10991,10992,10993,10994,10995,10996,10997,10998, //10880 10999,11000,11001,11002,11003,11004,11005,11006,3960,11007,11008,11009,11010,11011,11012,11013, //10896 11014,11015,11016,11017,11018,11019,11020,11021,11022,11023,11024,11025,11026,11027,11028,11029, //10912 11030,11031,11032,4951,11033,11034,11035,11036,11037,11038,11039,11040,11041,11042,11043,11044, //10928 11045,11046,11047,4489,11048,11049,11050,11051,4952,11052,11053,11054,11055,11056,11057,11058, //10944 4953,11059,11060,11061,11062,11063,11064,11065,11066,11067,11068,11069,11070,11071,4954,11072, //10960 11073,11074,11075,11076,11077,11078,11079,11080,11081,11082,11083,11084,11085,11086,11087,11088, //10976 11089,11090,11091,11092,11093,11094,11095,11096,11097,11098,11099,11100,11101,11102,11103,11104, //10992 11105,11106,11107,11108,11109,11110,11111,11112,11113,11114,11115,3808,11116,11117,11118,11119, //11008 11120,11121,11122,11123,11124,11125,11126,11127,11128,11129,11130,11131,11132,11133,11134,4955, //11024 11135,11136,11137,11138,11139,11140,11141,11142,11143,11144,11145,11146,11147,11148,11149,11150, //11040 11151,11152,11153,11154,11155,11156,11157,11158,11159,11160,11161,4956,11162,11163,11164,11165, //11056 11166,11167,11168,11169,11170,11171,11172,11173,11174,11175,11176,11177,11178,11179,11180,4957, //11072 11181,11182,11183,11184,11185,11186,4958,11187,11188,11189,11190,11191,11192,11193,11194,11195, //11088 11196,11197,11198,11199,11200,3678,11201,11202,11203,11204,11205,11206,4191,11207,11208,11209, //11104 11210,11211,11212,11213,11214,11215,11216,11217,11218,11219,11220,11221,11222,11223,11224,11225, //11120 11226,11227,11228,11229,11230,11231,11232,11233,11234,11235,11236,11237,11238,11239,11240,11241, //11136 11242,11243,11244,11245,11246,11247,11248,11249,11250,11251,4959,11252,11253,11254,11255,11256, //11152 11257,11258,11259,11260,11261,11262,11263,11264,11265,11266,11267,11268,11269,11270,11271,11272, //11168 11273,11274,11275,11276,11277,11278,11279,11280,11281,11282,11283,11284,11285,11286,11287,11288, //11184 11289,11290,11291,11292,11293,11294,11295,11296,11297,11298,11299,11300,11301,11302,11303,11304, //11200 11305,11306,11307,11308,11309,11310,11311,11312,11313,11314,3679,11315,11316,11317,11318,4490, //11216 11319,11320,11321,11322,11323,11324,11325,11326,11327,11328,11329,11330,11331,11332,11333,11334, //11232 11335,11336,11337,11338,11339,11340,11341,11342,11343,11344,11345,11346,11347,4960,11348,11349, //11248 11350,11351,11352,11353,11354,11355,11356,11357,11358,11359,11360,11361,11362,11363,11364,11365, //11264 11366,11367,11368,11369,11370,11371,11372,11373,11374,11375,11376,11377,3961,4961,11378,11379, //11280 11380,11381,11382,11383,11384,11385,11386,11387,11388,11389,11390,11391,11392,11393,11394,11395, //11296 11396,11397,4192,11398,11399,11400,11401,11402,11403,11404,11405,11406,11407,11408,11409,11410, //11312 11411,4962,11412,11413,11414,11415,11416,11417,11418,11419,11420,11421,11422,11423,11424,11425, //11328 11426,11427,11428,11429,11430,11431,11432,11433,11434,11435,11436,11437,11438,11439,11440,11441, //11344 11442,11443,11444,11445,11446,11447,11448,11449,11450,11451,11452,11453,11454,11455,11456,11457, //11360 11458,11459,11460,11461,11462,11463,11464,11465,11466,11467,11468,11469,4963,11470,11471,4491, //11376 11472,11473,11474,11475,4964,11476,11477,11478,11479,11480,11481,11482,11483,11484,11485,11486, //11392 11487,11488,11489,11490,11491,11492,4965,11493,11494,11495,11496,11497,11498,11499,11500,11501, //11408 11502,11503,11504,11505,11506,11507,11508,11509,11510,11511,11512,11513,11514,11515,11516,11517, //11424 11518,11519,11520,11521,11522,11523,11524,11525,11526,11527,11528,11529,3962,11530,11531,11532, //11440 11533,11534,11535,11536,11537,11538,11539,11540,11541,11542,11543,11544,11545,11546,11547,11548, //11456 11549,11550,11551,11552,11553,11554,11555,11556,11557,11558,11559,11560,11561,11562,11563,11564, //11472 4193,4194,11565,11566,11567,11568,11569,11570,11571,11572,11573,11574,11575,11576,11577,11578, //11488 11579,11580,11581,11582,11583,11584,11585,11586,11587,11588,11589,11590,11591,4966,4195,11592, //11504 11593,11594,11595,11596,11597,11598,11599,11600,11601,11602,11603,11604,3090,11605,11606,11607, //11520 11608,11609,11610,4967,11611,11612,11613,11614,11615,11616,11617,11618,11619,11620,11621,11622, //11536 11623,11624,11625,11626,11627,11628,11629,11630,11631,11632,11633,11634,11635,11636,11637,11638, //11552 11639,11640,11641,11642,11643,11644,11645,11646,11647,11648,11649,11650,11651,11652,11653,11654, //11568 11655,11656,11657,11658,11659,11660,11661,11662,11663,11664,11665,11666,11667,11668,11669,11670, //11584 11671,11672,11673,11674,4968,11675,11676,11677,11678,11679,11680,11681,11682,11683,11684,11685, //11600 11686,11687,11688,11689,11690,11691,11692,11693,3809,11694,11695,11696,11697,11698,11699,11700, //11616 11701,11702,11703,11704,11705,11706,11707,11708,11709,11710,11711,11712,11713,11714,11715,11716, //11632 11717,11718,3553,11719,11720,11721,11722,11723,11724,11725,11726,11727,11728,11729,11730,4969, //11648 11731,11732,11733,11734,11735,11736,11737,11738,11739,11740,4492,11741,11742,11743,11744,11745, //11664 11746,11747,11748,11749,11750,11751,11752,4970,11753,11754,11755,11756,11757,11758,11759,11760, //11680 11761,11762,11763,11764,11765,11766,11767,11768,11769,11770,11771,11772,11773,11774,11775,11776, //11696 11777,11778,11779,11780,11781,11782,11783,11784,11785,11786,11787,11788,11789,11790,4971,11791, //11712 11792,11793,11794,11795,11796,11797,4972,11798,11799,11800,11801,11802,11803,11804,11805,11806, //11728 11807,11808,11809,11810,4973,11811,11812,11813,11814,11815,11816,11817,11818,11819,11820,11821, //11744 11822,11823,11824,11825,11826,11827,11828,11829,11830,11831,11832,11833,11834,3680,3810,11835, //11760 11836,4974,11837,11838,11839,11840,11841,11842,11843,11844,11845,11846,11847,11848,11849,11850, //11776 11851,11852,11853,11854,11855,11856,11857,11858,11859,11860,11861,11862,11863,11864,11865,11866, //11792 11867,11868,11869,11870,11871,11872,11873,11874,11875,11876,11877,11878,11879,11880,11881,11882, //11808 11883,11884,4493,11885,11886,11887,11888,11889,11890,11891,11892,11893,11894,11895,11896,11897, //11824 11898,11899,11900,11901,11902,11903,11904,11905,11906,11907,11908,11909,11910,11911,11912,11913, //11840 11914,11915,4975,11916,11917,11918,11919,11920,11921,11922,11923,11924,11925,11926,11927,11928, //11856 11929,11930,11931,11932,11933,11934,11935,11936,11937,11938,11939,11940,11941,11942,11943,11944, //11872 11945,11946,11947,11948,11949,4976,11950,11951,11952,11953,11954,11955,11956,11957,11958,11959, //11888 11960,11961,11962,11963,11964,11965,11966,11967,11968,11969,11970,11971,11972,11973,11974,11975, //11904 11976,11977,11978,11979,11980,11981,11982,11983,11984,11985,11986,11987,4196,11988,11989,11990, //11920 11991,11992,4977,11993,11994,11995,11996,11997,11998,11999,12000,12001,12002,12003,12004,12005, //11936 12006,12007,12008,12009,12010,12011,12012,12013,12014,12015,12016,12017,12018,12019,12020,12021, //11952 12022,12023,12024,12025,12026,12027,12028,12029,12030,12031,12032,12033,12034,12035,12036,12037, //11968 12038,12039,12040,12041,12042,12043,12044,12045,12046,12047,12048,12049,12050,12051,12052,12053, //11984 12054,12055,12056,12057,12058,12059,12060,12061,4978,12062,12063,12064,12065,12066,12067,12068, //12000 12069,12070,12071,12072,12073,12074,12075,12076,12077,12078,12079,12080,12081,12082,12083,12084, //12016 12085,12086,12087,12088,12089,12090,12091,12092,12093,12094,12095,12096,12097,12098,12099,12100, //12032 12101,12102,12103,12104,12105,12106,12107,12108,12109,12110,12111,12112,12113,12114,12115,12116, //12048 12117,12118,12119,12120,12121,12122,12123,4979,12124,12125,12126,12127,12128,4197,12129,12130, //12064 12131,12132,12133,12134,12135,12136,12137,12138,12139,12140,12141,12142,12143,12144,12145,12146, //12080 12147,12148,12149,12150,12151,12152,12153,12154,4980,12155,12156,12157,12158,12159,12160,4494, //12096 12161,12162,12163,12164,3811,12165,12166,12167,12168,12169,4495,12170,12171,4496,12172,12173, //12112 12174,12175,12176,3812,12177,12178,12179,12180,12181,12182,12183,12184,12185,12186,12187,12188, //12128 12189,12190,12191,12192,12193,12194,12195,12196,12197,12198,12199,12200,12201,12202,12203,12204, //12144 12205,12206,12207,12208,12209,12210,12211,12212,12213,12214,12215,12216,12217,12218,12219,12220, //12160 12221,4981,12222,12223,12224,12225,12226,12227,12228,12229,12230,12231,12232,12233,12234,12235, //12176 4982,12236,12237,12238,12239,12240,12241,12242,12243,12244,12245,4983,12246,12247,12248,12249, //12192 4984,12250,12251,12252,12253,12254,12255,12256,12257,12258,12259,12260,12261,12262,12263,12264, //12208 4985,12265,4497,12266,12267,12268,12269,12270,12271,12272,12273,12274,12275,12276,12277,12278, //12224 12279,12280,12281,12282,12283,12284,12285,12286,12287,4986,12288,12289,12290,12291,12292,12293, //12240 12294,12295,12296,2473,12297,12298,12299,12300,12301,12302,12303,12304,12305,12306,12307,12308, //12256 12309,12310,12311,12312,12313,12314,12315,12316,12317,12318,12319,3963,12320,12321,12322,12323, //12272 12324,12325,12326,12327,12328,12329,12330,12331,12332,4987,12333,12334,12335,12336,12337,12338, //12288 12339,12340,12341,12342,12343,12344,12345,12346,12347,12348,12349,12350,12351,12352,12353,12354, //12304 12355,12356,12357,12358,12359,3964,12360,12361,12362,12363,12364,12365,12366,12367,12368,12369, //12320 12370,3965,12371,12372,12373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384, //12336 12385,12386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,12399,12400, //12352 12401,12402,12403,12404,12405,12406,12407,12408,4988,12409,12410,12411,12412,12413,12414,12415, //12368 12416,12417,12418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431, //12384 12432,12433,12434,12435,12436,12437,12438,3554,12439,12440,12441,12442,12443,12444,12445,12446, //12400 12447,12448,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462, //12416 12463,12464,4989,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477, //12432 12478,12479,12480,4990,12481,12482,12483,12484,12485,12486,12487,12488,12489,4498,12490,12491, //12448 12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507, //12464 12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523, //12480 12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,12535,12536,12537,12538,12539, //12496 12540,12541,12542,12543,12544,12545,12546,12547,12548,12549,12550,12551,4991,12552,12553,12554, //12512 12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,12570, //12528 12571,12572,12573,12574,12575,12576,12577,12578,3036,12579,12580,12581,12582,12583,3966,12584, //12544 12585,12586,12587,12588,12589,12590,12591,12592,12593,12594,12595,12596,12597,12598,12599,12600, //12560 12601,12602,12603,12604,12605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616, //12576 12617,12618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,12631,12632, //12592 12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,12644,12645,12646,4499,12647, //12608 12648,12649,12650,12651,12652,12653,12654,12655,12656,12657,12658,12659,12660,12661,12662,12663, //12624 12664,12665,12666,12667,12668,12669,12670,12671,12672,12673,12674,12675,12676,12677,12678,12679, //12640 12680,12681,12682,12683,12684,12685,12686,12687,12688,12689,12690,12691,12692,12693,12694,12695, //12656 12696,12697,12698,4992,12699,12700,12701,12702,12703,12704,12705,12706,12707,12708,12709,12710, //12672 12711,12712,12713,12714,12715,12716,12717,12718,12719,12720,12721,12722,12723,12724,12725,12726, //12688 12727,12728,12729,12730,12731,12732,12733,12734,12735,12736,12737,12738,12739,12740,12741,12742, //12704 12743,12744,12745,12746,12747,12748,12749,12750,12751,12752,12753,12754,12755,12756,12757,12758, //12720 12759,12760,12761,12762,12763,12764,12765,12766,12767,12768,12769,12770,12771,12772,12773,12774, //12736 12775,12776,12777,12778,4993,2175,12779,12780,12781,12782,12783,12784,12785,12786,4500,12787, //12752 12788,12789,12790,12791,12792,12793,12794,12795,12796,12797,12798,12799,12800,12801,12802,12803, //12768 12804,12805,12806,12807,12808,12809,12810,12811,12812,12813,12814,12815,12816,12817,12818,12819, //12784 12820,12821,12822,12823,12824,12825,12826,4198,3967,12827,12828,12829,12830,12831,12832,12833, //12800 12834,12835,12836,12837,12838,12839,12840,12841,12842,12843,12844,12845,12846,12847,12848,12849, //12816 12850,12851,12852,12853,12854,12855,12856,12857,12858,12859,12860,12861,4199,12862,12863,12864, //12832 12865,12866,12867,12868,12869,12870,12871,12872,12873,12874,12875,12876,12877,12878,12879,12880, //12848 12881,12882,12883,12884,12885,12886,12887,4501,12888,12889,12890,12891,12892,12893,12894,12895, //12864 12896,12897,12898,12899,12900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911, //12880 12912,4994,12913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,12924,12925,12926, //12896 12927,12928,12929,12930,12931,12932,12933,12934,12935,12936,12937,12938,12939,12940,12941,12942, //12912 12943,12944,12945,12946,12947,12948,12949,12950,12951,12952,12953,12954,12955,12956,1772,12957, //12928 12958,12959,12960,12961,12962,12963,12964,12965,12966,12967,12968,12969,12970,12971,12972,12973, //12944 12974,12975,12976,12977,12978,12979,12980,12981,12982,12983,12984,12985,12986,12987,12988,12989, //12960 12990,12991,12992,12993,12994,12995,12996,12997,4502,12998,4503,12999,13000,13001,13002,13003, //12976 4504,13004,13005,13006,13007,13008,13009,13010,13011,13012,13013,13014,13015,13016,13017,13018, //12992 13019,13020,13021,13022,13023,13024,13025,13026,13027,13028,13029,3449,13030,13031,13032,13033, //13008 13034,13035,13036,13037,13038,13039,13040,13041,13042,13043,13044,13045,13046,13047,13048,13049, //13024 13050,13051,13052,13053,13054,13055,13056,13057,13058,13059,13060,13061,13062,13063,13064,13065, //13040 13066,13067,13068,13069,13070,13071,13072,13073,13074,13075,13076,13077,13078,13079,13080,13081, //13056 13082,13083,13084,13085,13086,13087,13088,13089,13090,13091,13092,13093,13094,13095,13096,13097, //13072 13098,13099,13100,13101,13102,13103,13104,13105,13106,13107,13108,13109,13110,13111,13112,13113, //13088 13114,13115,13116,13117,13118,3968,13119,4995,13120,13121,13122,13123,13124,13125,13126,13127, //13104 4505,13128,13129,13130,13131,13132,13133,13134,4996,4506,13135,13136,13137,13138,13139,4997, //13120 13140,13141,13142,13143,13144,13145,13146,13147,13148,13149,13150,13151,13152,13153,13154,13155, //13136 13156,13157,13158,13159,4998,13160,13161,13162,13163,13164,13165,13166,13167,13168,13169,13170, //13152 13171,13172,13173,13174,13175,13176,4999,13177,13178,13179,13180,13181,13182,13183,13184,13185, //13168 13186,13187,13188,13189,13190,13191,13192,13193,13194,13195,13196,13197,13198,13199,13200,13201, //13184 13202,13203,13204,13205,13206,5000,13207,13208,13209,13210,13211,13212,13213,13214,13215,13216, //13200 13217,13218,13219,13220,13221,13222,13223,13224,13225,13226,13227,4200,5001,13228,13229,13230, //13216 13231,13232,13233,13234,13235,13236,13237,13238,13239,13240,3969,13241,13242,13243,13244,3970, //13232 13245,13246,13247,13248,13249,13250,13251,13252,13253,13254,13255,13256,13257,13258,13259,13260, //13248 13261,13262,13263,13264,13265,13266,13267,13268,3450,13269,13270,13271,13272,13273,13274,13275, //13264 13276,5002,13277,13278,13279,13280,13281,13282,13283,13284,13285,13286,13287,13288,13289,13290, //13280 13291,13292,13293,13294,13295,13296,13297,13298,13299,13300,13301,13302,3813,13303,13304,13305, //13296 13306,13307,13308,13309,13310,13311,13312,13313,13314,13315,13316,13317,13318,13319,13320,13321, //13312 13322,13323,13324,13325,13326,13327,13328,4507,13329,13330,13331,13332,13333,13334,13335,13336, //13328 13337,13338,13339,13340,13341,5003,13342,13343,13344,13345,13346,13347,13348,13349,13350,13351, //13344 13352,13353,13354,13355,13356,13357,13358,13359,13360,13361,13362,13363,13364,13365,13366,13367, //13360 5004,13368,13369,13370,13371,13372,13373,13374,13375,13376,13377,13378,13379,13380,13381,13382, //13376 13383,13384,13385,13386,13387,13388,13389,13390,13391,13392,13393,13394,13395,13396,13397,13398, //13392 13399,13400,13401,13402,13403,13404,13405,13406,13407,13408,13409,13410,13411,13412,13413,13414, //13408 13415,13416,13417,13418,13419,13420,13421,13422,13423,13424,13425,13426,13427,13428,13429,13430, //13424 13431,13432,4508,13433,13434,13435,4201,13436,13437,13438,13439,13440,13441,13442,13443,13444, //13440 13445,13446,13447,13448,13449,13450,13451,13452,13453,13454,13455,13456,13457,5005,13458,13459, //13456 13460,13461,13462,13463,13464,13465,13466,13467,13468,13469,13470,4509,13471,13472,13473,13474, //13472 13475,13476,13477,13478,13479,13480,13481,13482,13483,13484,13485,13486,13487,13488,13489,13490, //13488 13491,13492,13493,13494,13495,13496,13497,13498,13499,13500,13501,13502,13503,13504,13505,13506, //13504 13507,13508,13509,13510,13511,13512,13513,13514,13515,13516,13517,13518,13519,13520,13521,13522, //13520 13523,13524,13525,13526,13527,13528,13529,13530,13531,13532,13533,13534,13535,13536,13537,13538, //13536 13539,13540,13541,13542,13543,13544,13545,13546,13547,13548,13549,13550,13551,13552,13553,13554, //13552 13555,13556,13557,13558,13559,13560,13561,13562,13563,13564,13565,13566,13567,13568,13569,13570, //13568 13571,13572,13573,13574,13575,13576,13577,13578,13579,13580,13581,13582,13583,13584,13585,13586, //13584 13587,13588,13589,13590,13591,13592,13593,13594,13595,13596,13597,13598,13599,13600,13601,13602, //13600 13603,13604,13605,13606,13607,13608,13609,13610,13611,13612,13613,13614,13615,13616,13617,13618, //13616 13619,13620,13621,13622,13623,13624,13625,13626,13627,13628,13629,13630,13631,13632,13633,13634, //13632 13635,13636,13637,13638,13639,13640,13641,13642,5006,13643,13644,13645,13646,13647,13648,13649, //13648 13650,13651,5007,13652,13653,13654,13655,13656,13657,13658,13659,13660,13661,13662,13663,13664, //13664 13665,13666,13667,13668,13669,13670,13671,13672,13673,13674,13675,13676,13677,13678,13679,13680, //13680 13681,13682,13683,13684,13685,13686,13687,13688,13689,13690,13691,13692,13693,13694,13695,13696, //13696 13697,13698,13699,13700,13701,13702,13703,13704,13705,13706,13707,13708,13709,13710,13711,13712, //13712 13713,13714,13715,13716,13717,13718,13719,13720,13721,13722,13723,13724,13725,13726,13727,13728, //13728 13729,13730,13731,13732,13733,13734,13735,13736,13737,13738,13739,13740,13741,13742,13743,13744, //13744 13745,13746,13747,13748,13749,13750,13751,13752,13753,13754,13755,13756,13757,13758,13759,13760, //13760 13761,13762,13763,13764,13765,13766,13767,13768,13769,13770,13771,13772,13773,13774,3273,13775, //13776 13776,13777,13778,13779,13780,13781,13782,13783,13784,13785,13786,13787,13788,13789,13790,13791, //13792 13792,13793,13794,13795,13796,13797,13798,13799,13800,13801,13802,13803,13804,13805,13806,13807, //13808 13808,13809,13810,13811,13812,13813,13814,13815,13816,13817,13818,13819,13820,13821,13822,13823, //13824 13824,13825,13826,13827,13828,13829,13830,13831,13832,13833,13834,13835,13836,13837,13838,13839, //13840 13840,13841,13842,13843,13844,13845,13846,13847,13848,13849,13850,13851,13852,13853,13854,13855, //13856 13856,13857,13858,13859,13860,13861,13862,13863,13864,13865,13866,13867,13868,13869,13870,13871, //13872 13872,13873,13874,13875,13876,13877,13878,13879,13880,13881,13882,13883,13884,13885,13886,13887, //13888 13888,13889,13890,13891,13892,13893,13894,13895,13896,13897,13898,13899,13900,13901,13902,13903, //13904 13904,13905,13906,13907,13908,13909,13910,13911,13912,13913,13914,13915,13916,13917,13918,13919, //13920 13920,13921,13922,13923,13924,13925,13926,13927,13928,13929,13930,13931,13932,13933,13934,13935, //13936 13936,13937,13938,13939,13940,13941,13942,13943,13944,13945,13946,13947,13948,13949,13950,13951, //13952 13952,13953,13954,13955,13956,13957,13958,13959,13960,13961,13962,13963,13964,13965,13966,13967, //13968 13968,13969,13970,13971,13972, //13973 ****************************************************************************************/ }; diff --git a/src/probers/tables/EUCKRFreq.tab b/src/probers/tables/EUCKRFreq.tab index aac5677..a54145b 100644 --- a/src/probers/tables/EUCKRFreq.tab +++ b/src/probers/tables/EUCKRFreq.tab @@ -1,602 +1,584 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 + + SPDX-License-Identifier: MIT */ //Sampling from about 20M text materials include literature and computer technology /****************************************************************************** * 128 --> 0.79 * 256 --> 0.92 * 512 --> 0.986 * 1024 --> 0.99944 * 2048 --> 0.99999 * * Idea Distribution Ratio = 0.98653 / (1-0.98653) = 73.24 * Random Distribution Ration = 512 / (2350-512) = 0.279. - * - * Typical Distribution Ratio + * + * Typical Distribution Ratio *****************************************************************************/ #define EUCKR_TYPICAL_DISTRIBUTION_RATIO (float) 6.0 #define EUCKR_TABLE_SIZE 2352 -//Char to FreqOrder table , +//Char to FreqOrder table , static const short EUCKRCharToFreqOrder[] = { 13, 130, 120,1396, 481,1719,1720, 328, 609, 212,1721, 707, 400, 299,1722, 87, 1397,1723, 104, 536,1117,1203,1724,1267, 685,1268, 508,1725,1726,1727,1728,1398, 1399,1729,1730,1731, 141, 621, 326,1057, 368,1732, 267, 488, 20,1733,1269,1734, 945,1400,1735, 47, 904,1270,1736,1737, 773, 248,1738, 409, 313, 786, 429,1739, 116, 987, 813,1401, 683, 75,1204, 145,1740,1741,1742,1743, 16, 847, 667, 622, 708,1744,1745,1746, 966, 787, 304, 129,1747, 60, 820, 123, 676,1748,1749,1750, 1751, 617,1752, 626,1753,1754,1755,1756, 653,1757,1758,1759,1760,1761,1762, 856, 344,1763,1764,1765,1766, 89, 401, 418, 806, 905, 848,1767,1768,1769, 946,1205, 709,1770,1118,1771, 241,1772,1773,1774,1271,1775, 569,1776, 999,1777,1778,1779, 1780, 337, 751,1058, 28, 628, 254,1781, 177, 906, 270, 349, 891,1079,1782, 19, 1783, 379,1784, 315,1785, 629, 754,1402, 559,1786, 636, 203,1206,1787, 710, 567, 1788, 935, 814,1789,1790,1207, 766, 528,1791,1792,1208,1793,1794,1795,1796,1797, 1403,1798,1799, 533,1059,1404,1405,1156,1406, 936, 884,1080,1800, 351,1801,1802, 1803,1804,1805, 801,1806,1807,1808,1119,1809,1157, 714, 474,1407,1810, 298, 899, 885,1811,1120, 802,1158,1812, 892,1813,1814,1408, 659,1815,1816,1121,1817,1818, 1819,1820,1821,1822, 319,1823, 594, 545,1824, 815, 937,1209,1825,1826, 573,1409, 1022,1827,1210,1828,1829,1830,1831,1832,1833, 556, 722, 807,1122,1060,1834, 697, 1835, 900, 557, 715,1836,1410, 540,1411, 752,1159, 294, 597,1211, 976, 803, 770, 1412,1837,1838, 39, 794,1413, 358,1839, 371, 925,1840, 453, 661, 788, 531, 723, 544,1023,1081, 869, 91,1841, 392, 430, 790, 602,1414, 677,1082, 457,1415,1416, 1842,1843, 475, 327,1024,1417, 795, 121,1844, 733, 403,1418,1845,1846,1847, 300, 119, 711,1212, 627,1848,1272, 207,1849,1850, 796,1213, 382,1851, 519,1852,1083, 893,1853,1854,1855, 367, 809, 487, 671,1856, 663,1857,1858, 956, 471, 306, 857, 1859,1860,1160,1084,1861,1862,1863,1864,1865,1061,1866,1867,1868,1869,1870,1871, 282, 96, 574,1872, 502,1085,1873,1214,1874, 907,1875,1876, 827, 977,1419,1420, 1421, 268,1877,1422,1878,1879,1880, 308,1881, 2, 537,1882,1883,1215,1884,1885, 127, 791,1886,1273,1423,1887, 34, 336, 404, 643,1888, 571, 654, 894, 840,1889, 0, 886,1274, 122, 575, 260, 908, 938,1890,1275, 410, 316,1891,1892, 100,1893, 1894,1123, 48,1161,1124,1025,1895, 633, 901,1276,1896,1897, 115, 816,1898, 317, 1899, 694,1900, 909, 734,1424, 572, 866,1425, 691, 85, 524,1010, 543, 394, 841, 1901,1902,1903,1026,1904,1905,1906,1907,1908,1909, 30, 451, 651, 988, 310,1910, 1911,1426, 810,1216, 93,1912,1913,1277,1217,1914, 858, 759, 45, 58, 181, 610, 269,1915,1916, 131,1062, 551, 443,1000, 821,1427, 957, 895,1086,1917,1918, 375, 1919, 359,1920, 687,1921, 822,1922, 293,1923,1924, 40, 662, 118, 692, 29, 939, 887, 640, 482, 174,1925, 69,1162, 728,1428, 910,1926,1278,1218,1279, 386, 870, 217, 854,1163, 823,1927,1928,1929,1930, 834,1931, 78,1932, 859,1933,1063,1934, 1935,1936,1937, 438,1164, 208, 595,1938,1939,1940,1941,1219,1125,1942, 280, 888, 1429,1430,1220,1431,1943,1944,1945,1946,1947,1280, 150, 510,1432,1948,1949,1950, 1951,1952,1953,1954,1011,1087,1955,1433,1043,1956, 881,1957, 614, 958,1064,1065, 1221,1958, 638,1001, 860, 967, 896,1434, 989, 492, 553,1281,1165,1959,1282,1002, 1283,1222,1960,1961,1962,1963, 36, 383, 228, 753, 247, 454,1964, 876, 678,1965, 1966,1284, 126, 464, 490, 835, 136, 672, 529, 940,1088,1435, 473,1967,1968, 467, 50, 390, 227, 587, 279, 378, 598, 792, 968, 240, 151, 160, 849, 882,1126,1285, 639,1044, 133, 140, 288, 360, 811, 563,1027, 561, 142, 523,1969,1970,1971, 7, 103, 296, 439, 407, 506, 634, 990,1972,1973,1974,1975, 645,1976,1977,1978,1979, 1980,1981, 236,1982,1436,1983,1984,1089, 192, 828, 618, 518,1166, 333,1127,1985, 818,1223,1986,1987,1988,1989,1990,1991,1992,1993, 342,1128,1286, 746, 842,1994, 1995, 560, 223,1287, 98, 8, 189, 650, 978,1288,1996,1437,1997, 17, 345, 250, 423, 277, 234, 512, 226, 97, 289, 42, 167,1998, 201,1999,2000, 843, 836, 824, 532, 338, 783,1090, 182, 576, 436,1438,1439, 527, 500,2001, 947, 889,2002,2003, 2004,2005, 262, 600, 314, 447,2006, 547,2007, 693, 738,1129,2008, 71,1440, 745, 619, 688,2009, 829,2010,2011, 147,2012, 33, 948,2013,2014, 74, 224,2015, 61, 191, 918, 399, 637,2016,1028,1130, 257, 902,2017,2018,2019,2020,2021,2022,2023, 2024,2025,2026, 837,2027,2028,2029,2030, 179, 874, 591, 52, 724, 246,2031,2032, 2033,2034,1167, 969,2035,1289, 630, 605, 911,1091,1168,2036,2037,2038,1441, 912, 2039, 623,2040,2041, 253,1169,1290,2042,1442, 146, 620, 611, 577, 433,2043,1224, 719,1170, 959, 440, 437, 534, 84, 388, 480,1131, 159, 220, 198, 679,2044,1012, 819,1066,1443, 113,1225, 194, 318,1003,1029,2045,2046,2047,2048,1067,2049,2050, 2051,2052,2053, 59, 913, 112,2054, 632,2055, 455, 144, 739,1291,2056, 273, 681, 499,2057, 448,2058,2059, 760,2060,2061, 970, 384, 169, 245,1132,2062,2063, 414, 1444,2064,2065, 41, 235,2066, 157, 252, 877, 568, 919, 789, 580,2067, 725,2068, 2069,1292,2070,2071,1445,2072,1446,2073,2074, 55, 588, 66,1447, 271,1092,2075, 1226,2076, 960,1013, 372,2077,2078,2079,2080,2081,1293,2082,2083,2084,2085, 850, 2086,2087,2088,2089,2090, 186,2091,1068, 180,2092,2093,2094, 109,1227, 522, 606, 2095, 867,1448,1093, 991,1171, 926, 353,1133,2096, 581,2097,2098,2099,1294,1449, 1450,2100, 596,1172,1014,1228,2101,1451,1295,1173,1229,2102,2103,1296,1134,1452, 949,1135,2104,2105,1094,1453,1454,1455,2106,1095,2107,2108,2109,2110,2111,2112, 2113,2114,2115,2116,2117, 804,2118,2119,1230,1231, 805,1456, 405,1136,2120,2121, 2122,2123,2124, 720, 701,1297, 992,1457, 927,1004,2125,2126,2127,2128,2129,2130, 22, 417,2131, 303,2132, 385,2133, 971, 520, 513,2134,1174, 73,1096, 231, 274, 962,1458, 673,2135,1459,2136, 152,1137,2137,2138,2139,2140,1005,1138,1460,1139, 2141,2142,2143,2144, 11, 374, 844,2145, 154,1232, 46,1461,2146, 838, 830, 721, 1233, 106,2147, 90, 428, 462, 578, 566,1175, 352,2148,2149, 538,1234, 124,1298, 2150,1462, 761, 565,2151, 686,2152, 649,2153, 72, 173,2154, 460, 415,2155,1463, 2156,1235, 305,2157,2158,2159,2160,2161,2162, 579,2163,2164,2165,2166,2167, 747, 2168,2169,2170,2171,1464, 669,2172,2173,2174,2175,2176,1465,2177, 23, 530, 285, 2178, 335, 729,2179, 397,2180,2181,2182,1030,2183,2184, 698,2185,2186, 325,2187, 2188, 369,2189, 799,1097,1015, 348,2190,1069, 680,2191, 851,1466,2192,2193, 10, 2194, 613, 424,2195, 979, 108, 449, 589, 27, 172, 81,1031, 80, 774, 281, 350, 1032, 525, 301, 582,1176,2196, 674,1045,2197,2198,1467, 730, 762,2199,2200,2201, 2202,1468,2203, 993,2204,2205, 266,1070, 963,1140,2206,2207,2208, 664,1098, 972, 2209,2210,2211,1177,1469,1470, 871,2212,2213,2214,2215,2216,1471,2217,2218,2219, 2220,2221,2222,2223,2224,2225,2226,2227,1472,1236,2228,2229,2230,2231,2232,2233, 2234,2235,1299,2236,2237, 200,2238, 477, 373,2239,2240, 731, 825, 777,2241,2242, 2243, 521, 486, 548,2244,2245,2246,1473,1300, 53, 549, 137, 875, 76, 158,2247, 1301,1474, 469, 396,1016, 278, 712,2248, 321, 442, 503, 767, 744, 941,1237,1178, 1475,2249, 82, 178,1141,1179, 973,2250,1302,2251, 297,2252,2253, 570,2254,2255, 2256, 18, 450, 206,2257, 290, 292,1142,2258, 511, 162, 99, 346, 164, 735,2259, 1476,1477, 4, 554, 343, 798,1099,2260,1100,2261, 43, 171,1303, 139, 215,2262, 2263, 717, 775,2264,1033, 322, 216,2265, 831,2266, 149,2267,1304,2268,2269, 702, 1238, 135, 845, 347, 309,2270, 484,2271, 878, 655, 238,1006,1478,2272, 67,2273, 295,2274,2275, 461,2276, 478, 942, 412,2277,1034,2278,2279,2280, 265,2281, 541, 2282,2283,2284,2285,2286, 70, 852,1071,2287,2288,2289,2290, 21, 56, 509, 117, 432,2291,2292, 331, 980, 552,1101, 148, 284, 105, 393,1180,1239, 755,2293, 187, 2294,1046,1479,2295, 340,2296, 63,1047, 230,2297,2298,1305, 763,1306, 101, 800, 808, 494,2299,2300,2301, 903,2302, 37,1072, 14, 5,2303, 79, 675,2304, 312, 2305,2306,2307,2308,2309,1480, 6,1307,2310,2311,2312, 1, 470, 35, 24, 229, 2313, 695, 210, 86, 778, 15, 784, 592, 779, 32, 77, 855, 964,2314, 259,2315, 501, 380,2316,2317, 83, 981, 153, 689,1308,1481,1482,1483,2318,2319, 716,1484, 2320,2321,2322,2323,2324,2325,1485,2326,2327, 128, 57, 68, 261,1048, 211, 170, 1240, 31,2328, 51, 435, 742,2329,2330,2331, 635,2332, 264, 456,2333,2334,2335, 425,2336,1486, 143, 507, 263, 943,2337, 363, 920,1487, 256,1488,1102, 243, 601, 1489,2338,2339,2340,2341,2342,2343,2344, 861,2345,2346,2347,2348,2349,2350, 395, 2351,1490,1491, 62, 535, 166, 225,2352,2353, 668, 419,1241, 138, 604, 928,2354, 1181,2355,1492,1493,2356,2357,2358,1143,2359, 696,2360, 387, 307,1309, 682, 476, 2361,2362, 332, 12, 222, 156,2363, 232,2364, 641, 276, 656, 517,1494,1495,1035, 416, 736,1496,2365,1017, 586,2366,2367,2368,1497,2369, 242,2370,2371,2372,1498, 2373, 965, 713,2374,2375,2376,2377, 740, 982,1499, 944,1500,1007,2378,2379,1310, 1501,2380,2381,2382, 785, 329,2383,2384,1502,2385,2386,2387, 932,2388,1503,2389, 2390,2391,2392,1242,2393,2394,2395,2396,2397, 994, 950,2398,2399,2400,2401,1504, 1311,2402,2403,2404,2405,1049, 749,2406,2407, 853, 718,1144,1312,2408,1182,1505, 2409,2410, 255, 516, 479, 564, 550, 214,1506,1507,1313, 413, 239, 444, 339,1145, 1036,1508,1509,1314,1037,1510,1315,2411,1511,2412,2413,2414, 176, 703, 497, 624, 593, 921, 302,2415, 341, 165,1103,1512,2416,1513,2417,2418,2419, 376,2420, 700, 2421,2422,2423, 258, 768,1316,2424,1183,2425, 995, 608,2426,2427,2428,2429, 221, 2430,2431,2432,2433,2434,2435,2436,2437, 195, 323, 726, 188, 897, 983,1317, 377, 644,1050, 879,2438, 452,2439,2440,2441,2442,2443,2444, 914,2445,2446,2447,2448, 915, 489,2449,1514,1184,2450,2451, 515, 64, 427, 495,2452, 583,2453, 483, 485, 1038, 562, 213,1515, 748, 666,2454,2455,2456,2457, 334,2458, 780, 996,1008, 705, 1243,2459,2460,2461,2462,2463, 114,2464, 493,1146, 366, 163,1516, 961,1104,2465, 291,2466,1318,1105,2467,1517, 365,2468, 355, 951,1244,2469,1319,2470, 631,2471, 2472, 218,1320, 364, 320, 756,1518,1519,1321,1520,1322,2473,2474,2475,2476, 997, 2477,2478,2479,2480, 665,1185,2481, 916,1521,2482,2483,2484, 584, 684,2485,2486, 797,2487,1051,1186,2488,2489,2490,1522,2491,2492, 370,2493,1039,1187, 65,2494, 434, 205, 463,1188,2495, 125, 812, 391, 402, 826, 699, 286, 398, 155, 781, 771, 585,2496, 590, 505,1073,2497, 599, 244, 219, 917,1018, 952, 646,1523,2498,1323, 2499,2500, 49, 984, 354, 741,2501, 625,2502,1324,2503,1019, 190, 357, 757, 491, 95, 782, 868,2504,2505,2506,2507,2508,2509, 134,1524,1074, 422,1525, 898,2510, 161,2511,2512,2513,2514, 769,2515,1526,2516,2517, 411,1325,2518, 472,1527,2519, 2520,2521,2522,2523,2524, 985,2525,2526,2527,2528,2529,2530, 764,2531,1245,2532, 2533, 25, 204, 311,2534, 496,2535,1052,2536,2537,2538,2539,2540,2541,2542, 199, 704, 504, 468, 758, 657,1528, 196, 44, 839,1246, 272, 750,2543, 765, 862,2544, 2545,1326,2546, 132, 615, 933,2547, 732,2548,2549,2550,1189,1529,2551, 283,1247, 1053, 607, 929,2552,2553,2554, 930, 183, 872, 616,1040,1147,2555,1148,1020, 441, 249,1075,2556,2557,2558, 466, 743,2559,2560,2561, 92, 514, 426, 420, 526,2562, 2563,2564,2565,2566,2567,2568, 185,2569,2570,2571,2572, 776,1530, 658,2573, 362, 2574, 361, 922,1076, 793,2575,2576,2577,2578,2579,2580,1531, 251,2581,2582,2583, 2584,1532, 54, 612, 237,1327,2585,2586, 275, 408, 647, 111,2587,1533,1106, 465, 3, 458, 9, 38,2588, 107, 110, 890, 209, 26, 737, 498,2589,1534,2590, 431, 202, 88,1535, 356, 287,1107, 660,1149,2591, 381,1536, 986,1150, 445,1248,1151, 974,2592,2593, 846,2594, 446, 953, 184,1249,1250, 727,2595, 923, 193, 883,2596, 2597,2598, 102, 324, 539, 817,2599, 421,1041,2600, 832,2601, 94, 175, 197, 406, 2602, 459,2603,2604,2605,2606,2607, 330, 555,2608,2609,2610, 706,1108, 389,2611, 2612,2613,2614, 233,2615, 833, 558, 931, 954,1251,2616,2617,1537, 546,2618,2619, 1009,2620,2621,2622,1538, 690,1328,2623, 955,2624,1539,2625,2626, 772,2627,2628, 2629,2630,2631, 924, 648, 863, 603,2632,2633, 934,1540, 864, 865,2634, 642,1042, 670,1190,2635,2636,2637,2638, 168,2639, 652, 873, 542,1054,1541,2640,2641,2642, //512, 256 -/*************************************************************************************** +/*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 2643,2644,2645,2646,2647,2648,2649,2650,2651,2652,2653,2654,2655,2656,2657,2658, 2659,2660,2661,2662,2663,2664,2665,2666,2667,2668,2669,2670,2671,2672,2673,2674, 2675,2676,2677,2678,2679,2680,2681,2682,2683,2684,2685,2686,2687,2688,2689,2690, 2691,2692,2693,2694,2695,2696,2697,2698,2699,1542, 880,2700,2701,2702,2703,2704, 2705,2706,2707,2708,2709,2710,2711,2712,2713,2714,2715,2716,2717,2718,2719,2720, 2721,2722,2723,2724,2725,1543,2726,2727,2728,2729,2730,2731,2732,1544,2733,2734, 2735,2736,2737,2738,2739,2740,2741,2742,2743,2744,2745,2746,2747,2748,2749,2750, 2751,2752,2753,2754,1545,2755,2756,2757,2758,2759,2760,2761,2762,2763,2764,2765, 2766,1546,2767,1547,2768,2769,2770,2771,2772,2773,2774,2775,2776,2777,2778,2779, 2780,2781,2782,2783,2784,2785,2786,1548,2787,2788,2789,1109,2790,2791,2792,2793, 2794,2795,2796,2797,2798,2799,2800,2801,2802,2803,2804,2805,2806,2807,2808,2809, 2810,2811,2812,1329,2813,2814,2815,2816,2817,2818,2819,2820,2821,2822,2823,2824, 2825,2826,2827,2828,2829,2830,2831,2832,2833,2834,2835,2836,2837,2838,2839,2840, 2841,2842,2843,2844,2845,2846,2847,2848,2849,2850,2851,2852,2853,2854,2855,2856, 1549,2857,2858,2859,2860,1550,2861,2862,1551,2863,2864,2865,2866,2867,2868,2869, 2870,2871,2872,2873,2874,1110,1330,2875,2876,2877,2878,2879,2880,2881,2882,2883, 2884,2885,2886,2887,2888,2889,2890,2891,2892,2893,2894,2895,2896,2897,2898,2899, 2900,2901,2902,2903,2904,2905,2906,2907,2908,2909,2910,2911,2912,2913,2914,2915, 2916,2917,2918,2919,2920,2921,2922,2923,2924,2925,2926,2927,2928,2929,2930,1331, 2931,2932,2933,2934,2935,2936,2937,2938,2939,2940,2941,2942,2943,1552,2944,2945, 2946,2947,2948,2949,2950,2951,2952,2953,2954,2955,2956,2957,2958,2959,2960,2961, 2962,2963,2964,1252,2965,2966,2967,2968,2969,2970,2971,2972,2973,2974,2975,2976, 2977,2978,2979,2980,2981,2982,2983,2984,2985,2986,2987,2988,2989,2990,2991,2992, 2993,2994,2995,2996,2997,2998,2999,3000,3001,3002,3003,3004,3005,3006,3007,3008, 3009,3010,3011,3012,1553,3013,3014,3015,3016,3017,1554,3018,1332,3019,3020,3021, 3022,3023,3024,3025,3026,3027,3028,3029,3030,3031,3032,3033,3034,3035,3036,3037, 3038,3039,3040,3041,3042,3043,3044,3045,3046,3047,3048,3049,3050,1555,3051,3052, 3053,1556,1557,3054,3055,3056,3057,3058,3059,3060,3061,3062,3063,3064,3065,3066, 3067,1558,3068,3069,3070,3071,3072,3073,3074,3075,3076,1559,3077,3078,3079,3080, 3081,3082,3083,1253,3084,3085,3086,3087,3088,3089,3090,3091,3092,3093,3094,3095, 3096,3097,3098,3099,3100,3101,3102,3103,3104,3105,3106,3107,3108,1152,3109,3110, 3111,3112,3113,1560,3114,3115,3116,3117,1111,3118,3119,3120,3121,3122,3123,3124, 3125,3126,3127,3128,3129,3130,3131,3132,3133,3134,3135,3136,3137,3138,3139,3140, 3141,3142,3143,3144,3145,3146,3147,3148,3149,3150,3151,3152,3153,3154,3155,3156, 3157,3158,3159,3160,3161,3162,3163,3164,3165,3166,3167,3168,3169,3170,3171,3172, 3173,3174,3175,3176,1333,3177,3178,3179,3180,3181,3182,3183,3184,3185,3186,3187, 3188,3189,1561,3190,3191,1334,3192,3193,3194,3195,3196,3197,3198,3199,3200,3201, 3202,3203,3204,3205,3206,3207,3208,3209,3210,3211,3212,3213,3214,3215,3216,3217, 3218,3219,3220,3221,3222,3223,3224,3225,3226,3227,3228,3229,3230,3231,3232,3233, 3234,1562,3235,3236,3237,3238,3239,3240,3241,3242,3243,3244,3245,3246,3247,3248, 3249,3250,3251,3252,3253,3254,3255,3256,3257,3258,3259,3260,3261,3262,3263,3264, 3265,3266,3267,3268,3269,3270,3271,3272,3273,3274,3275,3276,3277,1563,3278,3279, 3280,3281,3282,3283,3284,3285,3286,3287,3288,3289,3290,3291,3292,3293,3294,3295, 3296,3297,3298,3299,3300,3301,3302,3303,3304,3305,3306,3307,3308,3309,3310,3311, 3312,3313,3314,3315,3316,3317,3318,3319,3320,3321,3322,3323,3324,3325,3326,3327, 3328,3329,3330,3331,3332,3333,3334,3335,3336,3337,3338,3339,3340,3341,3342,3343, 3344,3345,3346,3347,3348,3349,3350,3351,3352,3353,3354,3355,3356,3357,3358,3359, 3360,3361,3362,3363,3364,1335,3365,3366,3367,3368,3369,3370,3371,3372,3373,3374, 3375,3376,3377,3378,3379,3380,3381,3382,3383,3384,3385,3386,3387,1336,3388,3389, 3390,3391,3392,3393,3394,3395,3396,3397,3398,3399,3400,3401,3402,3403,3404,3405, 3406,3407,3408,3409,3410,3411,3412,3413,3414,1337,3415,3416,3417,3418,3419,1338, 3420,3421,3422,1564,1565,3423,3424,3425,3426,3427,3428,3429,3430,3431,1254,3432, 3433,3434,1339,3435,3436,3437,3438,3439,1566,3440,3441,3442,3443,3444,3445,3446, 3447,3448,3449,3450,3451,3452,3453,3454,1255,3455,3456,3457,3458,3459,1567,1191, 3460,1568,1569,3461,3462,3463,1570,3464,3465,3466,3467,3468,1571,3469,3470,3471, 3472,3473,1572,3474,3475,3476,3477,3478,3479,3480,3481,3482,3483,3484,3485,3486, 1340,3487,3488,3489,3490,3491,3492,1021,3493,3494,3495,3496,3497,3498,1573,3499, 1341,3500,3501,3502,3503,3504,3505,3506,3507,3508,3509,3510,3511,1342,3512,3513, 3514,3515,3516,1574,1343,3517,3518,3519,1575,3520,1576,3521,3522,3523,3524,3525, 3526,3527,3528,3529,3530,3531,3532,3533,3534,3535,3536,3537,3538,3539,3540,3541, 3542,3543,3544,3545,3546,3547,3548,3549,3550,3551,3552,3553,3554,3555,3556,3557, 3558,3559,3560,3561,3562,3563,3564,3565,3566,3567,3568,3569,3570,3571,3572,3573, 3574,3575,3576,3577,3578,3579,3580,1577,3581,3582,1578,3583,3584,3585,3586,3587, 3588,3589,3590,3591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603, 3604,1579,3605,3606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618, 3619,3620,3621,3622,3623,3624,3625,3626,3627,3628,3629,1580,3630,3631,1581,3632, 3633,3634,3635,3636,3637,3638,3639,3640,3641,3642,3643,3644,3645,3646,3647,3648, 3649,3650,3651,3652,3653,3654,3655,3656,1582,3657,3658,3659,3660,3661,3662,3663, 3664,3665,3666,3667,3668,3669,3670,3671,3672,3673,3674,3675,3676,3677,3678,3679, 3680,3681,3682,3683,3684,3685,3686,3687,3688,3689,3690,3691,3692,3693,3694,3695, 3696,3697,3698,3699,3700,1192,3701,3702,3703,3704,1256,3705,3706,3707,3708,1583, 1257,3709,3710,3711,3712,3713,3714,3715,3716,1584,3717,3718,3719,3720,3721,3722, 3723,3724,3725,3726,3727,3728,3729,3730,3731,3732,3733,3734,3735,3736,3737,3738, 3739,3740,3741,3742,3743,3744,3745,1344,3746,3747,3748,3749,3750,3751,3752,3753, 3754,3755,3756,1585,3757,3758,3759,3760,3761,3762,3763,3764,3765,3766,1586,3767, 3768,3769,3770,3771,3772,3773,3774,3775,3776,3777,3778,1345,3779,3780,3781,3782, 3783,3784,3785,3786,3787,3788,3789,3790,3791,3792,3793,3794,3795,1346,1587,3796, 3797,1588,3798,3799,3800,3801,3802,3803,3804,3805,3806,1347,3807,3808,3809,3810, 3811,1589,3812,3813,3814,3815,3816,3817,3818,3819,3820,3821,1590,3822,3823,1591, 1348,3824,3825,3826,3827,3828,3829,3830,1592,3831,3832,1593,3833,3834,3835,3836, 3837,3838,3839,3840,3841,3842,3843,3844,1349,3845,3846,3847,3848,3849,3850,3851, 3852,3853,3854,3855,3856,3857,3858,1594,3859,3860,3861,3862,3863,3864,3865,3866, 3867,3868,3869,1595,3870,3871,3872,3873,1596,3874,3875,3876,3877,3878,3879,3880, 3881,3882,3883,3884,3885,3886,1597,3887,3888,3889,3890,3891,3892,3893,3894,3895, 1598,3896,3897,3898,1599,1600,3899,1350,3900,1351,3901,3902,1352,3903,3904,3905, 3906,3907,3908,3909,3910,3911,3912,3913,3914,3915,3916,3917,3918,3919,3920,3921, 3922,3923,3924,1258,3925,3926,3927,3928,3929,3930,3931,1193,3932,1601,3933,3934, 3935,3936,3937,3938,3939,3940,3941,3942,3943,1602,3944,3945,3946,3947,3948,1603, 3949,3950,3951,3952,3953,3954,3955,3956,3957,3958,3959,3960,3961,3962,3963,3964, 3965,1604,3966,3967,3968,3969,3970,3971,3972,3973,3974,3975,3976,3977,1353,3978, 3979,3980,3981,3982,3983,3984,3985,3986,3987,3988,3989,3990,3991,1354,3992,3993, 3994,3995,3996,3997,3998,3999,4000,4001,4002,4003,4004,4005,4006,4007,4008,4009, 4010,4011,4012,4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023,1355,4024, 4025,4026,4027,4028,4029,4030,4031,4032,4033,4034,4035,4036,4037,4038,4039,4040, 1605,4041,4042,4043,4044,4045,4046,4047,4048,4049,4050,4051,4052,4053,4054,4055, 4056,4057,4058,4059,4060,1606,4061,4062,4063,4064,1607,4065,4066,4067,4068,4069, 4070,4071,4072,4073,4074,4075,4076,1194,4077,4078,1608,4079,4080,4081,4082,4083, 4084,4085,4086,4087,1609,4088,4089,4090,4091,4092,4093,4094,4095,4096,4097,4098, 4099,4100,4101,4102,4103,4104,4105,4106,4107,4108,1259,4109,4110,4111,4112,4113, 4114,4115,4116,4117,4118,4119,4120,4121,4122,4123,4124,1195,4125,4126,4127,1610, 4128,4129,4130,4131,4132,4133,4134,4135,4136,4137,1356,4138,4139,4140,4141,4142, 4143,4144,1611,4145,4146,4147,4148,4149,4150,4151,4152,4153,4154,4155,4156,4157, 4158,4159,4160,4161,4162,4163,4164,4165,4166,4167,4168,4169,4170,4171,4172,4173, 4174,4175,4176,4177,4178,4179,4180,4181,4182,4183,4184,4185,4186,4187,4188,4189, 4190,4191,4192,4193,4194,4195,4196,4197,4198,4199,4200,4201,4202,4203,4204,4205, 4206,4207,4208,4209,4210,4211,4212,4213,4214,4215,4216,4217,4218,4219,1612,4220, 4221,4222,4223,4224,4225,4226,4227,1357,4228,1613,4229,4230,4231,4232,4233,4234, 4235,4236,4237,4238,4239,4240,4241,4242,4243,1614,4244,4245,4246,4247,4248,4249, 4250,4251,4252,4253,4254,4255,4256,4257,4258,4259,4260,4261,4262,4263,4264,4265, 4266,4267,4268,4269,4270,1196,1358,4271,4272,4273,4274,4275,4276,4277,4278,4279, 4280,4281,4282,4283,4284,4285,4286,4287,1615,4288,4289,4290,4291,4292,4293,4294, 4295,4296,4297,4298,4299,4300,4301,4302,4303,4304,4305,4306,4307,4308,4309,4310, 4311,4312,4313,4314,4315,4316,4317,4318,4319,4320,4321,4322,4323,4324,4325,4326, 4327,4328,4329,4330,4331,4332,4333,4334,1616,4335,4336,4337,4338,4339,4340,4341, 4342,4343,4344,4345,4346,4347,4348,4349,4350,4351,4352,4353,4354,4355,4356,4357, 4358,4359,4360,1617,4361,4362,4363,4364,4365,1618,4366,4367,4368,4369,4370,4371, 4372,4373,4374,4375,4376,4377,4378,4379,4380,4381,4382,4383,4384,4385,4386,4387, 4388,4389,4390,4391,4392,4393,4394,4395,4396,4397,4398,4399,4400,4401,4402,4403, 4404,4405,4406,4407,4408,4409,4410,4411,4412,4413,4414,4415,4416,1619,4417,4418, 4419,4420,4421,4422,4423,4424,4425,1112,4426,4427,4428,4429,4430,1620,4431,4432, 4433,4434,4435,4436,4437,4438,4439,4440,4441,4442,1260,1261,4443,4444,4445,4446, 4447,4448,4449,4450,4451,4452,4453,4454,4455,1359,4456,4457,4458,4459,4460,4461, 4462,4463,4464,4465,1621,4466,4467,4468,4469,4470,4471,4472,4473,4474,4475,4476, 4477,4478,4479,4480,4481,4482,4483,4484,4485,4486,4487,4488,4489,1055,4490,4491, 4492,4493,4494,4495,4496,4497,4498,4499,4500,4501,4502,4503,4504,4505,4506,4507, 4508,4509,4510,4511,4512,4513,4514,4515,4516,4517,4518,1622,4519,4520,4521,1623, 4522,4523,4524,4525,4526,4527,4528,4529,4530,4531,4532,4533,4534,4535,1360,4536, 4537,4538,4539,4540,4541,4542,4543, 975,4544,4545,4546,4547,4548,4549,4550,4551, 4552,4553,4554,4555,4556,4557,4558,4559,4560,4561,4562,4563,4564,4565,4566,4567, 4568,4569,4570,4571,1624,4572,4573,4574,4575,4576,1625,4577,4578,4579,4580,4581, 4582,4583,4584,1626,4585,4586,4587,4588,4589,4590,4591,4592,4593,4594,4595,1627, 4596,4597,4598,4599,4600,4601,4602,4603,4604,4605,4606,4607,4608,4609,4610,4611, 4612,4613,4614,4615,1628,4616,4617,4618,4619,4620,4621,4622,4623,4624,4625,4626, 4627,4628,4629,4630,4631,4632,4633,4634,4635,4636,4637,4638,4639,4640,4641,4642, 4643,4644,4645,4646,4647,4648,4649,1361,4650,4651,4652,4653,4654,4655,4656,4657, 4658,4659,4660,4661,1362,4662,4663,4664,4665,4666,4667,4668,4669,4670,4671,4672, 4673,4674,4675,4676,4677,4678,4679,4680,4681,4682,1629,4683,4684,4685,4686,4687, 1630,4688,4689,4690,4691,1153,4692,4693,4694,1113,4695,4696,4697,4698,4699,4700, 4701,4702,4703,4704,4705,4706,4707,4708,4709,4710,4711,1197,4712,4713,4714,4715, 4716,4717,4718,4719,4720,4721,4722,4723,4724,4725,4726,4727,4728,4729,4730,4731, 4732,4733,4734,4735,1631,4736,1632,4737,4738,4739,4740,4741,4742,4743,4744,1633, 4745,4746,4747,4748,4749,1262,4750,4751,4752,4753,4754,1363,4755,4756,4757,4758, 4759,4760,4761,4762,4763,4764,4765,4766,4767,4768,1634,4769,4770,4771,4772,4773, 4774,4775,4776,4777,4778,1635,4779,4780,4781,4782,4783,4784,4785,4786,4787,4788, 4789,1636,4790,4791,4792,4793,4794,4795,4796,4797,4798,4799,4800,4801,4802,4803, 4804,4805,4806,1637,4807,4808,4809,1638,4810,4811,4812,4813,4814,4815,4816,4817, 4818,1639,4819,4820,4821,4822,4823,4824,4825,4826,4827,4828,4829,4830,4831,4832, 4833,1077,4834,4835,4836,4837,4838,4839,4840,4841,4842,4843,4844,4845,4846,4847, 4848,4849,4850,4851,4852,4853,4854,4855,4856,4857,4858,4859,4860,4861,4862,4863, 4864,4865,4866,4867,4868,4869,4870,4871,4872,4873,4874,4875,4876,4877,4878,4879, 4880,4881,4882,4883,1640,4884,4885,1641,4886,4887,4888,4889,4890,4891,4892,4893, 4894,4895,4896,4897,4898,4899,4900,4901,4902,4903,4904,4905,4906,4907,4908,4909, 4910,4911,1642,4912,4913,4914,1364,4915,4916,4917,4918,4919,4920,4921,4922,4923, 4924,4925,4926,4927,4928,4929,4930,4931,1643,4932,4933,4934,4935,4936,4937,4938, 4939,4940,4941,4942,4943,4944,4945,4946,4947,4948,4949,4950,4951,4952,4953,4954, 4955,4956,4957,4958,4959,4960,4961,4962,4963,4964,4965,4966,4967,4968,4969,4970, 4971,4972,4973,4974,4975,4976,4977,4978,4979,4980,1644,4981,4982,4983,4984,1645, 4985,4986,1646,4987,4988,4989,4990,4991,4992,4993,4994,4995,4996,4997,4998,4999, 5000,5001,5002,5003,5004,5005,1647,5006,1648,5007,5008,5009,5010,5011,5012,1078, 5013,5014,5015,5016,5017,5018,5019,5020,5021,5022,5023,5024,5025,5026,5027,5028, 1365,5029,5030,5031,5032,5033,5034,5035,5036,5037,5038,5039,1649,5040,5041,5042, 5043,5044,5045,1366,5046,5047,5048,5049,5050,5051,5052,5053,5054,5055,1650,5056, 5057,5058,5059,5060,5061,5062,5063,5064,5065,5066,5067,5068,5069,5070,5071,5072, 5073,5074,5075,5076,5077,1651,5078,5079,5080,5081,5082,5083,5084,5085,5086,5087, 5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102,5103, 5104,5105,5106,5107,5108,5109,5110,1652,5111,5112,5113,5114,5115,5116,5117,5118, 1367,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,1653,5130,5131,5132, 5133,5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148, 5149,1368,5150,1654,5151,1369,5152,5153,5154,5155,5156,5157,5158,5159,5160,5161, 5162,5163,5164,5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,5176,5177, 5178,1370,5179,5180,5181,5182,5183,5184,5185,5186,5187,5188,5189,5190,5191,5192, 5193,5194,5195,5196,5197,5198,1655,5199,5200,5201,5202,1656,5203,5204,5205,5206, 1371,5207,1372,5208,5209,5210,5211,1373,5212,5213,1374,5214,5215,5216,5217,5218, 5219,5220,5221,5222,5223,5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234, 5235,5236,5237,5238,5239,5240,5241,5242,5243,5244,5245,5246,5247,1657,5248,5249, 5250,5251,1658,1263,5252,5253,5254,5255,5256,1375,5257,5258,5259,5260,5261,5262, 5263,5264,5265,5266,5267,5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278, 5279,5280,5281,5282,5283,1659,5284,5285,5286,5287,5288,5289,5290,5291,5292,5293, 5294,5295,5296,5297,5298,5299,5300,1660,5301,5302,5303,5304,5305,5306,5307,5308, 5309,5310,5311,5312,5313,5314,5315,5316,5317,5318,5319,5320,5321,1376,5322,5323, 5324,5325,5326,5327,5328,5329,5330,5331,5332,5333,1198,5334,5335,5336,5337,5338, 5339,5340,5341,5342,5343,1661,5344,5345,5346,5347,5348,5349,5350,5351,5352,5353, 5354,5355,5356,5357,5358,5359,5360,5361,5362,5363,5364,5365,5366,5367,5368,5369, 5370,5371,5372,5373,5374,5375,5376,5377,5378,5379,5380,5381,5382,5383,5384,5385, 5386,5387,5388,5389,5390,5391,5392,5393,5394,5395,5396,5397,5398,1264,5399,5400, 5401,5402,5403,5404,5405,5406,5407,5408,5409,5410,5411,5412,1662,5413,5414,5415, 5416,1663,5417,5418,5419,5420,5421,5422,5423,5424,5425,5426,5427,5428,5429,5430, 5431,5432,5433,5434,5435,5436,5437,5438,1664,5439,5440,5441,5442,5443,5444,5445, 5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456,5457,5458,5459,5460,5461, 5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472,5473,5474,5475,5476,5477, 5478,1154,5479,5480,5481,5482,5483,5484,5485,1665,5486,5487,5488,5489,5490,5491, 5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504,5505,5506,5507, 5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520,5521,5522,5523, 5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536,5537,5538,5539, 5540,5541,5542,5543,5544,5545,5546,5547,5548,1377,5549,5550,5551,5552,5553,5554, 5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568,5569,5570, 1114,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584,5585, 5586,5587,5588,5589,5590,5591,5592,1378,5593,5594,5595,5596,5597,5598,5599,5600, 5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,1379,5615, 5616,5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631, 5632,5633,5634,1380,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646, 5647,5648,5649,1381,1056,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660, 1666,5661,5662,5663,5664,5665,5666,5667,5668,1667,5669,1668,5670,5671,5672,5673, 5674,5675,5676,5677,5678,1155,5679,5680,5681,5682,5683,5684,5685,5686,5687,5688, 5689,5690,5691,5692,5693,5694,5695,5696,5697,5698,1669,5699,5700,5701,5702,5703, 5704,5705,1670,5706,5707,5708,5709,5710,1671,5711,5712,5713,5714,1382,5715,5716, 5717,5718,5719,5720,5721,5722,5723,5724,5725,1672,5726,5727,1673,1674,5728,5729, 5730,5731,5732,5733,5734,5735,5736,1675,5737,5738,5739,5740,5741,5742,5743,5744, 1676,5745,5746,5747,5748,5749,5750,5751,1383,5752,5753,5754,5755,5756,5757,5758, 5759,5760,5761,5762,5763,5764,5765,5766,5767,5768,1677,5769,5770,5771,5772,5773, 1678,5774,5775,5776, 998,5777,5778,5779,5780,5781,5782,5783,5784,5785,1384,5786, 5787,5788,5789,5790,5791,5792,5793,5794,5795,5796,5797,5798,5799,5800,1679,5801, 5802,5803,1115,1116,5804,5805,5806,5807,5808,5809,5810,5811,5812,5813,5814,5815, 5816,5817,5818,5819,5820,5821,5822,5823,5824,5825,5826,5827,5828,5829,5830,5831, 5832,5833,5834,5835,5836,5837,5838,5839,5840,5841,5842,5843,5844,5845,5846,5847, 5848,5849,5850,5851,5852,5853,5854,5855,1680,5856,5857,5858,5859,5860,5861,5862, 5863,5864,1681,5865,5866,5867,1682,5868,5869,5870,5871,5872,5873,5874,5875,5876, 5877,5878,5879,1683,5880,1684,5881,5882,5883,5884,1685,5885,5886,5887,5888,5889, 5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904,5905, 5906,5907,1686,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, 5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,1687, 5936,5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951, 5952,1688,1689,5953,1199,5954,5955,5956,5957,5958,5959,5960,5961,1690,5962,5963, 5964,5965,5966,5967,5968,5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979, 5980,5981,1385,5982,1386,5983,5984,5985,5986,5987,5988,5989,5990,5991,5992,5993, 5994,5995,5996,5997,5998,5999,6000,6001,6002,6003,6004,6005,6006,6007,6008,6009, 6010,6011,6012,6013,6014,6015,6016,6017,6018,6019,6020,6021,6022,6023,6024,6025, 6026,6027,1265,6028,6029,1691,6030,6031,6032,6033,6034,6035,6036,6037,6038,6039, 6040,6041,6042,6043,6044,6045,6046,6047,6048,6049,6050,6051,6052,6053,6054,6055, 6056,6057,6058,6059,6060,6061,6062,6063,6064,6065,6066,6067,6068,6069,6070,6071, 6072,6073,6074,6075,6076,6077,6078,6079,6080,6081,6082,6083,6084,1692,6085,6086, 6087,6088,6089,6090,6091,6092,6093,6094,6095,6096,6097,6098,6099,6100,6101,6102, 6103,6104,6105,6106,6107,6108,6109,6110,6111,6112,6113,6114,6115,6116,6117,6118, 6119,6120,6121,6122,6123,6124,6125,6126,6127,6128,6129,6130,6131,1693,6132,6133, 6134,6135,6136,1694,6137,6138,6139,6140,6141,1695,6142,6143,6144,6145,6146,6147, 6148,6149,6150,6151,6152,6153,6154,6155,6156,6157,6158,6159,6160,6161,6162,6163, 6164,6165,6166,6167,6168,6169,6170,6171,6172,6173,6174,6175,6176,6177,6178,6179, 6180,6181,6182,6183,6184,6185,1696,6186,6187,6188,6189,6190,6191,6192,6193,6194, 6195,6196,6197,6198,6199,6200,6201,6202,6203,6204,6205,6206,6207,6208,6209,6210, 6211,6212,6213,6214,6215,6216,6217,6218,6219,1697,6220,6221,6222,6223,6224,6225, 6226,6227,6228,6229,6230,6231,6232,6233,6234,6235,6236,6237,6238,6239,6240,6241, 6242,6243,6244,6245,6246,6247,6248,6249,6250,6251,6252,6253,1698,6254,6255,6256, 6257,6258,6259,6260,6261,6262,6263,1200,6264,6265,6266,6267,6268,6269,6270,6271, //1024 6272,6273,6274,6275,6276,6277,6278,6279,6280,6281,6282,6283,6284,6285,6286,6287, 6288,6289,6290,6291,6292,6293,6294,6295,6296,6297,6298,6299,6300,6301,6302,1699, 6303,6304,1700,6305,6306,6307,6308,6309,6310,6311,6312,6313,6314,6315,6316,6317, 6318,6319,6320,6321,6322,6323,6324,6325,6326,6327,6328,6329,6330,6331,6332,6333, 6334,6335,6336,6337,6338,6339,1701,6340,6341,6342,6343,6344,1387,6345,6346,6347, 6348,6349,6350,6351,6352,6353,6354,6355,6356,6357,6358,6359,6360,6361,6362,6363, 6364,6365,6366,6367,6368,6369,6370,6371,6372,6373,6374,6375,6376,6377,6378,6379, 6380,6381,6382,6383,6384,6385,6386,6387,6388,6389,6390,6391,6392,6393,6394,6395, 6396,6397,6398,6399,6400,6401,6402,6403,6404,6405,6406,6407,6408,6409,6410,6411, 6412,6413,1702,6414,6415,6416,6417,6418,6419,6420,6421,6422,1703,6423,6424,6425, 6426,6427,6428,6429,6430,6431,6432,6433,6434,6435,6436,6437,6438,1704,6439,6440, 6441,6442,6443,6444,6445,6446,6447,6448,6449,6450,6451,6452,6453,6454,6455,6456, 6457,6458,6459,6460,6461,6462,6463,6464,6465,6466,6467,6468,6469,6470,6471,6472, 6473,6474,6475,6476,6477,6478,6479,6480,6481,6482,6483,6484,6485,6486,6487,6488, 6489,6490,6491,6492,6493,6494,6495,6496,6497,6498,6499,6500,6501,6502,6503,1266, 6504,6505,6506,6507,6508,6509,6510,6511,6512,6513,6514,6515,6516,6517,6518,6519, 6520,6521,6522,6523,6524,6525,6526,6527,6528,6529,6530,6531,6532,6533,6534,6535, 6536,6537,6538,6539,6540,6541,6542,6543,6544,6545,6546,6547,6548,6549,6550,6551, 1705,1706,6552,6553,6554,6555,6556,6557,6558,6559,6560,6561,6562,6563,6564,6565, 6566,6567,6568,6569,6570,6571,6572,6573,6574,6575,6576,6577,6578,6579,6580,6581, 6582,6583,6584,6585,6586,6587,6588,6589,6590,6591,6592,6593,6594,6595,6596,6597, 6598,6599,6600,6601,6602,6603,6604,6605,6606,6607,6608,6609,6610,6611,6612,6613, 6614,6615,6616,6617,6618,6619,6620,6621,6622,6623,6624,6625,6626,6627,6628,6629, 6630,6631,6632,6633,6634,6635,6636,6637,1388,6638,6639,6640,6641,6642,6643,6644, 1707,6645,6646,6647,6648,6649,6650,6651,6652,6653,6654,6655,6656,6657,6658,6659, 6660,6661,6662,6663,1708,6664,6665,6666,6667,6668,6669,6670,6671,6672,6673,6674, 1201,6675,6676,6677,6678,6679,6680,6681,6682,6683,6684,6685,6686,6687,6688,6689, 6690,6691,6692,6693,6694,6695,6696,6697,6698,6699,6700,6701,6702,6703,6704,6705, 6706,6707,6708,6709,6710,6711,6712,6713,6714,6715,6716,6717,6718,6719,6720,6721, 6722,6723,6724,6725,1389,6726,6727,6728,6729,6730,6731,6732,6733,6734,6735,6736, 1390,1709,6737,6738,6739,6740,6741,6742,1710,6743,6744,6745,6746,1391,6747,6748, 6749,6750,6751,6752,6753,6754,6755,6756,6757,1392,6758,6759,6760,6761,6762,6763, 6764,6765,6766,6767,6768,6769,6770,6771,6772,6773,6774,6775,6776,6777,6778,6779, 6780,1202,6781,6782,6783,6784,6785,6786,6787,6788,6789,6790,6791,6792,6793,6794, 6795,6796,6797,6798,6799,6800,6801,6802,6803,6804,6805,6806,6807,6808,6809,1711, 6810,6811,6812,6813,6814,6815,6816,6817,6818,6819,6820,6821,6822,6823,6824,6825, 6826,6827,6828,6829,6830,6831,6832,6833,6834,6835,6836,1393,6837,6838,6839,6840, 6841,6842,6843,6844,6845,6846,6847,6848,6849,6850,6851,6852,6853,6854,6855,6856, 6857,6858,6859,6860,6861,6862,6863,6864,6865,6866,6867,6868,6869,6870,6871,6872, 6873,6874,6875,6876,6877,6878,6879,6880,6881,6882,6883,6884,6885,6886,6887,6888, 6889,6890,6891,6892,6893,6894,6895,6896,6897,6898,6899,6900,6901,6902,1712,6903, 6904,6905,6906,6907,6908,6909,6910,1713,6911,6912,6913,6914,6915,6916,6917,6918, 6919,6920,6921,6922,6923,6924,6925,6926,6927,6928,6929,6930,6931,6932,6933,6934, 6935,6936,6937,6938,6939,6940,6941,6942,6943,6944,6945,6946,6947,6948,6949,6950, 6951,6952,6953,6954,6955,6956,6957,6958,6959,6960,6961,6962,6963,6964,6965,6966, 6967,6968,6969,6970,6971,6972,6973,6974,1714,6975,6976,6977,6978,6979,6980,6981, 6982,6983,6984,6985,6986,6987,6988,1394,6989,6990,6991,6992,6993,6994,6995,6996, 6997,6998,6999,7000,1715,7001,7002,7003,7004,7005,7006,7007,7008,7009,7010,7011, 7012,7013,7014,7015,7016,7017,7018,7019,7020,7021,7022,7023,7024,7025,7026,7027, 7028,1716,7029,7030,7031,7032,7033,7034,7035,7036,7037,7038,7039,7040,7041,7042, 7043,7044,7045,7046,7047,7048,7049,7050,7051,7052,7053,7054,7055,7056,7057,7058, 7059,7060,7061,7062,7063,7064,7065,7066,7067,7068,7069,7070,7071,7072,7073,7074, 7075,7076,7077,7078,7079,7080,7081,7082,7083,7084,7085,7086,7087,7088,7089,7090, 7091,7092,7093,7094,7095,7096,7097,7098,7099,7100,7101,7102,7103,7104,7105,7106, 7107,7108,7109,7110,7111,7112,7113,7114,7115,7116,7117,7118,7119,7120,7121,7122, 7123,7124,7125,7126,7127,7128,7129,7130,7131,7132,7133,7134,7135,7136,7137,7138, 7139,7140,7141,7142,7143,7144,7145,7146,7147,7148,7149,7150,7151,7152,7153,7154, 7155,7156,7157,7158,7159,7160,7161,7162,7163,7164,7165,7166,7167,7168,7169,7170, 7171,7172,7173,7174,7175,7176,7177,7178,7179,7180,7181,7182,7183,7184,7185,7186, 7187,7188,7189,7190,7191,7192,7193,7194,7195,7196,7197,7198,7199,7200,7201,7202, 7203,7204,7205,7206,7207,1395,7208,7209,7210,7211,7212,7213,1717,7214,7215,7216, 7217,7218,7219,7220,7221,7222,7223,7224,7225,7226,7227,7228,7229,7230,7231,7232, 7233,7234,7235,7236,7237,7238,7239,7240,7241,7242,7243,7244,7245,7246,7247,7248, 7249,7250,7251,7252,7253,7254,7255,7256,7257,7258,7259,7260,7261,7262,7263,7264, 7265,7266,7267,7268,7269,7270,7271,7272,7273,7274,7275,7276,7277,7278,7279,7280, 7281,7282,7283,7284,7285,7286,7287,7288,7289,7290,7291,7292,7293,7294,7295,7296, 7297,7298,7299,7300,7301,7302,7303,7304,7305,7306,7307,7308,7309,7310,7311,7312, 7313,1718,7314,7315,7316,7317,7318,7319,7320,7321,7322,7323,7324,7325,7326,7327, 7328,7329,7330,7331,7332,7333,7334,7335,7336,7337,7338,7339,7340,7341,7342,7343, 7344,7345,7346,7347,7348,7349,7350,7351,7352,7353,7354,7355,7356,7357,7358,7359, 7360,7361,7362,7363,7364,7365,7366,7367,7368,7369,7370,7371,7372,7373,7374,7375, 7376,7377,7378,7379,7380,7381,7382,7383,7384,7385,7386,7387,7388,7389,7390,7391, 7392,7393,7394,7395,7396,7397,7398,7399,7400,7401,7402,7403,7404,7405,7406,7407, 7408,7409,7410,7411,7412,7413,7414,7415,7416,7417,7418,7419,7420,7421,7422,7423, 7424,7425,7426,7427,7428,7429,7430,7431,7432,7433,7434,7435,7436,7437,7438,7439, 7440,7441,7442,7443,7444,7445,7446,7447,7448,7449,7450,7451,7452,7453,7454,7455, 7456,7457,7458,7459,7460,7461,7462,7463,7464,7465,7466,7467,7468,7469,7470,7471, 7472,7473,7474,7475,7476,7477,7478,7479,7480,7481,7482,7483,7484,7485,7486,7487, 7488,7489,7490,7491,7492,7493,7494,7495,7496,7497,7498,7499,7500,7501,7502,7503, 7504,7505,7506,7507,7508,7509,7510,7511,7512,7513,7514,7515,7516,7517,7518,7519, 7520,7521,7522,7523,7524,7525,7526,7527,7528,7529,7530,7531,7532,7533,7534,7535, 7536,7537,7538,7539,7540,7541,7542,7543,7544,7545,7546,7547,7548,7549,7550,7551, 7552,7553,7554,7555,7556,7557,7558,7559,7560,7561,7562,7563,7564,7565,7566,7567, 7568,7569,7570,7571,7572,7573,7574,7575,7576,7577,7578,7579,7580,7581,7582,7583, 7584,7585,7586,7587,7588,7589,7590,7591,7592,7593,7594,7595,7596,7597,7598,7599, 7600,7601,7602,7603,7604,7605,7606,7607,7608,7609,7610,7611,7612,7613,7614,7615, 7616,7617,7618,7619,7620,7621,7622,7623,7624,7625,7626,7627,7628,7629,7630,7631, 7632,7633,7634,7635,7636,7637,7638,7639,7640,7641,7642,7643,7644,7645,7646,7647, 7648,7649,7650,7651,7652,7653,7654,7655,7656,7657,7658,7659,7660,7661,7662,7663, 7664,7665,7666,7667,7668,7669,7670,7671,7672,7673,7674,7675,7676,7677,7678,7679, 7680,7681,7682,7683,7684,7685,7686,7687,7688,7689,7690,7691,7692,7693,7694,7695, 7696,7697,7698,7699,7700,7701,7702,7703,7704,7705,7706,7707,7708,7709,7710,7711, 7712,7713,7714,7715,7716,7717,7718,7719,7720,7721,7722,7723,7724,7725,7726,7727, 7728,7729,7730,7731,7732,7733,7734,7735,7736,7737,7738,7739,7740,7741,7742,7743, 7744,7745,7746,7747,7748,7749,7750,7751,7752,7753,7754,7755,7756,7757,7758,7759, 7760,7761,7762,7763,7764,7765,7766,7767,7768,7769,7770,7771,7772,7773,7774,7775, 7776,7777,7778,7779,7780,7781,7782,7783,7784,7785,7786,7787,7788,7789,7790,7791, 7792,7793,7794,7795,7796,7797,7798,7799,7800,7801,7802,7803,7804,7805,7806,7807, 7808,7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823, 7824,7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839, 7840,7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855, 7856,7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871, 7872,7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887, 7888,7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903, 7904,7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919, 7920,7921,7922,7923,7924,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, 7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, 7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, 7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, 7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, 8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, 8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, 8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, 8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, 8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, 8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, 8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, 8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, 8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, 8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, 8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, 8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, 8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, 8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, 8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, 8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, 8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, 8272,8273,8274,8275,8276,8277,8278,8279,8280,8281,8282,8283,8284,8285,8286,8287, 8288,8289,8290,8291,8292,8293,8294,8295,8296,8297,8298,8299,8300,8301,8302,8303, 8304,8305,8306,8307,8308,8309,8310,8311,8312,8313,8314,8315,8316,8317,8318,8319, 8320,8321,8322,8323,8324,8325,8326,8327,8328,8329,8330,8331,8332,8333,8334,8335, 8336,8337,8338,8339,8340,8341,8342,8343,8344,8345,8346,8347,8348,8349,8350,8351, 8352,8353,8354,8355,8356,8357,8358,8359,8360,8361,8362,8363,8364,8365,8366,8367, 8368,8369,8370,8371,8372,8373,8374,8375,8376,8377,8378,8379,8380,8381,8382,8383, 8384,8385,8386,8387,8388,8389,8390,8391,8392,8393,8394,8395,8396,8397,8398,8399, 8400,8401,8402,8403,8404,8405,8406,8407,8408,8409,8410,8411,8412,8413,8414,8415, 8416,8417,8418,8419,8420,8421,8422,8423,8424,8425,8426,8427,8428,8429,8430,8431, 8432,8433,8434,8435,8436,8437,8438,8439,8440,8441,8442,8443,8444,8445,8446,8447, 8448,8449,8450,8451,8452,8453,8454,8455,8456,8457,8458,8459,8460,8461,8462,8463, 8464,8465,8466,8467,8468,8469,8470,8471,8472,8473,8474,8475,8476,8477,8478,8479, 8480,8481,8482,8483,8484,8485,8486,8487,8488,8489,8490,8491,8492,8493,8494,8495, 8496,8497,8498,8499,8500,8501,8502,8503,8504,8505,8506,8507,8508,8509,8510,8511, 8512,8513,8514,8515,8516,8517,8518,8519,8520,8521,8522,8523,8524,8525,8526,8527, 8528,8529,8530,8531,8532,8533,8534,8535,8536,8537,8538,8539,8540,8541,8542,8543, 8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,8554,8555,8556,8557,8558,8559, 8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,8570,8571,8572,8573,8574,8575, 8576,8577,8578,8579,8580,8581,8582,8583,8584,8585,8586,8587,8588,8589,8590,8591, 8592,8593,8594,8595,8596,8597,8598,8599,8600,8601,8602,8603,8604,8605,8606,8607, 8608,8609,8610,8611,8612,8613,8614,8615,8616,8617,8618,8619,8620,8621,8622,8623, 8624,8625,8626,8627,8628,8629,8630,8631,8632,8633,8634,8635,8636,8637,8638,8639, 8640,8641,8642,8643,8644,8645,8646,8647,8648,8649,8650,8651,8652,8653,8654,8655, 8656,8657,8658,8659,8660,8661,8662,8663,8664,8665,8666,8667,8668,8669,8670,8671, 8672,8673,8674,8675,8676,8677,8678,8679,8680,8681,8682,8683,8684,8685,8686,8687, 8688,8689,8690,8691,8692,8693,8694,8695,8696,8697,8698,8699,8700,8701,8702,8703, 8704,8705,8706,8707,8708,8709,8710,8711,8712,8713,8714,8715,8716,8717,8718,8719, 8720,8721,8722,8723,8724,8725,8726,8727,8728,8729,8730,8731,8732,8733,8734,8735, 8736,8737,8738,8739,8740,8741 ****************************************************************************************/ }; diff --git a/src/probers/tables/GB2312Freq.tab b/src/probers/tables/GB2312Freq.tab index 88b4220..061eed2 100644 --- a/src/probers/tables/GB2312Freq.tab +++ b/src/probers/tables/GB2312Freq.tab @@ -1,479 +1,461 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 + + SPDX-License-Identifier: MIT */ //GB2312 most frequently used character table //Char to FreqOrder table , from hz6763 /****************************************************************************** * 512 --> 0.79 -- 0.79 * 1024 --> 0.92 -- 0.13 * 2048 --> 0.98 -- 0.06 * 6768 --> 1.00 -- 0.02 * * Idea Distribution Ratio = 0.79135/(1-0.79135) = 3.79 * Random Distribution Ration = 512 / (3755 - 512) = 0.157 - * + * * Typical Distribution Ratio about 25% of Ideal one, still much higher that RDR *****************************************************************************/ #define GB2312_TYPICAL_DISTRIBUTION_RATIO (float)0.9 #define GB2312_TABLE_SIZE 3760 static const short GB2312CharToFreqOrder[] = { 1671, 749,1443,2364,3924,3807,2330,3921,1704,3463,2691,1511,1515, 572,3191,2205, 2361, 224,2558, 479,1711, 963,3162, 440,4060,1905,2966,2947,3580,2647,3961,3842, 2204, 869,4207, 970,2678,5626,2944,2956,1479,4048, 514,3595, 588,1346,2820,3409, 249,4088,1746,1873,2047,1774, 581,1813, 358,1174,3590,1014,1561,4844,2245, 670, 1636,3112, 889,1286, 953, 556,2327,3060,1290,3141, 613, 185,3477,1367, 850,3820, 1715,2428,2642,2303,2732,3041,2562,2648,3566,3946,1349, 388,3098,2091,1360,3585, 152,1687,1539, 738,1559, 59,1232,2925,2267,1388,1249,1741,1679,2960, 151,1566, 1125,1352,4271, 924,4296, 385,3166,4459, 310,1245,2850, 70,3285,2729,3534,3575, 2398,3298,3466,1960,2265, 217,3647, 864,1909,2084,4401,2773,1010,3269,5152, 853, 3051,3121,1244,4251,1895, 364,1499,1540,2313,1180,3655,2268, 562, 715,2417,3061, 544, 336,3768,2380,1752,4075, 950, 280,2425,4382, 183,2759,3272, 333,4297,2155, 1688,2356,1444,1039,4540, 736,1177,3349,2443,2368,2144,2225, 565, 196,1482,3406, 927,1335,4147, 692, 878,1311,1653,3911,3622,1378,4200,1840,2969,3149,2126,1816, 2534,1546,2393,2760, 737,2494, 13, 447, 245,2747, 38,2765,2129,2589,1079, 606, 360, 471,3755,2890, 404, 848, 699,1785,1236, 370,2221,1023,3746,2074,2026,2023, 2388,1581,2119, 812,1141,3091,2536,1519, 804,2053, 406,1596,1090, 784, 548,4414, 1806,2264,2936,1100, 343,4114,5096, 622,3358, 743,3668,1510,1626,5020,3567,2513, 3195,4115,5627,2489,2991, 24,2065,2697,1087,2719, 48,1634, 315, 68, 985,2052, 198,2239,1347,1107,1439, 597,2366,2172, 871,3307, 919,2487,2790,1867, 236,2570, 1413,3794, 906,3365,3381,1701,1982,1818,1524,2924,1205, 616,2586,2072,2004, 575, 253,3099, 32,1365,1182, 197,1714,2454,1201, 554,3388,3224,2748, 756,2587, 250, 2567,1507,1517,3529,1922,2761,2337,3416,1961,1677,2452,2238,3153, 615, 911,1506, 1474,2495,1265,1906,2749,3756,3280,2161, 898,2714,1759,3450,2243,2444, 563, 26, 3286,2266,3769,3344,2707,3677, 611,1402, 531,1028,2871,4548,1375, 261,2948, 835, 1190,4134, 353, 840,2684,1900,3082,1435,2109,1207,1674, 329,1872,2781,4055,2686, 2104, 608,3318,2423,2957,2768,1108,3739,3512,3271,3985,2203,1771,3520,1418,2054, 1681,1153, 225,1627,2929, 162,2050,2511,3687,1954, 124,1859,2431,1684,3032,2894, 585,4805,3969,2869,2704,2088,2032,2095,3656,2635,4362,2209, 256, 518,2042,2105, 3777,3657, 643,2298,1148,1779, 190, 989,3544, 414, 11,2135,2063,2979,1471, 403, 3678, 126, 770,1563, 671,2499,3216,2877, 600,1179, 307,2805,4937,1268,1297,2694, 252,4032,1448,1494,1331,1394, 127,2256, 222,1647,1035,1481,3056,1915,1048, 873, 3651, 210, 33,1608,2516, 200,1520, 415, 102, 0,3389,1287, 817, 91,3299,2940, 836,1814, 549,2197,1396,1669,2987,3582,2297,2848,4528,1070, 687, 20,1819, 121, 1552,1364,1461,1968,2617,3540,2824,2083, 177, 948,4938,2291, 110,4549,2066, 648, 3359,1755,2110,2114,4642,4845,1693,3937,3308,1257,1869,2123, 208,1804,3159,2992, 2531,2549,3361,2418,1350,2347,2800,2568,1291,2036,2680, 72, 842,1990, 212,1233, 1154,1586, 75,2027,3410,4900,1823,1337,2710,2676, 728,2810,1522,3026,4995, 157, 755,1050,4022, 710, 785,1936,2194,2085,1406,2777,2400, 150,1250,4049,1206, 807, 1910, 534, 529,3309,1721,1660, 274, 39,2827, 661,2670,1578, 925,3248,3815,1094, 4278,4901,4252, 41,1150,3747,2572,2227,4501,3658,4902,3813,3357,3617,2884,2258, 887, 538,4187,3199,1294,2439,3042,2329,2343,2497,1255, 107, 543,1527, 521,3478, 3568, 194,5062, 15, 961,3870,1241,1192,2664, 66,5215,3260,2111,1295,1127,2152, 3805,4135, 901,1164,1976, 398,1278, 530,1460, 748, 904,1054,1966,1426, 53,2909, 509, 523,2279,1534, 536,1019, 239,1685, 460,2353, 673,1065,2401,3600,4298,2272, 1272,2363, 284,1753,3679,4064,1695, 81, 815,2677,2757,2731,1386, 859, 500,4221, 2190,2566, 757,1006,2519,2068,1166,1455, 337,2654,3203,1863,1682,1914,3025,1252, 1409,1366, 847, 714,2834,2038,3209, 964,2970,1901, 885,2553,1078,1756,3049, 301, 1572,3326, 688,2130,1996,2429,1805,1648,2930,3421,2750,3652,3088, 262,1158,1254, 389,1641,1812, 526,1719, 923,2073,1073,1902, 468, 489,4625,1140, 857,2375,3070, 3319,2863, 380, 116,1328,2693,1161,2244, 273,1212,1884,2769,3011,1775,1142, 461, 3066,1200,2147,2212, 790, 702,2695,4222,1601,1058, 434,2338,5153,3640, 67,2360, 4099,2502, 618,3472,1329, 416,1132, 830,2782,1807,2653,3211,3510,1662, 192,2124, 296,3979,1739,1611,3684, 23, 118, 324, 446,1239,1225, 293,2520,3814,3795,2535, 3116, 17,1074, 467,2692,2201, 387,2922, 45,1326,3055,1645,3659,2817, 958, 243, 1903,2320,1339,2825,1784,3289, 356, 576, 865,2315,2381,3377,3916,1088,3122,1713, 1655, 935, 628,4689,1034,1327, 441, 800, 720, 894,1979,2183,1528,5289,2702,1071, 4046,3572,2399,1571,3281, 79, 761,1103, 327, 134, 758,1899,1371,1615, 879, 442, 215,2605,2579, 173,2048,2485,1057,2975,3317,1097,2253,3801,4263,1403,1650,2946, 814,4968,3487,1548,2644,1567,1285, 2, 295,2636, 97, 946,3576, 832, 141,4257, 3273, 760,3821,3521,3156,2607, 949,1024,1733,1516,1803,1920,2125,2283,2665,3180, 1501,2064,3560,2171,1592, 803,3518,1416, 732,3897,4258,1363,1362,2458, 119,1427, 602,1525,2608,1605,1639,3175, 694,3064, 10, 465, 76,2000,4846,4208, 444,3781, 1619,3353,2206,1273,3796, 740,2483, 320,1723,2377,3660,2619,1359,1137,1762,1724, 2345,2842,1850,1862, 912, 821,1866, 612,2625,1735,2573,3369,1093, 844, 89, 937, 930,1424,3564,2413,2972,1004,3046,3019,2011, 711,3171,1452,4178, 428, 801,1943, 432, 445,2811, 206,4136,1472, 730, 349, 73, 397,2802,2547, 998,1637,1167, 789, 396,3217, 154,1218, 716,1120,1780,2819,4826,1931,3334,3762,2139,1215,2627, 552, 3664,3628,3232,1405,2383,3111,1356,2652,3577,3320,3101,1703, 640,1045,1370,1246, 4996, 371,1575,2436,1621,2210, 984,4033,1734,2638, 16,4529, 663,2755,3255,1451, 3917,2257,1253,1955,2234,1263,2951, 214,1229, 617, 485, 359,1831,1969, 473,2310, 750,2058, 165, 80,2864,2419, 361,4344,2416,2479,1134, 796,3726,1266,2943, 860, 2715, 938, 390,2734,1313,1384, 248, 202, 877,1064,2854, 522,3907, 279,1602, 297, 2357, 395,3740, 137,2075, 944,4089,2584,1267,3802, 62,1533,2285, 178, 176, 780, 2440, 201,3707, 590, 478,1560,4354,2117,1075, 30, 74,4643,4004,1635,1441,2745, 776,2596, 238,1077,1692,1912,2844, 605, 499,1742,3947, 241,3053, 980,1749, 936, 2640,4511,2582, 515,1543,2162,5322,2892,2993, 890,2148,1924, 665,1827,3581,1032, 968,3163, 339,1044,1896, 270, 583,1791,1720,4367,1194,3488,3669, 43,2523,1657, 163,2167, 290,1209,1622,3378, 550, 634,2508,2510, 695,2634,2384,2512,1476,1414, 220,1469,2341,2138,2852,3183,2900,4939,2865,3502,1211,3680, 854,3227,1299,2976, 3172, 186,2998,1459, 443,1067,3251,1495, 321,1932,3054, 909, 753,1410,1828, 436, 2441,1119,1587,3164,2186,1258, 227, 231,1425,1890,3200,3942, 247, 959, 725,5254, 2741, 577,2158,2079, 929, 120, 174, 838,2813, 591,1115, 417,2024, 40,3240,1536, 1037, 291,4151,2354, 632,1298,2406,2500,3535,1825,1846,3451, 205,1171, 345,4238, 18,1163, 811, 685,2208,1217, 425,1312,1508,1175,4308,2552,1033, 587,1381,3059, 2984,3482, 340,1316,4023,3972, 792,3176, 519, 777,4690, 918, 933,4130,2981,3741, 90,3360,2911,2200,5184,4550, 609,3079,2030, 272,3379,2736, 363,3881,1130,1447, 286, 779, 357,1169,3350,3137,1630,1220,2687,2391, 747,1277,3688,2618,2682,2601, 1156,3196,5290,4034,3102,1689,3596,3128, 874, 219,2783, 798, 508,1843,2461, 269, 1658,1776,1392,1913,2983,3287,2866,2159,2372, 829,4076, 46,4253,2873,1889,1894, 915,1834,1631,2181,2318, 298, 664,2818,3555,2735, 954,3228,3117, 527,3511,2173, 681,2712,3033,2247,2346,3467,1652, 155,2164,3382, 113,1994, 450, 899, 494, 994, 1237,2958,1875,2336,1926,3727, 545,1577,1550, 633,3473, 204,1305,3072,2410,1956, 2471, 707,2134, 841,2195,2196,2663,3843,1026,4940, 990,3252,4997, 368,1092, 437, 3212,3258,1933,1829, 675,2977,2893, 412, 943,3723,4644,3294,3283,2230,2373,5154, 2389,2241,2661,2323,1404,2524, 593, 787, 677,3008,1275,2059, 438,2709,2609,2240, 2269,2246,1446, 36,1568,1373,3892,1574,2301,1456,3962, 693,2276,5216,2035,1143, 2720,1919,1797,1811,2763,4137,2597,1830,1699,1488,1198,2090, 424,1694, 312,3634, 3390,4179,3335,2252,1214, 561,1059,3243,2295,2561, 975,5155,2321,2751,3772, 472, 1537,3282,3398,1047,2077,2348,2878,1323,3340,3076, 690,2906, 51, 369, 170,3541, 1060,2187,2688,3670,2541,1083,1683, 928,3918, 459, 109,4427, 599,3744,4286, 143, 2101,2730,2490, 82,1588,3036,2121, 281,1860, 477,4035,1238,2812,3020,2716,3312, 1530,2188,2055,1317, 843, 636,1808,1173,3495, 649, 181,1002, 147,3641,1159,2414, 3750,2289,2795, 813,3123,2610,1136,4368, 5,3391,4541,2174, 420, 429,1728, 754, 1228,2115,2219, 347,2223,2733, 735,1518,3003,2355,3134,1764,3948,3329,1888,2424, 1001,1234,1972,3321,3363,1672,1021,1450,1584, 226, 765, 655,2526,3404,3244,2302, 3665, 731, 594,2184, 319,1576, 621, 658,2656,4299,2099,3864,1279,2071,2598,2739, 795,3086,3699,3908,1707,2352,2402,1382,3136,2475,1465,4847,3496,3865,1085,3004, 2591,1084, 213,2287,1963,3565,2250, 822, 793,4574,3187,1772,1789,3050, 595,1484, 1959,2770,1080,2650, 456, 422,2996, 940,3322,4328,4345,3092,2742, 965,2784, 739, 4124, 952,1358,2498,2949,2565, 332,2698,2378, 660,2260,2473,4194,3856,2919, 535, 1260,2651,1208,1428,1300,1949,1303,2942, 433,2455,2450,1251,1946, 614,1269, 641, 1306,1810,2737,3078,2912, 564,2365,1419,1415,1497,4460,2367,2185,1379,3005,1307, 3218,2175,1897,3063, 682,1157,4040,4005,1712,1160,1941,1399, 394, 402,2952,1573, 1151,2986,2404, 862, 299,2033,1489,3006, 346, 171,2886,3401,1726,2932, 168,2533, 47,2507,1030,3735,1145,3370,1395,1318,1579,3609,4560,2857,4116,1457,2529,1965, 504,1036,2690,2988,2405, 745,5871, 849,2397,2056,3081, 863,2359,3857,2096, 99, 1397,1769,2300,4428,1643,3455,1978,1757,3718,1440, 35,4879,3742,1296,4228,2280, 160,5063,1599,2013, 166, 520,3479,1646,3345,3012, 490,1937,1545,1264,2182,2505, 1096,1188,1369,1436,2421,1667,2792,2460,1270,2122, 727,3167,2143, 806,1706,1012, 1800,3037, 960,2218,1882, 805, 139,2456,1139,1521, 851,1052,3093,3089, 342,2039, 744,5097,1468,1502,1585,2087, 223, 939, 326,2140,2577, 892,2481,1623,4077, 982, 3708, 135,2131, 87,2503,3114,2326,1106, 876,1616, 547,2997,2831,2093,3441,4530, 4314, 9,3256,4229,4148, 659,1462,1986,1710,2046,2913,2231,4090,4880,5255,3392, 3274,1368,3689,4645,1477, 705,3384,3635,1068,1529,2941,1458,3782,1509, 100,1656, 2548, 718,2339, 408,1590,2780,3548,1838,4117,3719,1345,3530, 717,3442,2778,3220, 2898,1892,4590,3614,3371,2043,1998,1224,3483, 891, 635, 584,2559,3355, 733,1766, 1729,1172,3789,1891,2307, 781,2982,2271,1957,1580,5773,2633,2005,4195,3097,1535, 3213,1189,1934,5693,3262, 586,3118,1324,1598, 517,1564,2217,1868,1893,4445,3728, 2703,3139,1526,1787,1992,3882,2875,1549,1199,1056,2224,1904,2711,5098,4287, 338, 1993,3129,3489,2689,1809,2815,1997, 957,1855,3898,2550,3275,3057,1105,1319, 627, 1505,1911,1883,3526, 698,3629,3456,1833,1431, 746, 77,1261,2017,2296,1977,1885, 125,1334,1600, 525,1798,1109,2222,1470,1945, 559,2236,1186,3443,2476,1929,1411, 2411,3135,1777,3372,2621,1841,1613,3229, 668,1430,1839,2643,2916, 195,1989,2671, 2358,1387, 629,3205,2293,5256,4439, 123,1310, 888,1879,4300,3021,3605,1003,1162, 3192,2910,2010, 140,2395,2859, 55,1082,2012,2901, 662, 419,2081,1438, 680,2774, 4654,3912,1620,1731,1625,5035,4065,2328, 512,1344, 802,5443,2163,2311,2537, 524, 3399, 98,1155,2103,1918,2606,3925,2816,1393,2465,1504,3773,2177,3963,1478,4346, 180,1113,4655,3461,2028,1698, 833,2696,1235,1322,1594,4408,3623,3013,3225,2040, 3022, 541,2881, 607,3632,2029,1665,1219, 639,1385,1686,1099,2803,3231,1938,3188, 2858, 427, 676,2772,1168,2025, 454,3253,2486,3556, 230,1950, 580, 791,1991,1280, 1086,1974,2034, 630, 257,3338,2788,4903,1017, 86,4790, 966,2789,1995,1696,1131, 259,3095,4188,1308, 179,1463,5257, 289,4107,1248, 42,3413,1725,2288, 896,1947, 774,4474,4254, 604,3430,4264, 392,2514,2588, 452, 237,1408,3018, 988,4531,1970, 3034,3310, 540,2370,1562,1288,2990, 502,4765,1147, 4,1853,2708, 207, 294,2814, 4078,2902,2509, 684, 34,3105,3532,2551, 644, 709,2801,2344, 573,1727,3573,3557, 2021,1081,3100,4315,2100,3681, 199,2263,1837,2385, 146,3484,1195,2776,3949, 997, 1939,3973,1008,1091,1202,1962,1847,1149,4209,5444,1076, 493, 117,5400,2521, 972, 1490,2934,1796,4542,2374,1512,2933,2657, 413,2888,1135,2762,2314,2156,1355,2369, 766,2007,2527,2170,3124,2491,2593,2632,4757,2437, 234,3125,3591,1898,1750,1376, 1942,3468,3138, 570,2127,2145,3276,4131, 962, 132,1445,4196, 19, 941,3624,3480, 3366,1973,1374,4461,3431,2629, 283,2415,2275, 808,2887,3620,2112,2563,1353,3610, 955,1089,3103,1053, 96, 88,4097, 823,3808,1583, 399, 292,4091,3313, 421,1128, 642,4006, 903,2539,1877,2082, 596, 29,4066,1790, 722,2157, 130, 995,1569, 769, 1485, 464, 513,2213, 288,1923,1101,2453,4316, 133, 486,2445, 50, 625, 487,2207, 57, 423, 481,2962, 159,3729,1558, 491, 303, 482, 501, 240,2837, 112,3648,2392, 1783, 362, 8,3433,3422, 610,2793,3277,1390,1284,1654, 21,3823, 734, 367, 623, 193, 287, 374,1009,1483, 816, 476, 313,2255,2340,1262,2150,2899,1146,2581, 782, 2116,1659,2018,1880, 255,3586,3314,1110,2867,2137,2564, 986,2767,5185,2006, 650, 158, 926, 762, 881,3157,2717,2362,3587, 306,3690,3245,1542,3077,2427,1691,2478, 2118,2985,3490,2438, 539,2305, 983, 129,1754, 355,4201,2386, 827,2923, 104,1773, 2838,2771, 411,2905,3919, 376, 767, 122,1114, 828,2422,1817,3506, 266,3460,1007, 1609,4998, 945,2612,4429,2274, 726,1247,1964,2914,2199,2070,4002,4108, 657,3323, 1422, 579, 455,2764,4737,1222,2895,1670, 824,1223,1487,2525, 558, 861,3080, 598, 2659,2515,1967, 752,2583,2376,2214,4180, 977, 704,2464,4999,2622,4109,1210,2961, 819,1541, 142,2284, 44, 418, 457,1126,3730,4347,4626,1644,1876,3671,1864, 302, 1063,5694, 624, 723,1984,3745,1314,1676,2488,1610,1449,3558,3569,2166,2098, 409, 1011,2325,3704,2306, 818,1732,1383,1824,1844,3757, 999,2705,3497,1216,1423,2683, 2426,2954,2501,2726,2229,1475,2554,5064,1971,1794,1666,2014,1343, 783, 724, 191, 2434,1354,2220,5065,1763,2752,2472,4152, 131, 175,2885,3434, 92,1466,4920,2616, 3871,3872,3866, 128,1551,1632, 669,1854,3682,4691,4125,1230, 188,2973,3290,1302, 1213, 560,3266, 917, 763,3909,3249,1760, 868,1958, 764,1782,2097, 145,2277,3774, 4462, 64,1491,3062, 971,2132,3606,2442, 221,1226,1617, 218, 323,1185,3207,3147, 571, 619,1473,1005,1744,2281, 449,1887,2396,3685, 275, 375,3816,1743,3844,3731, 845,1983,2350,4210,1377, 773, 967,3499,3052,3743,2725,4007,1697,1022,3943,1464, 3264,2855,2722,1952,1029,2839,2467, 84,4383,2215, 820,1391,2015,2448,3672, 377, 1948,2168, 797,2545,3536,2578,2645, 94,2874,1678, 405,1259,3071, 771, 546,1315, 470,1243,3083, 895,2468, 981, 969,2037, 846,4181, 653,1276,2928, 14,2594, 557, 3007,2474, 156, 902,1338,1740,2574, 537,2518, 973,2282,2216,2433,1928, 138,2903, 1293,2631,1612, 646,3457, 839,2935, 111, 496,2191,2847, 589,3186, 149,3994,2060, 4031,2641,4067,3145,1870, 37,3597,2136,1025,2051,3009,3383,3549,1121,1016,3261, 1301, 251,2446,2599,2153, 872,3246, 637, 334,3705, 831, 884, 921,3065,3140,4092, 2198,1944, 246,2964, 108,2045,1152,1921,2308,1031, 203,3173,4170,1907,3890, 810, 1401,2003,1690, 506, 647,1242,2828,1761,1649,3208,2249,1589,3709,2931,5156,1708, 498, 666,2613, 834,3817,1231, 184,2851,1124, 883,3197,2261,3710,1765,1553,2658, 1178,2639,2351, 93,1193, 942,2538,2141,4402, 235,1821, 870,1591,2192,1709,1871, 3341,1618,4126,2595,2334, 603, 651, 69, 701, 268,2662,3411,2555,1380,1606, 503, 448, 254,2371,2646, 574,1187,2309,1770, 322,2235,1292,1801, 305, 566,1133, 229, 2067,2057, 706, 167, 483,2002,2672,3295,1820,3561,3067, 316, 378,2746,3452,1112, 136,1981, 507,1651,2917,1117, 285,4591, 182,2580,3522,1304, 335,3303,1835,2504, 1795,1792,2248, 674,1018,2106,2449,1857,2292,2845, 976,3047,1781,2600,2727,1389, 1281, 52,3152, 153, 265,3950, 672,3485,3951,4463, 430,1183, 365, 278,2169, 27, 1407,1336,2304, 209,1340,1730,2202,1852,2403,2883, 979,1737,1062, 631,2829,2542, 3876,2592, 825,2086,2226,3048,3625, 352,1417,3724, 542, 991, 431,1351,3938,1861, 2294, 826,1361,2927,3142,3503,1738, 463,2462,2723, 582,1916,1595,2808, 400,3845, 3891,2868,3621,2254, 58,2492,1123, 910,2160,2614,1372,1603,1196,1072,3385,1700, 3267,1980, 696, 480,2430, 920, 799,1570,2920,1951,2041,4047,2540,1321,4223,2469, 3562,2228,1271,2602, 401,2833,3351,2575,5157, 907,2312,1256, 410, 263,3507,1582, 996, 678,1849,2316,1480, 908,3545,2237, 703,2322, 667,1826,2849,1531,2604,2999, 2407,3146,2151,2630,1786,3711, 469,3542, 497,3899,2409, 858, 837,4446,3393,1274, 786, 620,1845,2001,3311, 484, 308,3367,1204,1815,3691,2332,1532,2557,1842,2020, 2724,1927,2333,4440, 567, 22,1673,2728,4475,1987,1858,1144,1597, 101,1832,3601, 12, 974,3783,4391, 951,1412, 1,3720, 453,4608,4041, 528,1041,1027,3230,2628, 1129, 875,1051,3291,1203,2262,1069,2860,2799,2149,2615,3278, 144,1758,3040, 31, 475,1680, 366,2685,3184, 311,1642,4008,2466,5036,1593,1493,2809, 216,1420,1668, 233, 304,2128,3284, 232,1429,1768,1040,2008,3407,2740,2967,2543, 242,2133, 778, 1565,2022,2620, 505,2189,2756,1098,2273, 372,1614, 708, 553,2846,2094,2278, 169, 3626,2835,4161, 228,2674,3165, 809,1454,1309, 466,1705,1095, 900,3423, 880,2667, 3751,5258,2317,3109,2571,4317,2766,1503,1342, 866,4447,1118, 63,2076, 314,1881, 1348,1061, 172, 978,3515,1747, 532, 511,3970, 6, 601, 905,2699,3300,1751, 276, 1467,3725,2668, 65,4239,2544,2779,2556,1604, 578,2451,1802, 992,2331,2624,1320, 3446, 713,1513,1013, 103,2786,2447,1661, 886,1702, 916, 654,3574,2031,1556, 751, 2178,2821,2179,1498,1538,2176, 271, 914,2251,2080,1325, 638,1953,2937,3877,2432, 2754, 95,3265,1716, 260,1227,4083, 775, 106,1357,3254, 426,1607, 555,2480, 772, 1985, 244,2546, 474, 495,1046,2611,1851,2061, 71,2089,1675,2590, 742,3758,2843, 3222,1433, 267,2180,2576,2826,2233,2092,3913,2435, 956,1745,3075, 856,2113,1116, 451, 3,1988,2896,1398, 993,2463,1878,2049,1341,2718,2721,2870,2108, 712,2904, 4363,2753,2324, 277,2872,2349,2649, 384, 987, 435, 691,3000, 922, 164,3939, 652, 1500,1184,4153,2482,3373,2165,4848,2335,3775,3508,3154,2806,2830,1554,2102,1664, 2530,1434,2408, 893,1547,2623,3447,2832,2242,2532,3169,2856,3223,2078, 49,3770, 3469, 462, 318, 656,2259,3250,3069, 679,1629,2758, 344,1138,1104,3120,1836,1283, 3115,2154,1437,4448, 934, 759,1999, 794,2862,1038, 533,2560,1722,2342, 855,2626, 1197,1663,4476,3127, 85,4240,2528, 25,1111,1181,3673, 407,3470,4561,2679,2713, 768,1925,2841,3986,1544,1165, 932, 373,1240,2146,1930,2673, 721,4766, 354,4333, 391,2963, 187, 61,3364,1442,1102, 330,1940,1767, 341,3809,4118, 393,2496,2062, 2211, 105, 331, 300, 439, 913,1332, 626, 379,3304,1557, 328, 689,3952, 309,1555, 931, 317,2517,3027, 325, 569, 686,2107,3084, 60,1042,1333,2794, 264,3177,4014, 1628, 258,3712, 7,4464,1176,1043,1778, 683, 114,1975, 78,1492, 383,1886, 510, 386, 645,5291,2891,2069,3305,4138,3867,2939,2603,2493,1935,1066,1848,3588,1015, 1282,1289,4609, 697,1453,3044,2666,3611,1856,2412, 54, 719,1330, 568,3778,2459, 1748, 788, 492, 551,1191,1000, 488,3394,3763, 282,1799, 348,2016,1523,3155,2390, 1049, 382,2019,1788,1170, 729,2968,3523, 897,3926,2785,2938,3292, 350,2319,3238, 1718,1717,2655,3453,3143,4465, 161,2889,2980,2009,1421, 56,1908,1640,2387,2232, 1917,1874,2477,4921, 148, 83,3438, 592,4245,2882,1822,1055, 741, 115,1496,1624, 381,1638,4592,1020, 516,3214, 458, 947,4575,1432, 211,1514,2926,1865,2142, 189, 852,1221,1400,1486, 882,2299,4036, 351, 28,1122, 700,6479,6480,6481,6482,6483, //last 512 -/*************************************************************************************** +/*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 5508,6484,3900,3414,3974,4441,4024,3537,4037,5628,5099,3633,6485,3148,6486,3636, 5509,3257,5510,5973,5445,5872,4941,4403,3174,4627,5873,6276,2286,4230,5446,5874, 5122,6102,6103,4162,5447,5123,5323,4849,6277,3980,3851,5066,4246,5774,5067,6278, 3001,2807,5695,3346,5775,5974,5158,5448,6487,5975,5976,5776,3598,6279,5696,4806, 4211,4154,6280,6488,6489,6490,6281,4212,5037,3374,4171,6491,4562,4807,4722,4827, 5977,6104,4532,4079,5159,5324,5160,4404,3858,5359,5875,3975,4288,4610,3486,4512, 5325,3893,5360,6282,6283,5560,2522,4231,5978,5186,5449,2569,3878,6284,5401,3578, 4415,6285,4656,5124,5979,2506,4247,4449,3219,3417,4334,4969,4329,6492,4576,4828, 4172,4416,4829,5402,6286,3927,3852,5361,4369,4830,4477,4867,5876,4173,6493,6105, 4657,6287,6106,5877,5450,6494,4155,4868,5451,3700,5629,4384,6288,6289,5878,3189, 4881,6107,6290,6495,4513,6496,4692,4515,4723,5100,3356,6497,6291,3810,4080,5561, 3570,4430,5980,6498,4355,5697,6499,4724,6108,6109,3764,4050,5038,5879,4093,3226, 6292,5068,5217,4693,3342,5630,3504,4831,4377,4466,4309,5698,4431,5777,6293,5778, 4272,3706,6110,5326,3752,4676,5327,4273,5403,4767,5631,6500,5699,5880,3475,5039, 6294,5562,5125,4348,4301,4482,4068,5126,4593,5700,3380,3462,5981,5563,3824,5404, 4970,5511,3825,4738,6295,6501,5452,4516,6111,5881,5564,6502,6296,5982,6503,4213, 4163,3454,6504,6112,4009,4450,6113,4658,6297,6114,3035,6505,6115,3995,4904,4739, 4563,4942,4110,5040,3661,3928,5362,3674,6506,5292,3612,4791,5565,4149,5983,5328, 5259,5021,4725,4577,4564,4517,4364,6298,5405,4578,5260,4594,4156,4157,5453,3592, 3491,6507,5127,5512,4709,4922,5984,5701,4726,4289,6508,4015,6116,5128,4628,3424, 4241,5779,6299,4905,6509,6510,5454,5702,5780,6300,4365,4923,3971,6511,5161,3270, 3158,5985,4100, 867,5129,5703,6117,5363,3695,3301,5513,4467,6118,6512,5455,4232, 4242,4629,6513,3959,4478,6514,5514,5329,5986,4850,5162,5566,3846,4694,6119,5456, 4869,5781,3779,6301,5704,5987,5515,4710,6302,5882,6120,4392,5364,5705,6515,6121, 6516,6517,3736,5988,5457,5989,4695,2457,5883,4551,5782,6303,6304,6305,5130,4971, 6122,5163,6123,4870,3263,5365,3150,4871,6518,6306,5783,5069,5706,3513,3498,4409, 5330,5632,5366,5458,5459,3991,5990,4502,3324,5991,5784,3696,4518,5633,4119,6519, 4630,5634,4417,5707,4832,5992,3418,6124,5993,5567,4768,5218,6520,4595,3458,5367, 6125,5635,6126,4202,6521,4740,4924,6307,3981,4069,4385,6308,3883,2675,4051,3834, 4302,4483,5568,5994,4972,4101,5368,6309,5164,5884,3922,6127,6522,6523,5261,5460, 5187,4164,5219,3538,5516,4111,3524,5995,6310,6311,5369,3181,3386,2484,5188,3464, 5569,3627,5708,6524,5406,5165,4677,4492,6312,4872,4851,5885,4468,5996,6313,5709, 5710,6128,2470,5886,6314,5293,4882,5785,3325,5461,5101,6129,5711,5786,6525,4906, 6526,6527,4418,5887,5712,4808,2907,3701,5713,5888,6528,3765,5636,5331,6529,6530, 3593,5889,3637,4943,3692,5714,5787,4925,6315,6130,5462,4405,6131,6132,6316,5262, 6531,6532,5715,3859,5716,5070,4696,5102,3929,5788,3987,4792,5997,6533,6534,3920, 4809,5000,5998,6535,2974,5370,6317,5189,5263,5717,3826,6536,3953,5001,4883,3190, 5463,5890,4973,5999,4741,6133,6134,3607,5570,6000,4711,3362,3630,4552,5041,6318, 6001,2950,2953,5637,4646,5371,4944,6002,2044,4120,3429,6319,6537,5103,4833,6538, 6539,4884,4647,3884,6003,6004,4758,3835,5220,5789,4565,5407,6540,6135,5294,4697, 4852,6320,6321,3206,4907,6541,6322,4945,6542,6136,6543,6323,6005,4631,3519,6544, 5891,6545,5464,3784,5221,6546,5571,4659,6547,6324,6137,5190,6548,3853,6549,4016, 4834,3954,6138,5332,3827,4017,3210,3546,4469,5408,5718,3505,4648,5790,5131,5638, 5791,5465,4727,4318,6325,6326,5792,4553,4010,4698,3439,4974,3638,4335,3085,6006, 5104,5042,5166,5892,5572,6327,4356,4519,5222,5573,5333,5793,5043,6550,5639,5071, 4503,6328,6139,6551,6140,3914,3901,5372,6007,5640,4728,4793,3976,3836,4885,6552, 4127,6553,4451,4102,5002,6554,3686,5105,6555,5191,5072,5295,4611,5794,5296,6556, 5893,5264,5894,4975,5466,5265,4699,4976,4370,4056,3492,5044,4886,6557,5795,4432, 4769,4357,5467,3940,4660,4290,6141,4484,4770,4661,3992,6329,4025,4662,5022,4632, 4835,4070,5297,4663,4596,5574,5132,5409,5895,6142,4504,5192,4664,5796,5896,3885, 5575,5797,5023,4810,5798,3732,5223,4712,5298,4084,5334,5468,6143,4052,4053,4336, 4977,4794,6558,5335,4908,5576,5224,4233,5024,4128,5469,5225,4873,6008,5045,4729, 4742,4633,3675,4597,6559,5897,5133,5577,5003,5641,5719,6330,6560,3017,2382,3854, 4406,4811,6331,4393,3964,4946,6561,2420,3722,6562,4926,4378,3247,1736,4442,6332, 5134,6333,5226,3996,2918,5470,4319,4003,4598,4743,4744,4485,3785,3902,5167,5004, 5373,4394,5898,6144,4874,1793,3997,6334,4085,4214,5106,5642,4909,5799,6009,4419, 4189,3330,5899,4165,4420,5299,5720,5227,3347,6145,4081,6335,2876,3930,6146,3293, 3786,3910,3998,5900,5300,5578,2840,6563,5901,5579,6147,3531,5374,6564,6565,5580, 4759,5375,6566,6148,3559,5643,6336,6010,5517,6337,6338,5721,5902,3873,6011,6339, 6567,5518,3868,3649,5722,6568,4771,4947,6569,6149,4812,6570,2853,5471,6340,6341, 5644,4795,6342,6012,5723,6343,5724,6013,4349,6344,3160,6150,5193,4599,4514,4493, 5168,4320,6345,4927,3666,4745,5169,5903,5005,4928,6346,5725,6014,4730,4203,5046, 4948,3395,5170,6015,4150,6016,5726,5519,6347,5047,3550,6151,6348,4197,4310,5904, 6571,5581,2965,6152,4978,3960,4291,5135,6572,5301,5727,4129,4026,5905,4853,5728, 5472,6153,6349,4533,2700,4505,5336,4678,3583,5073,2994,4486,3043,4554,5520,6350, 6017,5800,4487,6351,3931,4103,5376,6352,4011,4321,4311,4190,5136,6018,3988,3233, 4350,5906,5645,4198,6573,5107,3432,4191,3435,5582,6574,4139,5410,6353,5411,3944, 5583,5074,3198,6575,6354,4358,6576,5302,4600,5584,5194,5412,6577,6578,5585,5413, 5303,4248,5414,3879,4433,6579,4479,5025,4854,5415,6355,4760,4772,3683,2978,4700, 3797,4452,3965,3932,3721,4910,5801,6580,5195,3551,5907,3221,3471,3029,6019,3999, 5908,5909,5266,5267,3444,3023,3828,3170,4796,5646,4979,4259,6356,5647,5337,3694, 6357,5648,5338,4520,4322,5802,3031,3759,4071,6020,5586,4836,4386,5048,6581,3571, 4679,4174,4949,6154,4813,3787,3402,3822,3958,3215,3552,5268,4387,3933,4950,4359, 6021,5910,5075,3579,6358,4234,4566,5521,6359,3613,5049,6022,5911,3375,3702,3178, 4911,5339,4521,6582,6583,4395,3087,3811,5377,6023,6360,6155,4027,5171,5649,4421, 4249,2804,6584,2270,6585,4000,4235,3045,6156,5137,5729,4140,4312,3886,6361,4330, 6157,4215,6158,3500,3676,4929,4331,3713,4930,5912,4265,3776,3368,5587,4470,4855, 3038,4980,3631,6159,6160,4132,4680,6161,6362,3923,4379,5588,4255,6586,4121,6587, 6363,4649,6364,3288,4773,4774,6162,6024,6365,3543,6588,4274,3107,3737,5050,5803, 4797,4522,5589,5051,5730,3714,4887,5378,4001,4523,6163,5026,5522,4701,4175,2791, 3760,6589,5473,4224,4133,3847,4814,4815,4775,3259,5416,6590,2738,6164,6025,5304, 3733,5076,5650,4816,5590,6591,6165,6592,3934,5269,6593,3396,5340,6594,5804,3445, 3602,4042,4488,5731,5732,3525,5591,4601,5196,6166,6026,5172,3642,4612,3202,4506, 4798,6366,3818,5108,4303,5138,5139,4776,3332,4304,2915,3415,4434,5077,5109,4856, 2879,5305,4817,6595,5913,3104,3144,3903,4634,5341,3133,5110,5651,5805,6167,4057, 5592,2945,4371,5593,6596,3474,4182,6367,6597,6168,4507,4279,6598,2822,6599,4777, 4713,5594,3829,6169,3887,5417,6170,3653,5474,6368,4216,2971,5228,3790,4579,6369, 5733,6600,6601,4951,4746,4555,6602,5418,5475,6027,3400,4665,5806,6171,4799,6028, 5052,6172,3343,4800,4747,5006,6370,4556,4217,5476,4396,5229,5379,5477,3839,5914, 5652,5807,4714,3068,4635,5808,6173,5342,4192,5078,5419,5523,5734,6174,4557,6175, 4602,6371,6176,6603,5809,6372,5735,4260,3869,5111,5230,6029,5112,6177,3126,4681, 5524,5915,2706,3563,4748,3130,6178,4018,5525,6604,6605,5478,4012,4837,6606,4534, 4193,5810,4857,3615,5479,6030,4082,3697,3539,4086,5270,3662,4508,4931,5916,4912, 5811,5027,3888,6607,4397,3527,3302,3798,2775,2921,2637,3966,4122,4388,4028,4054, 1633,4858,5079,3024,5007,3982,3412,5736,6608,3426,3236,5595,3030,6179,3427,3336, 3279,3110,6373,3874,3039,5080,5917,5140,4489,3119,6374,5812,3405,4494,6031,4666, 4141,6180,4166,6032,5813,4981,6609,5081,4422,4982,4112,3915,5653,3296,3983,6375, 4266,4410,5654,6610,6181,3436,5082,6611,5380,6033,3819,5596,4535,5231,5306,5113, 6612,4952,5918,4275,3113,6613,6376,6182,6183,5814,3073,4731,4838,5008,3831,6614, 4888,3090,3848,4280,5526,5232,3014,5655,5009,5737,5420,5527,6615,5815,5343,5173, 5381,4818,6616,3151,4953,6617,5738,2796,3204,4360,2989,4281,5739,5174,5421,5197, 3132,5141,3849,5142,5528,5083,3799,3904,4839,5480,2880,4495,3448,6377,6184,5271, 5919,3771,3193,6034,6035,5920,5010,6036,5597,6037,6378,6038,3106,5422,6618,5423, 5424,4142,6619,4889,5084,4890,4313,5740,6620,3437,5175,5307,5816,4199,5198,5529, 5817,5199,5656,4913,5028,5344,3850,6185,2955,5272,5011,5818,4567,4580,5029,5921, 3616,5233,6621,6622,6186,4176,6039,6379,6380,3352,5200,5273,2908,5598,5234,3837, 5308,6623,6624,5819,4496,4323,5309,5201,6625,6626,4983,3194,3838,4167,5530,5922, 5274,6381,6382,3860,3861,5599,3333,4292,4509,6383,3553,5481,5820,5531,4778,6187, 3955,3956,4324,4389,4218,3945,4325,3397,2681,5923,4779,5085,4019,5482,4891,5382, 5383,6040,4682,3425,5275,4094,6627,5310,3015,5483,5657,4398,5924,3168,4819,6628, 5925,6629,5532,4932,4613,6041,6630,4636,6384,4780,4204,5658,4423,5821,3989,4683, 5822,6385,4954,6631,5345,6188,5425,5012,5384,3894,6386,4490,4104,6632,5741,5053, 6633,5823,5926,5659,5660,5927,6634,5235,5742,5824,4840,4933,4820,6387,4859,5928, 4955,6388,4143,3584,5825,5346,5013,6635,5661,6389,5014,5484,5743,4337,5176,5662, 6390,2836,6391,3268,6392,6636,6042,5236,6637,4158,6638,5744,5663,4471,5347,3663, 4123,5143,4293,3895,6639,6640,5311,5929,5826,3800,6189,6393,6190,5664,5348,3554, 3594,4749,4603,6641,5385,4801,6043,5827,4183,6642,5312,5426,4761,6394,5665,6191, 4715,2669,6643,6644,5533,3185,5427,5086,5930,5931,5386,6192,6044,6645,4781,4013, 5745,4282,4435,5534,4390,4267,6045,5746,4984,6046,2743,6193,3501,4087,5485,5932, 5428,4184,4095,5747,4061,5054,3058,3862,5933,5600,6646,5144,3618,6395,3131,5055, 5313,6396,4650,4956,3855,6194,3896,5202,4985,4029,4225,6195,6647,5828,5486,5829, 3589,3002,6648,6397,4782,5276,6649,6196,6650,4105,3803,4043,5237,5830,6398,4096, 3643,6399,3528,6651,4453,3315,4637,6652,3984,6197,5535,3182,3339,6653,3096,2660, 6400,6654,3449,5934,4250,4236,6047,6401,5831,6655,5487,3753,4062,5832,6198,6199, 6656,3766,6657,3403,4667,6048,6658,4338,2897,5833,3880,2797,3780,4326,6659,5748, 5015,6660,5387,4351,5601,4411,6661,3654,4424,5935,4339,4072,5277,4568,5536,6402, 6662,5238,6663,5349,5203,6200,5204,6201,5145,4536,5016,5056,4762,5834,4399,4957, 6202,6403,5666,5749,6664,4340,6665,5936,5177,5667,6666,6667,3459,4668,6404,6668, 6669,4543,6203,6670,4276,6405,4480,5537,6671,4614,5205,5668,6672,3348,2193,4763, 6406,6204,5937,5602,4177,5669,3419,6673,4020,6205,4443,4569,5388,3715,3639,6407, 6049,4058,6206,6674,5938,4544,6050,4185,4294,4841,4651,4615,5488,6207,6408,6051, 5178,3241,3509,5835,6208,4958,5836,4341,5489,5278,6209,2823,5538,5350,5206,5429, 6675,4638,4875,4073,3516,4684,4914,4860,5939,5603,5389,6052,5057,3237,5490,3791, 6676,6409,6677,4821,4915,4106,5351,5058,4243,5539,4244,5604,4842,4916,5239,3028, 3716,5837,5114,5605,5390,5940,5430,6210,4332,6678,5540,4732,3667,3840,6053,4305, 3408,5670,5541,6410,2744,5240,5750,6679,3234,5606,6680,5607,5671,3608,4283,4159, 4400,5352,4783,6681,6411,6682,4491,4802,6211,6412,5941,6413,6414,5542,5751,6683, 4669,3734,5942,6684,6415,5943,5059,3328,4670,4144,4268,6685,6686,6687,6688,4372, 3603,6689,5944,5491,4373,3440,6416,5543,4784,4822,5608,3792,4616,5838,5672,3514, 5391,6417,4892,6690,4639,6691,6054,5673,5839,6055,6692,6056,5392,6212,4038,5544, 5674,4497,6057,6693,5840,4284,5675,4021,4545,5609,6418,4454,6419,6213,4113,4472, 5314,3738,5087,5279,4074,5610,4959,4063,3179,4750,6058,6420,6214,3476,4498,4716, 5431,4960,4685,6215,5241,6694,6421,6216,6695,5841,5945,6422,3748,5946,5179,3905, 5752,5545,5947,4374,6217,4455,6423,4412,6218,4803,5353,6696,3832,5280,6219,4327, 4702,6220,6221,6059,4652,5432,6424,3749,4751,6425,5753,4986,5393,4917,5948,5030, 5754,4861,4733,6426,4703,6697,6222,4671,5949,4546,4961,5180,6223,5031,3316,5281, 6698,4862,4295,4934,5207,3644,6427,5842,5950,6428,6429,4570,5843,5282,6430,6224, 5088,3239,6060,6699,5844,5755,6061,6431,2701,5546,6432,5115,5676,4039,3993,3327, 4752,4425,5315,6433,3941,6434,5677,4617,4604,3074,4581,6225,5433,6435,6226,6062, 4823,5756,5116,6227,3717,5678,4717,5845,6436,5679,5846,6063,5847,6064,3977,3354, 6437,3863,5117,6228,5547,5394,4499,4524,6229,4605,6230,4306,4500,6700,5951,6065, 3693,5952,5089,4366,4918,6701,6231,5548,6232,6702,6438,4704,5434,6703,6704,5953, 4168,6705,5680,3420,6706,5242,4407,6066,3812,5757,5090,5954,4672,4525,3481,5681, 4618,5395,5354,5316,5955,6439,4962,6707,4526,6440,3465,4673,6067,6441,5682,6708, 5435,5492,5758,5683,4619,4571,4674,4804,4893,4686,5493,4753,6233,6068,4269,6442, 6234,5032,4705,5146,5243,5208,5848,6235,6443,4963,5033,4640,4226,6236,5849,3387, 6444,6445,4436,4437,5850,4843,5494,4785,4894,6709,4361,6710,5091,5956,3331,6237, 4987,5549,6069,6711,4342,3517,4473,5317,6070,6712,6071,4706,6446,5017,5355,6713, 6714,4988,5436,6447,4734,5759,6715,4735,4547,4456,4754,6448,5851,6449,6450,3547, 5852,5318,6451,6452,5092,4205,6716,6238,4620,4219,5611,6239,6072,4481,5760,5957, 5958,4059,6240,6453,4227,4537,6241,5761,4030,4186,5244,5209,3761,4457,4876,3337, 5495,5181,6242,5959,5319,5612,5684,5853,3493,5854,6073,4169,5613,5147,4895,6074, 5210,6717,5182,6718,3830,6243,2798,3841,6075,6244,5855,5614,3604,4606,5496,5685, 5118,5356,6719,6454,5960,5357,5961,6720,4145,3935,4621,5119,5962,4261,6721,6455, 4786,5963,4375,4582,6245,6246,6247,6076,5437,4877,5856,3376,4380,6248,4160,6722, 5148,6456,5211,6457,6723,4718,6458,6724,6249,5358,4044,3297,6459,6250,5857,5615, 5497,5245,6460,5498,6725,6251,6252,5550,3793,5499,2959,5396,6461,6462,4572,5093, 5500,5964,3806,4146,6463,4426,5762,5858,6077,6253,4755,3967,4220,5965,6254,4989, 5501,6464,4352,6726,6078,4764,2290,5246,3906,5438,5283,3767,4964,2861,5763,5094, 6255,6256,4622,5616,5859,5860,4707,6727,4285,4708,4824,5617,6257,5551,4787,5212, 4965,4935,4687,6465,6728,6466,5686,6079,3494,4413,2995,5247,5966,5618,6729,5967, 5764,5765,5687,5502,6730,6731,6080,5397,6467,4990,6258,6732,4538,5060,5619,6733, 4719,5688,5439,5018,5149,5284,5503,6734,6081,4607,6259,5120,3645,5861,4583,6260, 4584,4675,5620,4098,5440,6261,4863,2379,3306,4585,5552,5689,4586,5285,6735,4864, 6736,5286,6082,6737,4623,3010,4788,4381,4558,5621,4587,4896,3698,3161,5248,4353, 4045,6262,3754,5183,4588,6738,6263,6739,6740,5622,3936,6741,6468,6742,6264,5095, 6469,4991,5968,6743,4992,6744,6083,4897,6745,4256,5766,4307,3108,3968,4444,5287, 3889,4343,6084,4510,6085,4559,6086,4898,5969,6746,5623,5061,4919,5249,5250,5504, 5441,6265,5320,4878,3242,5862,5251,3428,6087,6747,4237,5624,5442,6266,5553,4539, 6748,2585,3533,5398,4262,6088,5150,4736,4438,6089,6267,5505,4966,6749,6268,6750, 6269,5288,5554,3650,6090,6091,4624,6092,5690,6751,5863,4270,5691,4277,5555,5864, 6752,5692,4720,4865,6470,5151,4688,4825,6753,3094,6754,6471,3235,4653,6755,5213, 5399,6756,3201,4589,5865,4967,6472,5866,6473,5019,3016,6757,5321,4756,3957,4573, 6093,4993,5767,4721,6474,6758,5625,6759,4458,6475,6270,6760,5556,4994,5214,5252, 6271,3875,5768,6094,5034,5506,4376,5769,6761,2120,6476,5253,5770,6762,5771,5970, 3990,5971,5557,5558,5772,6477,6095,2787,4641,5972,5121,6096,6097,6272,6763,3703, 5867,5507,6273,4206,6274,4789,6098,6764,3619,3646,3833,3804,2394,3788,4936,3978, 4866,4899,6099,6100,5559,6478,6765,3599,5868,6101,5869,5870,6275,6766,4527,6767, *******************************************************************************/ }; diff --git a/src/probers/tables/JISFreq.tab b/src/probers/tables/JISFreq.tab index 60242d5..76112f7 100644 --- a/src/probers/tables/JISFreq.tab +++ b/src/probers/tables/JISFreq.tab @@ -1,577 +1,559 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* -*- C++ -*- -* Copyright (C) 1998 -* -* -* 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. + SPDX-FileCopyrightText: 1998 + + SPDX-License-Identifier: MIT */ //Sampling from about 20M text materials include literature and computer technology // Japanese frequency table, applied to both S-JIS and EUC-JP -//They are sorted in order. +//They are sorted in order. /****************************************************************************** * 128 --> 0.77094 * 256 --> 0.85710 * 512 --> 0.92635 * 1024 --> 0.97130 * 2048 --> 0.99431 * * Idea Distribution Ratio = 0.92635 / (1-0.92635) = 12.58 * Random Distribution Ration = 512 / (2965+62+83+86-512) = 0.191 - * - * Typical Distribution Ratio, 25% of IDR + * + * Typical Distribution Ratio, 25% of IDR *****************************************************************************/ #define JIS_TYPICAL_DISTRIBUTION_RATIO (float) 3.0 -//Char to FreqOrder table , +//Char to FreqOrder table , #define JIS_TABLE_SIZE 4368 static const short JISCharToFreqOrder[] = { 40, 1, 6, 182, 152, 180, 295,2127, 285, 381,3295,4304,3068,4606,3165,3510, // 16 3511,1822,2785,4607,1193,2226,5070,4608, 171,2996,1247, 18, 179,5071, 856,1661, // 32 1262,5072, 619, 127,3431,3512,3230,1899,1700, 232, 228,1294,1298, 284, 283,2041, // 48 2042,1061,1062, 48, 49, 44, 45, 433, 434,1040,1041, 996, 787,2997,1255,4305, // 64 2108,4609,1684,1648,5073,5074,5075,5076,5077,5078,3687,5079,4610,5080,3927,3928, // 80 5081,3296,3432, 290,2285,1471,2187,5082,2580,2825,1303,2140,1739,1445,2691,3375, // 96 1691,3297,4306,4307,4611, 452,3376,1182,2713,3688,3069,4308,5083,5084,5085,5086, // 112 5087,5088,5089,5090,5091,5092,5093,5094,5095,5096,5097,5098,5099,5100,5101,5102, // 128 5103,5104,5105,5106,5107,5108,5109,5110,5111,5112,4097,5113,5114,5115,5116,5117, // 144 5118,5119,5120,5121,5122,5123,5124,5125,5126,5127,5128,5129,5130,5131,5132,5133, // 160 5134,5135,5136,5137,5138,5139,5140,5141,5142,5143,5144,5145,5146,5147,5148,5149, // 176 5150,5151,5152,4612,5153,5154,5155,5156,5157,5158,5159,5160,5161,5162,5163,5164, // 192 5165,5166,5167,5168,5169,5170,5171,5172,5173,5174,5175,1472, 598, 618, 820,1205, // 208 1309,1412,1858,1307,1692,5176,5177,5178,5179,5180,5181,5182,1142,1452,1234,1172, // 224 1875,2043,2149,1793,1382,2973, 925,2404,1067,1241, 960,1377,2935,1491, 919,1217, // 240 1865,2030,1406,1499,2749,4098,5183,5184,5185,5186,5187,5188,2561,4099,3117,1804, // 256 2049,3689,4309,3513,1663,5189,3166,3118,3298,1587,1561,3433,5190,3119,1625,2998, // 272 3299,4613,1766,3690,2786,4614,5191,5192,5193,5194,2161, 26,3377, 2,3929, 20, // 288 3691, 47,4100, 50, 17, 16, 35, 268, 27, 243, 42, 155, 24, 154, 29, 184, // 304 4, 91, 14, 92, 53, 396, 33, 289, 9, 37, 64, 620, 21, 39, 321, 5, // 320 12, 11, 52, 13, 3, 208, 138, 0, 7, 60, 526, 141, 151,1069, 181, 275, // 336 1591, 83, 132,1475, 126, 331, 829, 15, 69, 160, 59, 22, 157, 55,1079, 312, // 352 109, 38, 23, 25, 10, 19, 79,5195, 61, 382,1124, 8, 30,5196,5197,5198, // 368 5199,5200,5201,5202,5203,5204,5205,5206, 89, 62, 74, 34,2416, 112, 139, 196, // 384 271, 149, 84, 607, 131, 765, 46, 88, 153, 683, 76, 874, 101, 258, 57, 80, // 400 32, 364, 121,1508, 169,1547, 68, 235, 145,2999, 41, 360,3027, 70, 63, 31, // 416 43, 259, 262,1383, 99, 533, 194, 66, 93, 846, 217, 192, 56, 106, 58, 565, // 432 280, 272, 311, 256, 146, 82, 308, 71, 100, 128, 214, 655, 110, 261, 104,1140, // 448 54, 51, 36, 87, 67,3070, 185,2618,2936,2020, 28,1066,2390,2059,5207,5208, // 464 5209,5210,5211,5212,5213,5214,5215,5216,4615,5217,5218,5219,5220,5221,5222,5223, // 480 5224,5225,5226,5227,5228,5229,5230,5231,5232,5233,5234,5235,5236,3514,5237,5238, // 496 5239,5240,5241,5242,5243,5244,2297,2031,4616,4310,3692,5245,3071,5246,3598,5247, // 512 4617,3231,3515,5248,4101,4311,4618,3808,4312,4102,5249,4103,4104,3599,5250,5251, // 528 5252,5253,5254,5255,5256,5257,5258,5259,5260,5261,5262,5263,5264,5265,5266,5267, // 544 5268,5269,5270,5271,5272,5273,5274,5275,5276,5277,5278,5279,5280,5281,5282,5283, // 560 5284,5285,5286,5287,5288,5289,5290,5291,5292,5293,5294,5295,5296,5297,5298,5299, // 576 5300,5301,5302,5303,5304,5305,5306,5307,5308,5309,5310,5311,5312,5313,5314,5315, // 592 5316,5317,5318,5319,5320,5321,5322,5323,5324,5325,5326,5327,5328,5329,5330,5331, // 608 5332,5333,5334,5335,5336,5337,5338,5339,5340,5341,5342,5343,5344,5345,5346,5347, // 624 5348,5349,5350,5351,5352,5353,5354,5355,5356,5357,5358,5359,5360,5361,5362,5363, // 640 5364,5365,5366,5367,5368,5369,5370,5371,5372,5373,5374,5375,5376,5377,5378,5379, // 656 5380,5381, 363, 642,2787,2878,2788,2789,2316,3232,2317,3434,2011, 165,1942,3930, // 672 3931,3932,3933,5382,4619,5383,4620,5384,5385,5386,5387,5388,5389,5390,5391,5392, // 688 5393,5394,5395,5396,5397,5398,5399,5400,5401,5402,5403,5404,5405,5406,5407,5408, // 704 5409,5410,5411,5412,5413,5414,5415,5416,5417,5418,5419,5420,5421,5422,5423,5424, // 720 5425,5426,5427,5428,5429,5430,5431,5432,5433,5434,5435,5436,5437,5438,5439,5440, // 736 5441,5442,5443,5444,5445,5446,5447,5448,5449,5450,5451,5452,5453,5454,5455,5456, // 752 5457,5458,5459,5460,5461,5462,5463,5464,5465,5466,5467,5468,5469,5470,5471,5472, // 768 5473,5474,5475,5476,5477,5478,5479,5480,5481,5482,5483,5484,5485,5486,5487,5488, // 784 5489,5490,5491,5492,5493,5494,5495,5496,5497,5498,5499,5500,5501,5502,5503,5504, // 800 5505,5506,5507,5508,5509,5510,5511,5512,5513,5514,5515,5516,5517,5518,5519,5520, // 816 5521,5522,5523,5524,5525,5526,5527,5528,5529,5530,5531,5532,5533,5534,5535,5536, // 832 5537,5538,5539,5540,5541,5542,5543,5544,5545,5546,5547,5548,5549,5550,5551,5552, // 848 5553,5554,5555,5556,5557,5558,5559,5560,5561,5562,5563,5564,5565,5566,5567,5568, // 864 5569,5570,5571,5572,5573,5574,5575,5576,5577,5578,5579,5580,5581,5582,5583,5584, // 880 5585,5586,5587,5588,5589,5590,5591,5592,5593,5594,5595,5596,5597,5598,5599,5600, // 896 5601,5602,5603,5604,5605,5606,5607,5608,5609,5610,5611,5612,5613,5614,5615,5616, // 912 5617,5618,5619,5620,5621,5622,5623,5624,5625,5626,5627,5628,5629,5630,5631,5632, // 928 5633,5634,5635,5636,5637,5638,5639,5640,5641,5642,5643,5644,5645,5646,5647,5648, // 944 5649,5650,5651,5652,5653,5654,5655,5656,5657,5658,5659,5660,5661,5662,5663,5664, // 960 5665,5666,5667,5668,5669,5670,5671,5672,5673,5674,5675,5676,5677,5678,5679,5680, // 976 5681,5682,5683,5684,5685,5686,5687,5688,5689,5690,5691,5692,5693,5694,5695,5696, // 992 5697,5698,5699,5700,5701,5702,5703,5704,5705,5706,5707,5708,5709,5710,5711,5712, // 1008 5713,5714,5715,5716,5717,5718,5719,5720,5721,5722,5723,5724,5725,5726,5727,5728, // 1024 5729,5730,5731,5732,5733,5734,5735,5736,5737,5738,5739,5740,5741,5742,5743,5744, // 1040 5745,5746,5747,5748,5749,5750,5751,5752,5753,5754,5755,5756,5757,5758,5759,5760, // 1056 5761,5762,5763,5764,5765,5766,5767,5768,5769,5770,5771,5772,5773,5774,5775,5776, // 1072 5777,5778,5779,5780,5781,5782,5783,5784,5785,5786,5787,5788,5789,5790,5791,5792, // 1088 5793,5794,5795,5796,5797,5798,5799,5800,5801,5802,5803,5804,5805,5806,5807,5808, // 1104 5809,5810,5811,5812,5813,5814,5815,5816,5817,5818,5819,5820,5821,5822,5823,5824, // 1120 5825,5826,5827,5828,5829,5830,5831,5832,5833,5834,5835,5836,5837,5838,5839,5840, // 1136 5841,5842,5843,5844,5845,5846,5847,5848,5849,5850,5851,5852,5853,5854,5855,5856, // 1152 5857,5858,5859,5860,5861,5862,5863,5864,5865,5866,5867,5868,5869,5870,5871,5872, // 1168 5873,5874,5875,5876,5877,5878,5879,5880,5881,5882,5883,5884,5885,5886,5887,5888, // 1184 5889,5890,5891,5892,5893,5894,5895,5896,5897,5898,5899,5900,5901,5902,5903,5904, // 1200 5905,5906,5907,5908,5909,5910,5911,5912,5913,5914,5915,5916,5917,5918,5919,5920, // 1216 5921,5922,5923,5924,5925,5926,5927,5928,5929,5930,5931,5932,5933,5934,5935,5936, // 1232 5937,5938,5939,5940,5941,5942,5943,5944,5945,5946,5947,5948,5949,5950,5951,5952, // 1248 5953,5954,5955,5956,5957,5958,5959,5960,5961,5962,5963,5964,5965,5966,5967,5968, // 1264 5969,5970,5971,5972,5973,5974,5975,5976,5977,5978,5979,5980,5981,5982,5983,5984, // 1280 5985,5986,5987,5988,5989,5990,5991,5992,5993,5994,5995,5996,5997,5998,5999,6000, // 1296 6001,6002,6003,6004,6005,6006,6007,6008,6009,6010,6011,6012,6013,6014,6015,6016, // 1312 6017,6018,6019,6020,6021,6022,6023,6024,6025,6026,6027,6028,6029,6030,6031,6032, // 1328 6033,6034,6035,6036,6037,6038,6039,6040,6041,6042,6043,6044,6045,6046,6047,6048, // 1344 6049,6050,6051,6052,6053,6054,6055,6056,6057,6058,6059,6060,6061,6062,6063,6064, // 1360 6065,6066,6067,6068,6069,6070,6071,6072,6073,6074,6075,6076,6077,6078,6079,6080, // 1376 6081,6082,6083,6084,6085,6086,6087,6088,6089,6090,6091,6092,6093,6094,6095,6096, // 1392 6097,6098,6099,6100,6101,6102,6103,6104,6105,6106,6107,6108,6109,6110,6111,6112, // 1408 6113,6114,2044,2060,4621, 997,1235, 473,1186,4622, 920,3378,6115,6116, 379,1108, // 1424 4313,2657,2735,3934,6117,3809, 636,3233, 573,1026,3693,3435,2974,3300,2298,4105, // 1440 854,2937,2463, 393,2581,2417, 539, 752,1280,2750,2480, 140,1161, 440, 708,1569, // 1456 665,2497,1746,1291,1523,3000, 164,1603, 847,1331, 537,1997, 486, 508,1693,2418, // 1472 1970,2227, 878,1220, 299,1030, 969, 652,2751, 624,1137,3301,2619, 65,3302,2045, // 1488 1761,1859,3120,1930,3694,3516, 663,1767, 852, 835,3695, 269, 767,2826,2339,1305, // 1504 896,1150, 770,1616,6118, 506,1502,2075,1012,2519, 775,2520,2975,2340,2938,4314, // 1520 3028,2086,1224,1943,2286,6119,3072,4315,2240,1273,1987,3935,1557, 175, 597, 985, // 1536 3517,2419,2521,1416,3029, 585, 938,1931,1007,1052,1932,1685,6120,3379,4316,4623, // 1552 804, 599,3121,1333,2128,2539,1159,1554,2032,3810, 687,2033,2904, 952, 675,1467, // 1568 3436,6121,2241,1096,1786,2440,1543,1924, 980,1813,2228, 781,2692,1879, 728,1918, // 1584 3696,4624, 548,1950,4625,1809,1088,1356,3303,2522,1944, 502, 972, 373, 513,2827, // 1600 586,2377,2391,1003,1976,1631,6122,2464,1084, 648,1776,4626,2141, 324, 962,2012, // 1616 2177,2076,1384, 742,2178,1448,1173,1810, 222, 102, 301, 445, 125,2420, 662,2498, // 1632 277, 200,1476,1165,1068, 224,2562,1378,1446, 450,1880, 659, 791, 582,4627,2939, // 1648 3936,1516,1274, 555,2099,3697,1020,1389,1526,3380,1762,1723,1787,2229, 412,2114, // 1664 1900,2392,3518, 512,2597, 427,1925,2341,3122,1653,1686,2465,2499, 697, 330, 273, // 1680 380,2162, 951, 832, 780, 991,1301,3073, 965,2270,3519, 668,2523,2636,1286, 535, // 1696 1407, 518, 671, 957,2658,2378, 267, 611,2197,3030,6123, 248,2299, 967,1799,2356, // 1712 850,1418,3437,1876,1256,1480,2828,1718,6124,6125,1755,1664,2405,6126,4628,2879, // 1728 2829, 499,2179, 676,4629, 557,2329,2214,2090, 325,3234, 464, 811,3001, 992,2342, // 1744 2481,1232,1469, 303,2242, 466,1070,2163, 603,1777,2091,4630,2752,4631,2714, 322, // 1760 2659,1964,1768, 481,2188,1463,2330,2857,3600,2092,3031,2421,4632,2318,2070,1849, // 1776 2598,4633,1302,2254,1668,1701,2422,3811,2905,3032,3123,2046,4106,1763,1694,4634, // 1792 1604, 943,1724,1454, 917, 868,2215,1169,2940, 552,1145,1800,1228,1823,1955, 316, // 1808 1080,2510, 361,1807,2830,4107,2660,3381,1346,1423,1134,4108,6127, 541,1263,1229, // 1824 1148,2540, 545, 465,1833,2880,3438,1901,3074,2482, 816,3937, 713,1788,2500, 122, // 1840 1575, 195,1451,2501,1111,6128, 859, 374,1225,2243,2483,4317, 390,1033,3439,3075, // 1856 2524,1687, 266, 793,1440,2599, 946, 779, 802, 507, 897,1081, 528,2189,1292, 711, // 1872 1866,1725,1167,1640, 753, 398,2661,1053, 246, 348,4318, 137,1024,3440,1600,2077, // 1888 2129, 825,4319, 698, 238, 521, 187,2300,1157,2423,1641,1605,1464,1610,1097,2541, // 1904 1260,1436, 759,2255,1814,2150, 705,3235, 409,2563,3304, 561,3033,2005,2564, 726, // 1920 1956,2343,3698,4109, 949,3812,3813,3520,1669, 653,1379,2525, 881,2198, 632,2256, // 1936 1027, 778,1074, 733,1957, 514,1481,2466, 554,2180, 702,3938,1606,1017,1398,6129, // 1952 1380,3521, 921, 993,1313, 594, 449,1489,1617,1166, 768,1426,1360, 495,1794,3601, // 1968 1177,3602,1170,4320,2344, 476, 425,3167,4635,3168,1424, 401,2662,1171,3382,1998, // 1984 1089,4110, 477,3169, 474,6130,1909, 596,2831,1842, 494, 693,1051,1028,1207,3076, // 2000 606,2115, 727,2790,1473,1115, 743,3522, 630, 805,1532,4321,2021, 366,1057, 838, // 2016 684,1114,2142,4322,2050,1492,1892,1808,2271,3814,2424,1971,1447,1373,3305,1090, // 2032 1536,3939,3523,3306,1455,2199, 336, 369,2331,1035, 584,2393, 902, 718,2600,6131, // 2048 2753, 463,2151,1149,1611,2467, 715,1308,3124,1268, 343,1413,3236,1517,1347,2663, // 2064 2093,3940,2022,1131,1553,2100,2941,1427,3441,2942,1323,2484,6132,1980, 872,2368, // 2080 2441,2943, 320,2369,2116,1082, 679,1933,3941,2791,3815, 625,1143,2023, 422,2200, // 2096 3816,6133, 730,1695, 356,2257,1626,2301,2858,2637,1627,1778, 937, 883,2906,2693, // 2112 3002,1769,1086, 400,1063,1325,3307,2792,4111,3077, 456,2345,1046, 747,6134,1524, // 2128 884,1094,3383,1474,2164,1059, 974,1688,2181,2258,1047, 345,1665,1187, 358, 875, // 2144 3170, 305, 660,3524,2190,1334,1135,3171,1540,1649,2542,1527, 927, 968,2793, 885, // 2160 1972,1850, 482, 500,2638,1218,1109,1085,2543,1654,2034, 876, 78,2287,1482,1277, // 2176 861,1675,1083,1779, 724,2754, 454, 397,1132,1612,2332, 893, 672,1237, 257,2259, // 2192 2370, 135,3384, 337,2244, 547, 352, 340, 709,2485,1400, 788,1138,2511, 540, 772, // 2208 1682,2260,2272,2544,2013,1843,1902,4636,1999,1562,2288,4637,2201,1403,1533, 407, // 2224 576,3308,1254,2071, 978,3385, 170, 136,1201,3125,2664,3172,2394, 213, 912, 873, // 2240 3603,1713,2202, 699,3604,3699, 813,3442, 493, 531,1054, 468,2907,1483, 304, 281, // 2256 4112,1726,1252,2094, 339,2319,2130,2639, 756,1563,2944, 748, 571,2976,1588,2425, // 2272 2715,1851,1460,2426,1528,1392,1973,3237, 288,3309, 685,3386, 296, 892,2716,2216, // 2288 1570,2245, 722,1747,2217, 905,3238,1103,6135,1893,1441,1965, 251,1805,2371,3700, // 2304 2601,1919,1078, 75,2182,1509,1592,1270,2640,4638,2152,6136,3310,3817, 524, 706, // 2320 1075, 292,3818,1756,2602, 317, 98,3173,3605,3525,1844,2218,3819,2502, 814, 567, // 2336 385,2908,1534,6137, 534,1642,3239, 797,6138,1670,1529, 953,4323, 188,1071, 538, // 2352 178, 729,3240,2109,1226,1374,2000,2357,2977, 731,2468,1116,2014,2051,6139,1261, // 2368 1593, 803,2859,2736,3443, 556, 682, 823,1541,6140,1369,2289,1706,2794, 845, 462, // 2384 2603,2665,1361, 387, 162,2358,1740, 739,1770,1720,1304,1401,3241,1049, 627,1571, // 2400 2427,3526,1877,3942,1852,1500, 431,1910,1503, 677, 297,2795, 286,1433,1038,1198, // 2416 2290,1133,1596,4113,4639,2469,1510,1484,3943,6141,2442, 108, 712,4640,2372, 866, // 2432 3701,2755,3242,1348, 834,1945,1408,3527,2395,3243,1811, 824, 994,1179,2110,1548, // 2448 1453, 790,3003, 690,4324,4325,2832,2909,3820,1860,3821, 225,1748, 310, 346,1780, // 2464 2470, 821,1993,2717,2796, 828, 877,3528,2860,2471,1702,2165,2910,2486,1789, 453, // 2480 359,2291,1676, 73,1164,1461,1127,3311, 421, 604, 314,1037, 589, 116,2487, 737, // 2496 837,1180, 111, 244, 735,6142,2261,1861,1362, 986, 523, 418, 581,2666,3822, 103, // 2512 855, 503,1414,1867,2488,1091, 657,1597, 979, 605,1316,4641,1021,2443,2078,2001, // 2528 1209, 96, 587,2166,1032, 260,1072,2153, 173, 94, 226,3244, 819,2006,4642,4114, // 2544 2203, 231,1744, 782, 97,2667, 786,3387, 887, 391, 442,2219,4326,1425,6143,2694, // 2560 633,1544,1202, 483,2015, 592,2052,1958,2472,1655, 419, 129,4327,3444,3312,1714, // 2576 1257,3078,4328,1518,1098, 865,1310,1019,1885,1512,1734, 469,2444, 148, 773, 436, // 2592 1815,1868,1128,1055,4329,1245,2756,3445,2154,1934,1039,4643, 579,1238, 932,2320, // 2608 353, 205, 801, 115,2428, 944,2321,1881, 399,2565,1211, 678, 766,3944, 335,2101, // 2624 1459,1781,1402,3945,2737,2131,1010, 844, 981,1326,1013, 550,1816,1545,2620,1335, // 2640 1008, 371,2881, 936,1419,1613,3529,1456,1395,2273,1834,2604,1317,2738,2503, 416, // 2656 1643,4330, 806,1126, 229, 591,3946,1314,1981,1576,1837,1666, 347,1790, 977,3313, // 2672 764,2861,1853, 688,2429,1920,1462, 77, 595, 415,2002,3034, 798,1192,4115,6144, // 2688 2978,4331,3035,2695,2582,2072,2566, 430,2430,1727, 842,1396,3947,3702, 613, 377, // 2704 278, 236,1417,3388,3314,3174, 757,1869, 107,3530,6145,1194, 623,2262, 207,1253, // 2720 2167,3446,3948, 492,1117,1935, 536,1838,2757,1246,4332, 696,2095,2406,1393,1572, // 2736 3175,1782, 583, 190, 253,1390,2230, 830,3126,3389, 934,3245,1703,1749,2979,1870, // 2752 2545,1656,2204, 869,2346,4116,3176,1817, 496,1764,4644, 942,1504, 404,1903,1122, // 2768 1580,3606,2945,1022, 515, 372,1735, 955,2431,3036,6146,2797,1110,2302,2798, 617, // 2784 6147, 441, 762,1771,3447,3607,3608,1904, 840,3037, 86, 939,1385, 572,1370,2445, // 2800 1336, 114,3703, 898, 294, 203,3315, 703,1583,2274, 429, 961,4333,1854,1951,3390, // 2816 2373,3704,4334,1318,1381, 966,1911,2322,1006,1155, 309, 989, 458,2718,1795,1372, // 2832 1203, 252,1689,1363,3177, 517,1936, 168,1490, 562, 193,3823,1042,4117,1835, 551, // 2848 470,4645, 395, 489,3448,1871,1465,2583,2641, 417,1493, 279,1295, 511,1236,1119, // 2864 72,1231,1982,1812,3004, 871,1564, 984,3449,1667,2696,2096,4646,2347,2833,1673, // 2880 3609, 695,3246,2668, 807,1183,4647, 890, 388,2333,1801,1457,2911,1765,1477,1031, // 2896 3316,3317,1278,3391,2799,2292,2526, 163,3450,4335,2669,1404,1802,6148,2323,2407, // 2912 1584,1728,1494,1824,1269, 298, 909,3318,1034,1632, 375, 776,1683,2061, 291, 210, // 2928 1123, 809,1249,1002,2642,3038, 206,1011,2132, 144, 975, 882,1565, 342, 667, 754, // 2944 1442,2143,1299,2303,2062, 447, 626,2205,1221,2739,2912,1144,1214,2206,2584, 760, // 2960 1715, 614, 950,1281,2670,2621, 810, 577,1287,2546,4648, 242,2168, 250,2643, 691, // 2976 123,2644, 647, 313,1029, 689,1357,2946,1650, 216, 771,1339,1306, 808,2063, 549, // 2992 913,1371,2913,2914,6149,1466,1092,1174,1196,1311,2605,2396,1783,1796,3079, 406, // 3008 2671,2117,3949,4649, 487,1825,2220,6150,2915, 448,2348,1073,6151,2397,1707, 130, // 3024 900,1598, 329, 176,1959,2527,1620,6152,2275,4336,3319,1983,2191,3705,3610,2155, // 3040 3706,1912,1513,1614,6153,1988, 646, 392,2304,1589,3320,3039,1826,1239,1352,1340, // 3056 2916, 505,2567,1709,1437,2408,2547, 906,6154,2672, 384,1458,1594,1100,1329, 710, // 3072 423,3531,2064,2231,2622,1989,2673,1087,1882, 333, 841,3005,1296,2882,2379, 580, // 3088 1937,1827,1293,2585, 601, 574, 249,1772,4118,2079,1120, 645, 901,1176,1690, 795, // 3104 2207, 478,1434, 516,1190,1530, 761,2080, 930,1264, 355, 435,1552, 644,1791, 987, // 3120 220,1364,1163,1121,1538, 306,2169,1327,1222, 546,2645, 218, 241, 610,1704,3321, // 3136 1984,1839,1966,2528, 451,6155,2586,3707,2568, 907,3178, 254,2947, 186,1845,4650, // 3152 745, 432,1757, 428,1633, 888,2246,2221,2489,3611,2118,1258,1265, 956,3127,1784, // 3168 4337,2490, 319, 510, 119, 457,3612, 274,2035,2007,4651,1409,3128, 970,2758, 590, // 3184 2800, 661,2247,4652,2008,3950,1420,1549,3080,3322,3951,1651,1375,2111, 485,2491, // 3200 1429,1156,6156,2548,2183,1495, 831,1840,2529,2446, 501,1657, 307,1894,3247,1341, // 3216 666, 899,2156,1539,2549,1559, 886, 349,2208,3081,2305,1736,3824,2170,2759,1014, // 3232 1913,1386, 542,1397,2948, 490, 368, 716, 362, 159, 282,2569,1129,1658,1288,1750, // 3248 2674, 276, 649,2016, 751,1496, 658,1818,1284,1862,2209,2087,2512,3451, 622,2834, // 3264 376, 117,1060,2053,1208,1721,1101,1443, 247,1250,3179,1792,3952,2760,2398,3953, // 3280 6157,2144,3708, 446,2432,1151,2570,3452,2447,2761,2835,1210,2448,3082, 424,2222, // 3296 1251,2449,2119,2836, 504,1581,4338, 602, 817, 857,3825,2349,2306, 357,3826,1470, // 3312 1883,2883, 255, 958, 929,2917,3248, 302,4653,1050,1271,1751,2307,1952,1430,2697, // 3328 2719,2359, 354,3180, 777, 158,2036,4339,1659,4340,4654,2308,2949,2248,1146,2232, // 3344 3532,2720,1696,2623,3827,6158,3129,1550,2698,1485,1297,1428, 637, 931,2721,2145, // 3360 914,2550,2587, 81,2450, 612, 827,2646,1242,4655,1118,2884, 472,1855,3181,3533, // 3376 3534, 569,1353,2699,1244,1758,2588,4119,2009,2762,2171,3709,1312,1531,6159,1152, // 3392 1938, 134,1830, 471,3710,2276,1112,1535,3323,3453,3535, 982,1337,2950, 488, 826, // 3408 674,1058,1628,4120,2017, 522,2399, 211, 568,1367,3454, 350, 293,1872,1139,3249, // 3424 1399,1946,3006,1300,2360,3324, 588, 736,6160,2606, 744, 669,3536,3828,6161,1358, // 3440 199, 723, 848, 933, 851,1939,1505,1514,1338,1618,1831,4656,1634,3613, 443,2740, // 3456 3829, 717,1947, 491,1914,6162,2551,1542,4121,1025,6163,1099,1223, 198,3040,2722, // 3472 370, 410,1905,2589, 998,1248,3182,2380, 519,1449,4122,1710, 947, 928,1153,4341, // 3488 2277, 344,2624,1511, 615, 105, 161,1212,1076,1960,3130,2054,1926,1175,1906,2473, // 3504 414,1873,2801,6164,2309, 315,1319,3325, 318,2018,2146,2157, 963, 631, 223,4342, // 3520 4343,2675, 479,3711,1197,2625,3712,2676,2361,6165,4344,4123,6166,2451,3183,1886, // 3536 2184,1674,1330,1711,1635,1506, 799, 219,3250,3083,3954,1677,3713,3326,2081,3614, // 3552 1652,2073,4657,1147,3041,1752, 643,1961, 147,1974,3955,6167,1716,2037, 918,3007, // 3568 1994, 120,1537, 118, 609,3184,4345, 740,3455,1219, 332,1615,3830,6168,1621,2980, // 3584 1582, 783, 212, 553,2350,3714,1349,2433,2082,4124, 889,6169,2310,1275,1410, 973, // 3600 166,1320,3456,1797,1215,3185,2885,1846,2590,2763,4658, 629, 822,3008, 763, 940, // 3616 1990,2862, 439,2409,1566,1240,1622, 926,1282,1907,2764, 654,2210,1607, 327,1130, // 3632 3956,1678,1623,6170,2434,2192, 686, 608,3831,3715, 903,3957,3042,6171,2741,1522, // 3648 1915,1105,1555,2552,1359, 323,3251,4346,3457, 738,1354,2553,2311,2334,1828,2003, // 3664 3832,1753,2351,1227,6172,1887,4125,1478,6173,2410,1874,1712,1847, 520,1204,2607, // 3680 264,4659, 836,2677,2102, 600,4660,3833,2278,3084,6174,4347,3615,1342, 640, 532, // 3696 543,2608,1888,2400,2591,1009,4348,1497, 341,1737,3616,2723,1394, 529,3252,1321, // 3712 983,4661,1515,2120, 971,2592, 924, 287,1662,3186,4349,2700,4350,1519, 908,1948, // 3728 2452, 156, 796,1629,1486,2223,2055, 694,4126,1259,1036,3392,1213,2249,2742,1889, // 3744 1230,3958,1015, 910, 408, 559,3617,4662, 746, 725, 935,4663,3959,3009,1289, 563, // 3760 867,4664,3960,1567,2981,2038,2626, 988,2263,2381,4351, 143,2374, 704,1895,6175, // 3776 1188,3716,2088, 673,3085,2362,4352, 484,1608,1921,2765,2918, 215, 904,3618,3537, // 3792 894, 509, 976,3043,2701,3961,4353,2837,2982, 498,6176,6177,1102,3538,1332,3393, // 3808 1487,1636,1637, 233, 245,3962, 383, 650, 995,3044, 460,1520,1206,2352, 749,3327, // 3824 530, 700, 389,1438,1560,1773,3963,2264, 719,2951,2724,3834, 870,1832,1644,1000, // 3840 839,2474,3717, 197,1630,3394, 365,2886,3964,1285,2133, 734, 922, 818,1106, 732, // 3856 480,2083,1774,3458, 923,2279,1350, 221,3086, 85,2233,2234,3835,1585,3010,2147, // 3872 1387,1705,2382,1619,2475, 133, 239,2802,1991,1016,2084,2383, 411,2838,1113, 651, // 3888 1985,1160,3328, 990,1863,3087,1048,1276,2647, 265,2627,1599,3253,2056, 150, 638, // 3904 2019, 656, 853, 326,1479, 680,1439,4354,1001,1759, 413,3459,3395,2492,1431, 459, // 3920 4355,1125,3329,2265,1953,1450,2065,2863, 849, 351,2678,3131,3254,3255,1104,1577, // 3936 227,1351,1645,2453,2193,1421,2887, 812,2121, 634, 95,2435, 201,2312,4665,1646, // 3952 1671,2743,1601,2554,2702,2648,2280,1315,1366,2089,3132,1573,3718,3965,1729,1189, // 3968 328,2679,1077,1940,1136, 558,1283, 964,1195, 621,2074,1199,1743,3460,3619,1896, // 3984 1916,1890,3836,2952,1154,2112,1064, 862, 378,3011,2066,2113,2803,1568,2839,6178, // 4000 3088,2919,1941,1660,2004,1992,2194, 142, 707,1590,1708,1624,1922,1023,1836,1233, // 4016 1004,2313, 789, 741,3620,6179,1609,2411,1200,4127,3719,3720,4666,2057,3721, 593, // 4032 2840, 367,2920,1878,6180,3461,1521, 628,1168, 692,2211,2649, 300, 720,2067,2571, // 4048 2953,3396, 959,2504,3966,3539,3462,1977, 701,6181, 954,1043, 800, 681, 183,3722, // 4064 1803,1730,3540,4128,2103, 815,2314, 174, 467, 230,2454,1093,2134, 755,3541,3397, // 4080 1141,1162,6182,1738,2039, 270,3256,2513,1005,1647,2185,3837, 858,1679,1897,1719, // 4096 2954,2324,1806, 402, 670, 167,4129,1498,2158,2104, 750,6183, 915, 189,1680,1551, // 4112 455,4356,1501,2455, 405,1095,2955, 338,1586,1266,1819, 570, 641,1324, 237,1556, // 4128 2650,1388,3723,6184,1368,2384,1343,1978,3089,2436, 879,3724, 792,1191, 758,3012, // 4144 1411,2135,1322,4357, 240,4667,1848,3725,1574,6185, 420,3045,1546,1391, 714,4358, // 4160 1967, 941,1864, 863, 664, 426, 560,1731,2680,1785,2864,1949,2363, 403,3330,1415, // 4176 1279,2136,1697,2335, 204, 721,2097,3838, 90,6186,2085,2505, 191,3967, 124,2148, // 4192 1376,1798,1178,1107,1898,1405, 860,4359,1243,1272,2375,2983,1558,2456,1638, 113, // 4208 3621, 578,1923,2609, 880, 386,4130, 784,2186,2266,1422,2956,2172,1722, 497, 263, // 4224 2514,1267,2412,2610, 177,2703,3542, 774,1927,1344, 616,1432,1595,1018, 172,4360, // 4240 2325, 911,4361, 438,1468,3622, 794,3968,2024,2173,1681,1829,2957, 945, 895,3090, // 4256 575,2212,2476, 475,2401,2681, 785,2744,1745,2293,2555,1975,3133,2865, 394,4668, // 4272 3839, 635,4131, 639, 202,1507,2195,2766,1345,1435,2572,3726,1908,1184,1181,2457, // 4288 3727,3134,4362, 843,2611, 437, 916,4669, 234, 769,1884,3046,3047,3623, 833,6187, // 4304 1639,2250,2402,1355,1185,2010,2047, 999, 525,1732,1290,1488,2612, 948,1578,3728, // 4320 2413,2477,1216,2725,2159, 334,3840,1328,3624,2921,1525,4132, 564,1056, 891,4363, // 4336 1444,1698,2385,2251,3729,1365,2281,2235,1717,6188, 864,3841,2515, 444, 527,2767, // 4352 2922,3625, 544, 461,6189, 566, 209,2437,3398,2098,1065,2068,3331,3626,3257,2137, // 4368 //last 512 -/*************************************************************************************** +/*************************************************************************************** *Everything below is of no interest for detection purpose * *************************************************************************************** 2138,2122,3730,2888,1995,1820,1044,6190,6191,6192,6193,6194,6195,6196,6197,6198, // 4384 6199,6200,6201,6202,6203,6204,6205,4670,6206,6207,6208,6209,6210,6211,6212,6213, // 4400 6214,6215,6216,6217,6218,6219,6220,6221,6222,6223,6224,6225,6226,6227,6228,6229, // 4416 6230,6231,6232,6233,6234,6235,6236,6237,3187,6238,6239,3969,6240,6241,6242,6243, // 4432 6244,4671,6245,6246,4672,6247,6248,4133,6249,6250,4364,6251,2923,2556,2613,4673, // 4448 4365,3970,6252,6253,6254,6255,4674,6256,6257,6258,2768,2353,4366,4675,4676,3188, // 4464 4367,3463,6259,4134,4677,4678,6260,2267,6261,3842,3332,4368,3543,6262,6263,6264, // 4480 3013,1954,1928,4135,4679,6265,6266,2478,3091,6267,4680,4369,6268,6269,1699,6270, // 4496 3544,4136,4681,6271,4137,6272,4370,2804,6273,6274,2593,3971,3972,4682,6275,2236, // 4512 4683,6276,6277,4684,6278,6279,4138,3973,4685,6280,6281,3258,6282,6283,6284,6285, // 4528 3974,4686,2841,3975,6286,6287,3545,6288,6289,4139,4687,4140,6290,4141,6291,4142, // 4544 6292,6293,3333,6294,6295,6296,4371,6297,3399,6298,6299,4372,3976,6300,6301,6302, // 4560 4373,6303,6304,3843,3731,6305,4688,4374,6306,6307,3259,2294,6308,3732,2530,4143, // 4576 6309,4689,6310,6311,6312,3048,6313,6314,4690,3733,2237,6315,6316,2282,3334,6317, // 4592 6318,3844,6319,6320,4691,6321,3400,4692,6322,4693,6323,3049,6324,4375,6325,3977, // 4608 6326,6327,6328,3546,6329,4694,3335,6330,4695,4696,6331,6332,6333,6334,4376,3978, // 4624 6335,4697,3979,4144,6336,3980,4698,6337,6338,6339,6340,6341,4699,4700,4701,6342, // 4640 6343,4702,6344,6345,4703,6346,6347,4704,6348,4705,4706,3135,6349,4707,6350,4708, // 4656 6351,4377,6352,4709,3734,4145,6353,2506,4710,3189,6354,3050,4711,3981,6355,3547, // 4672 3014,4146,4378,3735,2651,3845,3260,3136,2224,1986,6356,3401,6357,4712,2594,3627, // 4688 3137,2573,3736,3982,4713,3628,4714,4715,2682,3629,4716,6358,3630,4379,3631,6359, // 4704 6360,6361,3983,6362,6363,6364,6365,4147,3846,4717,6366,6367,3737,2842,6368,4718, // 4720 2628,6369,3261,6370,2386,6371,6372,3738,3984,4719,3464,4720,3402,6373,2924,3336, // 4736 4148,2866,6374,2805,3262,4380,2704,2069,2531,3138,2806,2984,6375,2769,6376,4721, // 4752 4722,3403,6377,6378,3548,6379,6380,2705,3092,1979,4149,2629,3337,2889,6381,3338, // 4768 4150,2557,3339,4381,6382,3190,3263,3739,6383,4151,4723,4152,2558,2574,3404,3191, // 4784 6384,6385,4153,6386,4724,4382,6387,6388,4383,6389,6390,4154,6391,4725,3985,6392, // 4800 3847,4155,6393,6394,6395,6396,6397,3465,6398,4384,6399,6400,6401,6402,6403,6404, // 4816 4156,6405,6406,6407,6408,2123,6409,6410,2326,3192,4726,6411,6412,6413,6414,4385, // 4832 4157,6415,6416,4158,6417,3093,3848,6418,3986,6419,6420,3849,6421,6422,6423,4159, // 4848 6424,6425,4160,6426,3740,6427,6428,6429,6430,3987,6431,4727,6432,2238,6433,6434, // 4864 4386,3988,6435,6436,3632,6437,6438,2843,6439,6440,6441,6442,3633,6443,2958,6444, // 4880 6445,3466,6446,2364,4387,3850,6447,4388,2959,3340,6448,3851,6449,4728,6450,6451, // 4896 3264,4729,6452,3193,6453,4389,4390,2706,3341,4730,6454,3139,6455,3194,6456,3051, // 4912 2124,3852,1602,4391,4161,3853,1158,3854,4162,3989,4392,3990,4731,4732,4393,2040, // 4928 4163,4394,3265,6457,2807,3467,3855,6458,6459,6460,3991,3468,4733,4734,6461,3140, // 4944 2960,6462,4735,6463,6464,6465,6466,4736,4737,4738,4739,6467,6468,4164,2403,3856, // 4960 6469,6470,2770,2844,6471,4740,6472,6473,6474,6475,6476,6477,6478,3195,6479,4741, // 4976 4395,6480,2867,6481,4742,2808,6482,2493,4165,6483,6484,6485,6486,2295,4743,6487, // 4992 6488,6489,3634,6490,6491,6492,6493,6494,6495,6496,2985,4744,6497,6498,4745,6499, // 5008 6500,2925,3141,4166,6501,6502,4746,6503,6504,4747,6505,6506,6507,2890,6508,6509, // 5024 6510,6511,6512,6513,6514,6515,6516,6517,6518,6519,3469,4167,6520,6521,6522,4748, // 5040 4396,3741,4397,4749,4398,3342,2125,4750,6523,4751,4752,4753,3052,6524,2961,4168, // 5056 6525,4754,6526,4755,4399,2926,4169,6527,3857,6528,4400,4170,6529,4171,6530,6531, // 5072 2595,6532,6533,6534,6535,3635,6536,6537,6538,6539,6540,6541,6542,4756,6543,6544, // 5088 6545,6546,6547,6548,4401,6549,6550,6551,6552,4402,3405,4757,4403,6553,6554,6555, // 5104 4172,3742,6556,6557,6558,3992,3636,6559,6560,3053,2726,6561,3549,4173,3054,4404, // 5120 6562,6563,3993,4405,3266,3550,2809,4406,6564,6565,6566,4758,4759,6567,3743,6568, // 5136 4760,3744,4761,3470,6569,6570,6571,4407,6572,3745,4174,6573,4175,2810,4176,3196, // 5152 4762,6574,4177,6575,6576,2494,2891,3551,6577,6578,3471,6579,4408,6580,3015,3197, // 5168 6581,3343,2532,3994,3858,6582,3094,3406,4409,6583,2892,4178,4763,4410,3016,4411, // 5184 6584,3995,3142,3017,2683,6585,4179,6586,6587,4764,4412,6588,6589,4413,6590,2986, // 5200 6591,2962,3552,6592,2963,3472,6593,6594,4180,4765,6595,6596,2225,3267,4414,6597, // 5216 3407,3637,4766,6598,6599,3198,6600,4415,6601,3859,3199,6602,3473,4767,2811,4416, // 5232 1856,3268,3200,2575,3996,3997,3201,4417,6603,3095,2927,6604,3143,6605,2268,6606, // 5248 3998,3860,3096,2771,6607,6608,3638,2495,4768,6609,3861,6610,3269,2745,4769,4181, // 5264 3553,6611,2845,3270,6612,6613,6614,3862,6615,6616,4770,4771,6617,3474,3999,4418, // 5280 4419,6618,3639,3344,6619,4772,4182,6620,2126,6621,6622,6623,4420,4773,6624,3018, // 5296 6625,4774,3554,6626,4183,2025,3746,6627,4184,2707,6628,4421,4422,3097,1775,4185, // 5312 3555,6629,6630,2868,6631,6632,4423,6633,6634,4424,2414,2533,2928,6635,4186,2387, // 5328 6636,4775,6637,4187,6638,1891,4425,3202,3203,6639,6640,4776,6641,3345,6642,6643, // 5344 3640,6644,3475,3346,3641,4000,6645,3144,6646,3098,2812,4188,3642,3204,6647,3863, // 5360 3476,6648,3864,6649,4426,4001,6650,6651,6652,2576,6653,4189,4777,6654,6655,6656, // 5376 2846,6657,3477,3205,4002,6658,4003,6659,3347,2252,6660,6661,6662,4778,6663,6664, // 5392 6665,6666,6667,6668,6669,4779,4780,2048,6670,3478,3099,6671,3556,3747,4004,6672, // 5408 6673,6674,3145,4005,3748,6675,6676,6677,6678,6679,3408,6680,6681,6682,6683,3206, // 5424 3207,6684,6685,4781,4427,6686,4782,4783,4784,6687,6688,6689,4190,6690,6691,3479, // 5440 6692,2746,6693,4428,6694,6695,6696,6697,6698,6699,4785,6700,6701,3208,2727,6702, // 5456 3146,6703,6704,3409,2196,6705,4429,6706,6707,6708,2534,1996,6709,6710,6711,2747, // 5472 6712,6713,6714,4786,3643,6715,4430,4431,6716,3557,6717,4432,4433,6718,6719,6720, // 5488 6721,3749,6722,4006,4787,6723,6724,3644,4788,4434,6725,6726,4789,2772,6727,6728, // 5504 6729,6730,6731,2708,3865,2813,4435,6732,6733,4790,4791,3480,6734,6735,6736,6737, // 5520 4436,3348,6738,3410,4007,6739,6740,4008,6741,6742,4792,3411,4191,6743,6744,6745, // 5536 6746,6747,3866,6748,3750,6749,6750,6751,6752,6753,6754,6755,3867,6756,4009,6757, // 5552 4793,4794,6758,2814,2987,6759,6760,6761,4437,6762,6763,6764,6765,3645,6766,6767, // 5568 3481,4192,6768,3751,6769,6770,2174,6771,3868,3752,6772,6773,6774,4193,4795,4438, // 5584 3558,4796,4439,6775,4797,6776,6777,4798,6778,4799,3559,4800,6779,6780,6781,3482, // 5600 6782,2893,6783,6784,4194,4801,4010,6785,6786,4440,6787,4011,6788,6789,6790,6791, // 5616 6792,6793,4802,6794,6795,6796,4012,6797,6798,6799,6800,3349,4803,3483,6801,4804, // 5632 4195,6802,4013,6803,6804,4196,6805,4014,4015,6806,2847,3271,2848,6807,3484,6808, // 5648 6809,6810,4441,6811,4442,4197,4443,3272,4805,6812,3412,4016,1579,6813,6814,4017, // 5664 6815,3869,6816,2964,6817,4806,6818,6819,4018,3646,6820,6821,4807,4019,4020,6822, // 5680 6823,3560,6824,6825,4021,4444,6826,4198,6827,6828,4445,6829,6830,4199,4808,6831, // 5696 6832,6833,3870,3019,2458,6834,3753,3413,3350,6835,4809,3871,4810,3561,4446,6836, // 5712 6837,4447,4811,4812,6838,2459,4448,6839,4449,6840,6841,4022,3872,6842,4813,4814, // 5728 6843,6844,4815,4200,4201,4202,6845,4023,6846,6847,4450,3562,3873,6848,6849,4816, // 5744 4817,6850,4451,4818,2139,6851,3563,6852,6853,3351,6854,6855,3352,4024,2709,3414, // 5760 4203,4452,6856,4204,6857,6858,3874,3875,6859,6860,4819,6861,6862,6863,6864,4453, // 5776 3647,6865,6866,4820,6867,6868,6869,6870,4454,6871,2869,6872,6873,4821,6874,3754, // 5792 6875,4822,4205,6876,6877,6878,3648,4206,4455,6879,4823,6880,4824,3876,6881,3055, // 5808 4207,6882,3415,6883,6884,6885,4208,4209,6886,4210,3353,6887,3354,3564,3209,3485, // 5824 2652,6888,2728,6889,3210,3755,6890,4025,4456,6891,4825,6892,6893,6894,6895,4211, // 5840 6896,6897,6898,4826,6899,6900,4212,6901,4827,6902,2773,3565,6903,4828,6904,6905, // 5856 6906,6907,3649,3650,6908,2849,3566,6909,3567,3100,6910,6911,6912,6913,6914,6915, // 5872 4026,6916,3355,4829,3056,4457,3756,6917,3651,6918,4213,3652,2870,6919,4458,6920, // 5888 2438,6921,6922,3757,2774,4830,6923,3356,4831,4832,6924,4833,4459,3653,2507,6925, // 5904 4834,2535,6926,6927,3273,4027,3147,6928,3568,6929,6930,6931,4460,6932,3877,4461, // 5920 2729,3654,6933,6934,6935,6936,2175,4835,2630,4214,4028,4462,4836,4215,6937,3148, // 5936 4216,4463,4837,4838,4217,6938,6939,2850,4839,6940,4464,6941,6942,6943,4840,6944, // 5952 4218,3274,4465,6945,6946,2710,6947,4841,4466,6948,6949,2894,6950,6951,4842,6952, // 5968 4219,3057,2871,6953,6954,6955,6956,4467,6957,2711,6958,6959,6960,3275,3101,4843, // 5984 6961,3357,3569,6962,4844,6963,6964,4468,4845,3570,6965,3102,4846,3758,6966,4847, // 6000 3878,4848,4849,4029,6967,2929,3879,4850,4851,6968,6969,1733,6970,4220,6971,6972, // 6016 6973,6974,6975,6976,4852,6977,6978,6979,6980,6981,6982,3759,6983,6984,6985,3486, // 6032 3487,6986,3488,3416,6987,6988,6989,6990,6991,6992,6993,6994,6995,6996,6997,4853, // 6048 6998,6999,4030,7000,7001,3211,7002,7003,4221,7004,7005,3571,4031,7006,3572,7007, // 6064 2614,4854,2577,7008,7009,2965,3655,3656,4855,2775,3489,3880,4222,4856,3881,4032, // 6080 3882,3657,2730,3490,4857,7010,3149,7011,4469,4858,2496,3491,4859,2283,7012,7013, // 6096 7014,2365,4860,4470,7015,7016,3760,7017,7018,4223,1917,7019,7020,7021,4471,7022, // 6112 2776,4472,7023,7024,7025,7026,4033,7027,3573,4224,4861,4034,4862,7028,7029,1929, // 6128 3883,4035,7030,4473,3058,7031,2536,3761,3884,7032,4036,7033,2966,2895,1968,4474, // 6144 3276,4225,3417,3492,4226,2105,7034,7035,1754,2596,3762,4227,4863,4475,3763,4864, // 6160 3764,2615,2777,3103,3765,3658,3418,4865,2296,3766,2815,7036,7037,7038,3574,2872, // 6176 3277,4476,7039,4037,4477,7040,7041,4038,7042,7043,7044,7045,7046,7047,2537,7048, // 6192 7049,7050,7051,7052,7053,7054,4478,7055,7056,3767,3659,4228,3575,7057,7058,4229, // 6208 7059,7060,7061,3660,7062,3212,7063,3885,4039,2460,7064,7065,7066,7067,7068,7069, // 6224 7070,7071,7072,7073,7074,4866,3768,4867,7075,7076,7077,7078,4868,3358,3278,2653, // 6240 7079,7080,4479,3886,7081,7082,4869,7083,7084,7085,7086,7087,7088,2538,7089,7090, // 6256 7091,4040,3150,3769,4870,4041,2896,3359,4230,2930,7092,3279,7093,2967,4480,3213, // 6272 4481,3661,7094,7095,7096,7097,7098,7099,7100,7101,7102,2461,3770,7103,7104,4231, // 6288 3151,7105,7106,7107,4042,3662,7108,7109,4871,3663,4872,4043,3059,7110,7111,7112, // 6304 3493,2988,7113,4873,7114,7115,7116,3771,4874,7117,7118,4232,4875,7119,3576,2336, // 6320 4876,7120,4233,3419,4044,4877,4878,4482,4483,4879,4484,4234,7121,3772,4880,1045, // 6336 3280,3664,4881,4882,7122,7123,7124,7125,4883,7126,2778,7127,4485,4486,7128,4884, // 6352 3214,3887,7129,7130,3215,7131,4885,4045,7132,7133,4046,7134,7135,7136,7137,7138, // 6368 7139,7140,7141,7142,7143,4235,7144,4886,7145,7146,7147,4887,7148,7149,7150,4487, // 6384 4047,4488,7151,7152,4888,4048,2989,3888,7153,3665,7154,4049,7155,7156,7157,7158, // 6400 7159,7160,2931,4889,4890,4489,7161,2631,3889,4236,2779,7162,7163,4891,7164,3060, // 6416 7165,1672,4892,7166,4893,4237,3281,4894,7167,7168,3666,7169,3494,7170,7171,4050, // 6432 7172,7173,3104,3360,3420,4490,4051,2684,4052,7174,4053,7175,7176,7177,2253,4054, // 6448 7178,7179,4895,7180,3152,3890,3153,4491,3216,7181,7182,7183,2968,4238,4492,4055, // 6464 7184,2990,7185,2479,7186,7187,4493,7188,7189,7190,7191,7192,4896,7193,4897,2969, // 6480 4494,4898,7194,3495,7195,7196,4899,4495,7197,3105,2731,7198,4900,7199,7200,7201, // 6496 4056,7202,3361,7203,7204,4496,4901,4902,7205,4497,7206,7207,2315,4903,7208,4904, // 6512 7209,4905,2851,7210,7211,3577,7212,3578,4906,7213,4057,3667,4907,7214,4058,2354, // 6528 3891,2376,3217,3773,7215,7216,7217,7218,7219,4498,7220,4908,3282,2685,7221,3496, // 6544 4909,2632,3154,4910,7222,2337,7223,4911,7224,7225,7226,4912,4913,3283,4239,4499, // 6560 7227,2816,7228,7229,7230,7231,7232,7233,7234,4914,4500,4501,7235,7236,7237,2686, // 6576 7238,4915,7239,2897,4502,7240,4503,7241,2516,7242,4504,3362,3218,7243,7244,7245, // 6592 4916,7246,7247,4505,3363,7248,7249,7250,7251,3774,4506,7252,7253,4917,7254,7255, // 6608 3284,2991,4918,4919,3219,3892,4920,3106,3497,4921,7256,7257,7258,4922,7259,4923, // 6624 3364,4507,4508,4059,7260,4240,3498,7261,7262,4924,7263,2992,3893,4060,3220,7264, // 6640 7265,7266,7267,7268,7269,4509,3775,7270,2817,7271,4061,4925,4510,3776,7272,4241, // 6656 4511,3285,7273,7274,3499,7275,7276,7277,4062,4512,4926,7278,3107,3894,7279,7280, // 6672 4927,7281,4513,7282,7283,3668,7284,7285,4242,4514,4243,7286,2058,4515,4928,4929, // 6688 4516,7287,3286,4244,7288,4517,7289,7290,7291,3669,7292,7293,4930,4931,4932,2355, // 6704 4933,7294,2633,4518,7295,4245,7296,7297,4519,7298,7299,4520,4521,4934,7300,4246, // 6720 4522,7301,7302,7303,3579,7304,4247,4935,7305,4936,7306,7307,7308,7309,3777,7310, // 6736 4523,7311,7312,7313,4248,3580,7314,4524,3778,4249,7315,3581,7316,3287,7317,3221, // 6752 7318,4937,7319,7320,7321,7322,7323,7324,4938,4939,7325,4525,7326,7327,7328,4063, // 6768 7329,7330,4940,7331,7332,4941,7333,4526,7334,3500,2780,1741,4942,2026,1742,7335, // 6784 7336,3582,4527,2388,7337,7338,7339,4528,7340,4250,4943,7341,7342,7343,4944,7344, // 6800 7345,7346,3020,7347,4945,7348,7349,7350,7351,3895,7352,3896,4064,3897,7353,7354, // 6816 7355,4251,7356,7357,3898,7358,3779,7359,3780,3288,7360,7361,4529,7362,4946,4530, // 6832 2027,7363,3899,4531,4947,3222,3583,7364,4948,7365,7366,7367,7368,4949,3501,4950, // 6848 3781,4951,4532,7369,2517,4952,4252,4953,3155,7370,4954,4955,4253,2518,4533,7371, // 6864 7372,2712,4254,7373,7374,7375,3670,4956,3671,7376,2389,3502,4065,7377,2338,7378, // 6880 7379,7380,7381,3061,7382,4957,7383,7384,7385,7386,4958,4534,7387,7388,2993,7389, // 6896 3062,7390,4959,7391,7392,7393,4960,3108,4961,7394,4535,7395,4962,3421,4536,7396, // 6912 4963,7397,4964,1857,7398,4965,7399,7400,2176,3584,4966,7401,7402,3422,4537,3900, // 6928 3585,7403,3782,7404,2852,7405,7406,7407,4538,3783,2654,3423,4967,4539,7408,3784, // 6944 3586,2853,4540,4541,7409,3901,7410,3902,7411,7412,3785,3109,2327,3903,7413,7414, // 6960 2970,4066,2932,7415,7416,7417,3904,3672,3424,7418,4542,4543,4544,7419,4968,7420, // 6976 7421,4255,7422,7423,7424,7425,7426,4067,7427,3673,3365,4545,7428,3110,2559,3674, // 6992 7429,7430,3156,7431,7432,3503,7433,3425,4546,7434,3063,2873,7435,3223,4969,4547, // 7008 4548,2898,4256,4068,7436,4069,3587,3786,2933,3787,4257,4970,4971,3788,7437,4972, // 7024 3064,7438,4549,7439,7440,7441,7442,7443,4973,3905,7444,2874,7445,7446,7447,7448, // 7040 3021,7449,4550,3906,3588,4974,7450,7451,3789,3675,7452,2578,7453,4070,7454,7455, // 7056 7456,4258,3676,7457,4975,7458,4976,4259,3790,3504,2634,4977,3677,4551,4260,7459, // 7072 7460,7461,7462,3907,4261,4978,7463,7464,7465,7466,4979,4980,7467,7468,2213,4262, // 7088 7469,7470,7471,3678,4981,7472,2439,7473,4263,3224,3289,7474,3908,2415,4982,7475, // 7104 4264,7476,4983,2655,7477,7478,2732,4552,2854,2875,7479,7480,4265,7481,4553,4984, // 7120 7482,7483,4266,7484,3679,3366,3680,2818,2781,2782,3367,3589,4554,3065,7485,4071, // 7136 2899,7486,7487,3157,2462,4072,4555,4073,4985,4986,3111,4267,2687,3368,4556,4074, // 7152 3791,4268,7488,3909,2783,7489,2656,1962,3158,4557,4987,1963,3159,3160,7490,3112, // 7168 4988,4989,3022,4990,4991,3792,2855,7491,7492,2971,4558,7493,7494,4992,7495,7496, // 7184 7497,7498,4993,7499,3426,4559,4994,7500,3681,4560,4269,4270,3910,7501,4075,4995, // 7200 4271,7502,7503,4076,7504,4996,7505,3225,4997,4272,4077,2819,3023,7506,7507,2733, // 7216 4561,7508,4562,7509,3369,3793,7510,3590,2508,7511,7512,4273,3113,2994,2616,7513, // 7232 7514,7515,7516,7517,7518,2820,3911,4078,2748,7519,7520,4563,4998,7521,7522,7523, // 7248 7524,4999,4274,7525,4564,3682,2239,4079,4565,7526,7527,7528,7529,5000,7530,7531, // 7264 5001,4275,3794,7532,7533,7534,3066,5002,4566,3161,7535,7536,4080,7537,3162,7538, // 7280 7539,4567,7540,7541,7542,7543,7544,7545,5003,7546,4568,7547,7548,7549,7550,7551, // 7296 7552,7553,7554,7555,7556,5004,7557,7558,7559,5005,7560,3795,7561,4569,7562,7563, // 7312 7564,2821,3796,4276,4277,4081,7565,2876,7566,5006,7567,7568,2900,7569,3797,3912, // 7328 7570,7571,7572,4278,7573,7574,7575,5007,7576,7577,5008,7578,7579,4279,2934,7580, // 7344 7581,5009,7582,4570,7583,4280,7584,7585,7586,4571,4572,3913,7587,4573,3505,7588, // 7360 5010,7589,7590,7591,7592,3798,4574,7593,7594,5011,7595,4281,7596,7597,7598,4282, // 7376 5012,7599,7600,5013,3163,7601,5014,7602,3914,7603,7604,2734,4575,4576,4577,7605, // 7392 7606,7607,7608,7609,3506,5015,4578,7610,4082,7611,2822,2901,2579,3683,3024,4579, // 7408 3507,7612,4580,7613,3226,3799,5016,7614,7615,7616,7617,7618,7619,7620,2995,3290, // 7424 7621,4083,7622,5017,7623,7624,7625,7626,7627,4581,3915,7628,3291,7629,5018,7630, // 7440 7631,7632,7633,4084,7634,7635,3427,3800,7636,7637,4582,7638,5019,4583,5020,7639, // 7456 3916,7640,3801,5021,4584,4283,7641,7642,3428,3591,2269,7643,2617,7644,4585,3592, // 7472 7645,4586,2902,7646,7647,3227,5022,7648,4587,7649,4284,7650,7651,7652,4588,2284, // 7488 7653,5023,7654,7655,7656,4589,5024,3802,7657,7658,5025,3508,4590,7659,7660,7661, // 7504 1969,5026,7662,7663,3684,1821,2688,7664,2028,2509,4285,7665,2823,1841,7666,2689, // 7520 3114,7667,3917,4085,2160,5027,5028,2972,7668,5029,7669,7670,7671,3593,4086,7672, // 7536 4591,4087,5030,3803,7673,7674,7675,7676,7677,7678,7679,4286,2366,4592,4593,3067, // 7552 2328,7680,7681,4594,3594,3918,2029,4287,7682,5031,3919,3370,4288,4595,2856,7683, // 7568 3509,7684,7685,5032,5033,7686,7687,3804,2784,7688,7689,7690,7691,3371,7692,7693, // 7584 2877,5034,7694,7695,3920,4289,4088,7696,7697,7698,5035,7699,5036,4290,5037,5038, // 7600 5039,7700,7701,7702,5040,5041,3228,7703,1760,7704,5042,3229,4596,2106,4089,7705, // 7616 4597,2824,5043,2107,3372,7706,4291,4090,5044,7707,4091,7708,5045,3025,3805,4598, // 7632 4292,4293,4294,3373,7709,4599,7710,5046,7711,7712,5047,5048,3806,7713,7714,7715, // 7648 5049,7716,7717,7718,7719,4600,5050,7720,7721,7722,5051,7723,4295,3429,7724,7725, // 7664 7726,7727,3921,7728,3292,5052,4092,7729,7730,7731,7732,7733,7734,7735,5053,5054, // 7680 7736,7737,7738,7739,3922,3685,7740,7741,7742,7743,2635,5055,7744,5056,4601,7745, // 7696 7746,2560,7747,7748,7749,7750,3923,7751,7752,7753,7754,7755,4296,2903,7756,7757, // 7712 7758,7759,7760,3924,7761,5057,4297,7762,7763,5058,4298,7764,4093,7765,7766,5059, // 7728 3925,7767,7768,7769,7770,7771,7772,7773,7774,7775,7776,3595,7777,4299,5060,4094, // 7744 7778,3293,5061,7779,7780,4300,7781,7782,4602,7783,3596,7784,7785,3430,2367,7786, // 7760 3164,5062,5063,4301,7787,7788,4095,5064,5065,7789,3374,3115,7790,7791,7792,7793, // 7776 7794,7795,7796,3597,4603,7797,7798,3686,3116,3807,5066,7799,7800,5067,7801,7802, // 7792 4604,4302,5068,4303,4096,7803,7804,3294,7805,7806,5069,4605,2690,7807,3026,7808, // 7808 7809,7810,7811,7812,7813,7814,7815,7816,7817,7818,7819,7820,7821,7822,7823,7824, // 7824 7825,7826,7827,7828,7829,7830,7831,7832,7833,7834,7835,7836,7837,7838,7839,7840, // 7840 7841,7842,7843,7844,7845,7846,7847,7848,7849,7850,7851,7852,7853,7854,7855,7856, // 7856 7857,7858,7859,7860,7861,7862,7863,7864,7865,7866,7867,7868,7869,7870,7871,7872, // 7872 7873,7874,7875,7876,7877,7878,7879,7880,7881,7882,7883,7884,7885,7886,7887,7888, // 7888 7889,7890,7891,7892,7893,7894,7895,7896,7897,7898,7899,7900,7901,7902,7903,7904, // 7904 7905,7906,7907,7908,7909,7910,7911,7912,7913,7914,7915,7916,7917,7918,7919,7920, // 7920 7921,7922,7923,7924,3926,7925,7926,7927,7928,7929,7930,7931,7932,7933,7934,7935, // 7936 7936,7937,7938,7939,7940,7941,7942,7943,7944,7945,7946,7947,7948,7949,7950,7951, // 7952 7952,7953,7954,7955,7956,7957,7958,7959,7960,7961,7962,7963,7964,7965,7966,7967, // 7968 7968,7969,7970,7971,7972,7973,7974,7975,7976,7977,7978,7979,7980,7981,7982,7983, // 7984 7984,7985,7986,7987,7988,7989,7990,7991,7992,7993,7994,7995,7996,7997,7998,7999, // 8000 8000,8001,8002,8003,8004,8005,8006,8007,8008,8009,8010,8011,8012,8013,8014,8015, // 8016 8016,8017,8018,8019,8020,8021,8022,8023,8024,8025,8026,8027,8028,8029,8030,8031, // 8032 8032,8033,8034,8035,8036,8037,8038,8039,8040,8041,8042,8043,8044,8045,8046,8047, // 8048 8048,8049,8050,8051,8052,8053,8054,8055,8056,8057,8058,8059,8060,8061,8062,8063, // 8064 8064,8065,8066,8067,8068,8069,8070,8071,8072,8073,8074,8075,8076,8077,8078,8079, // 8080 8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8091,8092,8093,8094,8095, // 8096 8096,8097,8098,8099,8100,8101,8102,8103,8104,8105,8106,8107,8108,8109,8110,8111, // 8112 8112,8113,8114,8115,8116,8117,8118,8119,8120,8121,8122,8123,8124,8125,8126,8127, // 8128 8128,8129,8130,8131,8132,8133,8134,8135,8136,8137,8138,8139,8140,8141,8142,8143, // 8144 8144,8145,8146,8147,8148,8149,8150,8151,8152,8153,8154,8155,8156,8157,8158,8159, // 8160 8160,8161,8162,8163,8164,8165,8166,8167,8168,8169,8170,8171,8172,8173,8174,8175, // 8176 8176,8177,8178,8179,8180,8181,8182,8183,8184,8185,8186,8187,8188,8189,8190,8191, // 8192 8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8203,8204,8205,8206,8207, // 8208 8208,8209,8210,8211,8212,8213,8214,8215,8216,8217,8218,8219,8220,8221,8222,8223, // 8224 8224,8225,8226,8227,8228,8229,8230,8231,8232,8233,8234,8235,8236,8237,8238,8239, // 8240 8240,8241,8242,8243,8244,8245,8246,8247,8248,8249,8250,8251,8252,8253,8254,8255, // 8256 8256,8257,8258,8259,8260,8261,8262,8263,8264,8265,8266,8267,8268,8269,8270,8271, // 8272 ****************************************************************************************/ };