From 4c4d6b8f727003691f639d81ed42fb1a5faaf4d3 Mon Sep 17 00:00:00 2001 From: Packit Date: Sep 14 2020 10:06:16 +0000 Subject: json-glib-1.4.4 base --- diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..b1e3f5a --- /dev/null +++ b/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. + + GNU LESSER GENERAL PUBLIC LICENSE + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..ec31653 --- /dev/null +++ b/NEWS @@ -0,0 +1,157 @@ +Overview of changes for 1.4 +============================== +• Use Meson as the only build system +• #773504 - Avoid extra allocations [Garrett Regier] +• #780550 - meson error looking for python3 [Daniele Forghieri] +• #769206 - docs: Clarify when NULL might be returned [Matthew Leeds] +• #766281 - utils/json_from_string: Don't reset user-provided error + argument [Heinrich Fink] +• #758580 - json_reader_is_value returns TRUE for null type but + json_reader_get_value throws an error [Robert Ancell] +• #768788 - Incorrect account of jsonPath syntax in doc [Allin Cottrell] +• #774688 - json_from_string() could be optimized to avoid copying the + root node [Ole André Vadla Ravnås] + +Overview of changes for 1.2 +============================== +• Add simple wrapper functions for JsonGenerator and JsonParser to + write and read a string from and to a JsonNode, respectively +• Drop use of deprecated GIO API +• Bump the dependency on GLib to 2.46 +• Do not create `null` nodes for empty strings [#730803] +• Documentation fixes [Philip Withnall - #754384] +• Avoid crashes in the test suite [Iain Lane - #755977] +• Add simple iterator object for JSON objects [Philip Withnall - #755509] +• Detect missing commas in arrays +• Add support for g_auto* macros +• Allow making JSON types optionally immutable, in order to allow + efficient hashing and equality tests [Philip Withnal - #756121] +• Improve the build under MSVC [Chun-wei Fan] +• Add Meson build system [Thibault Saunier - #773603] +• Support Visual Studio 2017 [Chun-wei Fan] +• Allow using G_DECLARE_INTERFACE with JsonSerializable +• Allow empty strings as JsonObject member names [Dr. David Alan Gilbert - #747279] + +Overview of changes for 1.0 +============================== +• Bump the dependency on GLib to 2.38 +• Use the TAP driver for the test suite +• Improve the syntax validation in JsonPath +• Validate the JsonParser input to be UTF-8 +• Add command line tools for validating and formatting JSON +• Improve documentation + +Overview of changes for 0.16.0 +============================== +• Fixes for building with VisualStudio. [Chun-wei Fan] +• Allow out-of-tree builds. [Colin Walters] +• Bump the dependency on GLib to 2.31. +• Use the new deprecation system provided by GLib. +• Simplify the value handling inside JsonNode. +• Use lcov to generate coverage reports for the test suite. +• Check expected ABI when building. +• Drop dependency on gnome-autogen.sh when building from Git. + +Overview of changes for 0.14.0 +============================== +• Documentation fixes +• Bump the dependency on GLib to 2.26 +• Allow building on Windows using VisualStudio [Chun-wei Fan] +• Add JSON ↔ GVariant translation [Eduardo Lima Mitev] +• Improve sanity checks when (de)serializing GObject + properties [Tristan Van Berkom] +• Add missing introspection annotations [Luca Bruno] +• Add JsonReader.list_members() +• Allow using JsonReader.read_element() on JSON objects +• Remove all G_CONST_RETURN usage after the deprecation +• Allow JsonSerializable to override the introspection and + modification of properties +• Add i18n support for GError messages +• Do not serialize GObject properties that match their default + values. +• Make JsonReader perform a stricter validation especially when using + the strongly typed accessors. + +Overview of changes for 0.12.0 +============================== +• Support surrogate pairs in JSON strings [Eiichi Sato] +• Update the test suite +• Add (optional) coverage reports +• Improve strictness of JsonParser +• Improve error reporting of JsonParser +• Add JsonBuilder, a convenience API for programmatic building + of JSON trees [Luca Bruno] +• Add methods for JsonParser and JsonGenerator to handle Input|OutputStream + objects coming from GIO. +• Add JsonReader, a convenience API for cursor-based parsing of + JSON trees +• Depend on GObject-Introspection ≥ 0.9.5 + +Overview of changes for 0.10.0 +============================== +• Fix generation of doubles [Cornelius Hald] +• Add more units to the test suite +• Add JsonNode macros for quick type checking +• Guarantee insertion order when parsing and generating JSON Objects +• Serialize GParamSpecObject properties +• Add serialization and deserialization for GBoxed types +• Add API for serializing GObjects to, and deserializing from, JsonNode +• Build environment fixes +• Documentation fixes +• Generate correct introspection data +• Make JsonSerializable in complete control of deserialization [Tristan Van + Berkom] + +Overview of changes for 0.8.0 +============================= +* Remove the in-tree Vala bindings: they are part of Vala, now +* Remove the in-tree Debian packaging +* Fix bug #958: JsonGenerator does not escape special characters +* Fix bug #965: Conditionally compile the test suite +* Display the filename and line inside the error messages when + loading from a file +* Fix bug #1203: Correctly terminate a string array +* Fix bug #1393: Regression tests fail on OpenBSD +* Do not leak memory on error code paths +* Improve and clean up the build system +* Make JsonNode completely opaque +* Conditionally generate introspection data on build +* Fix bug #1353: Do not overwrite when copying +* Deprecate json_object_add_member() +* Add convenience accessors for JsonObject and JsonArray +* Add convenience iteration functions for JsonObject and JsonArray +* Automatically promote integers to gint64, to compensate for the + lack of integer size in the JSON specificiation +* Disallow the inclusion of single header files: only json-glib,h + and json-gobject.h can be included directly +* Documentation fixes +* Clean up and remove code duplication inside the Parser object + +Overview of changes for 0.6.0 +============================= +* Allow deserialization of strings into enum and flag types +* Add the :indent-char property to JsonGenerator +* Add functions to retrieve copies of the nodes inside Object and Array +* Fix leaks and invalid accesses +* Use the right type for the buffer length parameter in JsonParser +* Provide a default implementation for JsonSerializable +* Provide our own JSON tokenizer (using GScanner) for the JSON-only + features that would have been lost by using GScanner +* Add a fully automated test suite, using the GTest framework +* Allow 'null' nodes to return a value without warnings +* Add support for parsing Unicode characters escaped using \uXXXX +* Make the deserialization of G_TYPE_STRV properties more robust +* Export the public symbols only +* Provide GTypes for the enumerations +* Avoid a warning when trying to copy an empty JsonNode +* Fix gtk-doc cross-references with GLib and GObject documentation + +Overview of changes for 0.4.0 +============================= +* Support parsing of negative numbers +* Fix parse error propagation and message +* More parser sanity checks +* GObject deserialization support +* Detect and parse JSON masked as a JavaScript assignment +* Allow using JsonNode with GObject properties and signals +* Add JsonGenerator:root property diff --git a/README.md b/README.md new file mode 100644 index 0000000..24d68ec --- /dev/null +++ b/README.md @@ -0,0 +1,117 @@ +JSON-GLib +=============================================================================== + +JSON-GLib implements a full suite of JSON-related tools using GLib and GObject. + +Use JSON-GLib it is possible to parse and generate valid JSON data +structures using a DOM-like API. JSON-GLib also integrates with GObject to +provide the ability to serialize and deserialize GObject instances to and from +JSON data types. + +JSON is the JavaScript Object Notation; it can be used to represent objects and +object hierarchies while retaining human-readability. + +GLib is a C library providing common and efficient data types for the C +developers. + +GObject is a library providing a run-time Object Oriented type system for C +developers. GLib and GObject are extensively used by the GTK+ toolkit and by the +[GNOME][gnome] project. + +For more information, see: + + * [JSON][json] + * [GLib and GObject][glib] + * [JSON-GLib][json-glib] + +Requirements +-------------------------------------------------------------------------------- +In order to build JSON-GLib you will need: + + * python3 + * [ninja](http://ninja-build.org) + * [meson](http://mesonbuild.com) + * pkg-config + * gtk-doc ≥ 1.13 (optional) + * GLib, GIO ≥ 2.38 + * GObject-Introspection ≥ 1.38 (optional) + +Build and installation +-------------------------------------------------------------------------------- +To build JSON-GLib just run: + +```sh + $ meson _build . + $ ninja -C _build + $ mesontest -C _build + $ sudo ninja -C _build install +``` + +See the [Meson documentation](http://mesonbuild.com) for more information. + +Contributing +-------------------------------------------------------------------------------- +If you find a bug in JSON-GLib, please file an issue on the +[Issues page][gitlab-issues]. + +Required information: + + * the version of JSON-GLib + * if it is a development version, the branch of the git repository + * the JSON data that produced the bug (if any) + * a small, self-contained test case, if none of the test units exhibit the + buggy behaviour + * in case of a segmentation fault, a full stack trace with debugging + symbols obtained through gdb is greatly appreaciated + +JSON-GLib is developed mainly inside a GIT repository available at: + + https://gitlab.gnome.org/GNOME/json-glib/ + +You can clone the GIT repository with: + + git clone https://gitlab.gnome.org/GNOME/json-glib.git + +If you want to contribute functionality or bug fixes to JSON-GLib you should +fork the json-glib repository, work on a separate branch, and then open a +merge request on Gitlab: + + https://gitlab.gnome.org/GNOME/json-glib/merge_requests/new + +Please, try to conform to the coding style used by JSON-GLib, which is the same +used by projects like GLib, [GTK+][gtk-coding-style], and Clutter. Coding style +conformance is a requirement for upstream acceptance. + +Make sure you always run the test suite when you are fixing bugs. New features +should come with a test unit. Patches that regress the test suite will be +rejected. + +Release notes +-------------------------------------------------------------------------------- + * Prior to JSON-GLib 0.10, a JsonSerializable implementation could + automatically fall back to the default serialization code by simply + returning NULL from an overridden JsonSerializable::serialize-property + virtual function. Since JSON-GLib 0.10 this is not possible any more. A + JsonSerializable is always expected to serialize and deserialize all + properties. JSON-GLib provides public API for the default implementation + in case the serialization code wants to fall back to that. + +Copyright and licensing +-------------------------------------------------------------------------------- +JSON-GLib has been written by Emmanuele Bassi + +JSON-GLib is released under the terms of the GNU Lesser General Public License, +either version 2.1 or (at your option) any later version. + +See the file COPYING for details. + +Copyright 2007, 2008 OpenedHand Ltd +Copyright 2009, 2010, 2011, 2012 Intel Corp. +Copyright 2013 Emmanuele Bassi + +[json]: http://www.json.org "JSON" +[glib]: http://www.gtk.org "GTK+" +[json-glib]: https://wiki.gnome.org/Projects/JsonGlib "JSON-GLib wiki" +[gnome]: https://www.gnome.org "GNOME" +[gitlab-issues]: https://gitlab.gnome.org/GNOME/json-glib/issues +[gtk-coding-style]: https://git.gnome.org/browse/gtk+/tree/docs/CODING-STYLE diff --git a/build-aux/gen-installed-test.py b/build-aux/gen-installed-test.py new file mode 100644 index 0000000..8fe4265 --- /dev/null +++ b/build-aux/gen-installed-test.py @@ -0,0 +1,19 @@ +import sys +import os +import argparse + +def write_template(filename, data): + with open(filename, 'w') as f: + f.write(data) + +def build_template(testdir, testname): + return "[Test]\nType=session\nExec={}\n".format(os.path.join(testdir, testname)) + +argparser = argparse.ArgumentParser(description='Generate installed-test data.') +argparser.add_argument('--testdir', metavar='dir', required=True, help='Installed test directory') +argparser.add_argument('--testname', metavar='name', required=True, help='Installed test name') +argparser.add_argument('--outfile', metavar='file', required=True, help='Output file') +argparser.add_argument('--outdir', metavar='dir', required=True, help='Output directory') +args = argparser.parse_args() + +write_template(os.path.join(args.outdir, args.outfile), build_template(args.testdir, args.testname)) diff --git a/build-aux/make_release.sh b/build-aux/make_release.sh new file mode 100755 index 0000000..8c69990 --- /dev/null +++ b/build-aux/make_release.sh @@ -0,0 +1,19 @@ +#!/bin/sh +test -n "$srcdir" || srcdir=$(dirname "$0") +test -n "$srcdir" || srcdir=. + +cd $srcdir + +PROJECT=json-glib +VERSION=$(git describe --abbrev=0) + +NAME="${PROJECT}-${VERSION}" + +rm -f "${NAME}.tar" +rm -f "${NAME}.tar.xz" + +echo "Creating git tree archive…" +git archive --prefix="${NAME}/" --format=tar HEAD > ${NAME}.tar + +echo "Compressing archive…" +xz -f "${NAME}.tar" diff --git a/configure b/configure new file mode 100755 index 0000000..5fe09a6 --- /dev/null +++ b/configure @@ -0,0 +1,156 @@ +#!/bin/bash +# configure script adapter for Meson +# Based on build-api: https://github.com/cgwalters/build-api +# Copyright 2010, 2011, 2013 Colin Walters +# Copyright 2016, 2017 Emmanuele Bassi +# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php) + +# Build API variables: + +# Little helper function for reading args from the commandline. +# it automatically handles -a b and -a=b variants, and returns 1 if +# we need to shift $3. +read_arg() { + # $1 = arg name + # $2 = arg value + # $3 = arg parameter + local rematch='^[^=]*=(.*)$' + if [[ $2 =~ $rematch ]]; then + read "$1" <<< "${BASH_REMATCH[1]}" + else + read "$1" <<< "$3" + # There is no way to shift our callers args, so + # return 1 to indicate they should do it instead. + return 1 + fi +} + +sanitycheck() { + # $1 = arg name + # $1 = arg command + # $2 = arg alternates + local cmd=$( which $2 2>/dev/null ) + + if [ -x "$cmd" ]; then + read "$1" <<< "$cmd" + return 0 + fi + + test -z $3 || { + for alt in $3; do + cmd=$( which $alt 2>/dev/null ) + + if [ -x "$cmd" ]; then + read "$1" <<< "$cmd" + return 0 + fi + done + } + + echo -e "\e[1;31mERROR\e[0m: Command '$2' not found" + exit 1 +} + +sanitycheck MESON 'meson' +sanitycheck MESONTEST 'mesontest' +sanitycheck NINJA 'ninja' 'ninja-build' + +enable_docs='-Ddocs=false' +enable_introspection='-Dintrospection=true' + +while (($# > 0)); do + case "${1%%=*}" in + --prefix) read_arg prefix "$@" || shift;; + --bindir) read_arg bindir "$@" || shift;; + --sbindir) read_arg sbindir "$@" || shift;; + --libexecdir) read_arg libexecdir "$@" || shift;; + --datarootdir) read_arg datarootdir "$@" || shift;; + --datadir) read_arg datadir "$@" || shift;; + --sysconfdir) read_arg sysconfdir "$@" || shift;; + --libdir) read_arg libdir "$@" || shift;; + --mandir) read_arg mandir "$@" || shift;; + --includedir) read_arg includedir "$@" || shift;; + --enable-gtk-doc) enable_docs='-Ddocs=true';; + --disable-gtk-doc) enable_docs='-Ddocs=false';; + --enable-introspection) enable_introspection='-Dintrospection=true';; + --disable-introspection) enable_introspection='-Dintrospection=false';; + *) echo -e "\e[1;33mINFO\e[0m: Ignoring unknown option '$1'";; + esac + shift +done + +# Defaults +test -z ${prefix} && prefix="/usr/local" +test -z ${bindir} && bindir=${prefix}/bin +test -z ${sbindir} && sbindir=${prefix}/sbin +test -z ${libexecdir} && libexecdir=${prefix}/bin +test -z ${datarootdir} && datarootdir=${prefix}/share +test -z ${datadir} && datadir=${datarootdir} +test -z ${sysconfdir} && sysconfdir=${prefix}/etc +test -z ${libdir} && libdir=${prefix}/lib +test -z ${mandir} && mandir=${prefix}/share/man +test -z ${includedir} && includedir=${prefix}/include + +# The source directory is the location of this file +srcdir=$(dirname $0) + +# The build directory is the current location +builddir=`pwd` + +# If we're calling this file from the source directory then +# we automatically create a build directory and ensure that +# both Meson and Ninja invocations are relative to that +# location +if [[ -f "${builddir}/meson.build" ]]; then + mkdir -p _build + builddir="${builddir}/_build" + NINJA_OPT="-C ${builddir}" +fi + +# Wrapper Makefile for Ninja +cat > Makefile <; rel="describedby" + + Instances MAY specify multiple schemas, to indicate all the schemas + that are applicable to the data. The instance data may have multiple + schemas that it is defined by (the instance data should be valid for + those schemas). Or if the document is a collection of instances, the + collection may contain instances from different schemas. When + collections contain heterogeneous instances, the pathStart attribute + MAY be specified in the schema to disambiguate which schema should be + applied for each item in the collection. + +4.1. Self-Descriptive Schema + + JSON Schemas are themselves instances for the schema schemas. A + self-describing JSON Schema for the core JSON Schema can be found at + http://json-schema.org/schema and the hyper schema self-description + can be found at: http://json-schema.org/hyper-schema. All schemas + used within a protocol with media type definitions SHOULD include a + MIME parameter that refers to the self-descriptive hyper schema or + another schema that extends this hyper schema: + + + Content-Type: application/json; + profile=http://www.json-schema.org/hyper-schema + +5. Core Schema Definition + + A JSON Schema is a JSON Object that defines various attributes of the + instance and defines it's usage and valid values. A JSON Schema is a + JSON Object with schema attribute properties. The following is the + grammar of a JSON Schema: + + And an example JSON Schema definition could look like: + + + {"description":"A person", + "type":"object", + + "properties": + {"name": {"type":"string"}, + "age" : {"type":"integer", + "maximum":125}} + } + + A JSON Schema object may have any of the following properties, called + + + +Zyp Expires September 24, 2010 [Page 7] + +Internet-Draft JSON Schema Media Type March 2010 + + + schema attributes (all attributes are optional): + +5.1. type + + Union type definition - An array with two or more items which + indicates a union of type definitions. Each item in the array may + be a simple type definition or a schema. The instance value is + valid if it is of the same type as one the type definitions in the + array or if it is valid by one of the schemas in the array. For + example to indicate that a string or number is a valid: {"type": + ["string","number"]} + + Simple type definition - A string indicating a primitive or simple + type. The following are acceptable strings: + + string - Value must be a string. + + number - Value must be a number, floating point numbers are + allowed. + + integer - Value must be an integer, no floating point numbers + are allowed. This is a subset of the number type. + + boolean - Value must be a boolean. + + object - Value must be an object. + + array - Value must be an array. + + null - Value must be null. Note this is mainly for purpose of + being able use union types to define nullability. + + any - Value may be of any type including null. If the property + is not defined or is not in this list, than any type of value + is acceptable. Other type values may be used for custom + purposes, but minimal validators of the specification + implementation can allow any instance value on unknown type + values. + +5.2. properties + + This should be an object type definition, which is an object with + property definitions that correspond to instance object properties. + When the instance value is an object, the property values of the + instance object must conform to the property definitions in this + object. In this object, each property definition's value should be a + schema, and the property's name should be the name of the instance + property that it defines. + + + +Zyp Expires September 24, 2010 [Page 8] + +Internet-Draft JSON Schema Media Type March 2010 + + +5.3. items + + This should be a schema or an array of schemas. When this is an + object/schema and the instance value is an array, all the items in + the array must conform to this schema. When this is an array of + schemas and the instance value is an array, each position in the + instance array must conform to the schema in the corresponding + position for this array. This called tuple typing. When tuple + typing is used, additional items are allowed, disallowed, or + constrained by the additionalProperties attribute using the same + rules as extra properties for objects. The default value is an empty + schema which allows any value for items in the instance array. + +5.4. optional + + This indicates that the instance property in the instance object is + optional. This is false by default. + +5.5. additionalProperties + + This provides a default property definition for all properties that + are not explicitly defined in an object type definition. The value + must be a schema. If false is provided, no additional properties are + allowed, and the schema can not be extended. The default value is an + empty schema which allows any value for additional properties. + +5.6. requires + + This indicates that if this property is present in the containing + instance object, the property given by requires attribute must also + be present in the containing instance object. The value of this + property may be a string, indicating the require property name. Or + the value may be a schema, in which case the containing instance must + be valid by the schema if the property is present. For example if a + object type definition is defined: + + + { + "state": + { + "optional":true + }, + "town": + { + "requires":"state", + "optional":true + } + } + + + +Zyp Expires September 24, 2010 [Page 9] + +Internet-Draft JSON Schema Media Type March 2010 + + + An instance must include a state property if a town property is + included. If a town property is not included, the state property is + optional. + +5.7. minimum + + This indicates the minimum value for the instance property when the + type of the instance value is a number. + +5.8. maximum + + This indicates the minimum value for the instance property when the + type of the instance value is a number. + +5.9. minimumCanEqual + + If the minimum is defined, this indicates whether or not the instance + property value can equal the minimum. + +5.10. maximumCanEqual + + If the maximum is defined, this indicates whether or not the instance + property value can equal the maximum. + +5.11. minItems + + This indicates the minimum number of values in an array when an array + is the instance value. + +5.12. maxItems + + This indicates the maximum number of values in an array when an array + is the instance value. + +5.13. uniqueItems + + This indicates that all the items in an array must be unique (no two + identical values) within that array when an array is the instance + value. + +5.14. pattern + + When the instance value is a string, this provides a regular + expression that a instance string value should match in order to be + valid. Regular expressions should follow the regular expression + specification from ECMA 262/Perl 5 + + + + + +Zyp Expires September 24, 2010 [Page 10] + +Internet-Draft JSON Schema Media Type March 2010 + + +5.15. maxLength + + When the instance value is a string, this indicates maximum length of + the string. + +5.16. minLength + + When the instance value is a string, this indicates minimum length of + the string. + +5.17. enum + + This provides an enumeration of possible values that are valid for + the instance property. This should be an array, and each item in the + array represents a possible value for the instance value. If "enum" + is included, the instance value must be one of the values in enum + array in order for the schema to be valid. + +5.18. title + + This provides a short description of the instance property. The + value must be a string. + +5.19. description + + This provides a full description of the of purpose the instance + property. The value must be a string. + +5.20. format + + This property indicates the type of data, content type, or + microformat to be expected in the instance property values. A format + attribute may be one of the values listed below, and if so, should + adhere to the semantics describing for the format. A format should + only be used give meaning to primitive types (string, integer, + number, or boolean). Validators are not required to validate that + the instance values conform to a format. The following formats are + defined: + + Any valid MIME media type may be used as a format value, in which + case the instance property value must be a string, representing + the contents of the MIME file. + + date-time - This should be a date in ISO 8601 format of YYYY-MM- + DDThh:mm:ssZ in UTC time. This is the recommended form of date/ + timestamp. + + + + + +Zyp Expires September 24, 2010 [Page 11] + +Internet-Draft JSON Schema Media Type March 2010 + + + date - This should be a date in the format of YYYY-MM-DD. It is + recommended that you use the "date-time" format instead of "date" + unless you need to transfer only the date part. + + time - This should be a time in the format of hh:mm:ss. It is + recommended that you use the "date-time" format instead of "time" + unless you need to transfer only the time part. + + utc-millisec - This should be the difference, measured in + milliseconds, between the specified time and midnight, January 1, + 1970 UTC. The value should be a number (integer or float). + + regex - A regular expression. + + color - This is a CSS color (like "#FF0000" or "red"). + + style - This is a CSS style definition (like "color: red; + background-color:#FFF"). + + phone - This should be a phone number (format may follow E.123). + + uri - This value should be a URI.. + + email - This should be an email address. + + ip-address - This should be an ip version 4 address. + + ipv6 - This should be an ip version 6 address. + + street-address - This should be a street address. + + locality - This should be a city or town. + + region - This should be a region (a state in the US, province in + Canada, etc.) + + postal-code - This should be a postal code (AKA zip code). + + country - This should be the name of a country. + + Additional custom formats may be defined with a URL to a + definition of the format. + +5.21. contentEncoding + + If the instance property value is a string, this indicates that the + string should be interpreted as binary data and decoded using the + encoding named by this schema property. RFC 2045, Sec 6.1 lists + + + +Zyp Expires September 24, 2010 [Page 12] + +Internet-Draft JSON Schema Media Type March 2010 + + + possible values. + +5.22. default + + This indicates the default for the instance property. + +5.23. divisibleBy + + This indicates that the instance property value must be divisible by + the given schema value when the instance property value is a number. + +5.24. disallow + + This attribute may take the same values as the "type" attribute, + however if the instance matches the type or if this value is an array + and the instance matches any type or schema in the array, than this + instance is not valid. + +5.25. extends + + The value of this property should be another schema which will + provide a base schema which the current schema will inherit from. + The inheritance rules are such that any instance that is valid + according to the current schema must be valid according to the + referenced schema. This may also be an array, in which case, the + instance must be valid for all the schemas in the array. + +6. Hyper Schema + + This section defines hypermedia definitions of JSON schema. The + following attributes are specified in addition to those attributes + that already provided by JSON schema with the specific purpose of + informing user agents of relations between resources based on JSON + data. Just as with JSON schema attributes, all the attributes in + hyper-schema are optional. Therefore an empty object is a valid + (non-informative) schema, and essentially describes plain JSON (no + constraints on the structures). Addition of attributes provides + additive information for user agents. + +6.1. links + + The value of the links property should be an array, where each item + in the array is a link description object which describes the link + relations of the instances. + + + + + + + +Zyp Expires September 24, 2010 [Page 13] + +Internet-Draft JSON Schema Media Type March 2010 + + +6.1.1. Link Description Object + + A link description object is used to describe the link relations. In + the context of a schema, it defines the link relations of the + instances of the schema, and can be parameterized by the instance + values. The link description format can be used on its own in + regular (non-schema documents), and use of this format can be + declared by referencing the normative link description schema as the + the schema for the data structure that uses the links. The URI of + the normative link description schema is: + http://json-schema.org/links. + +6.1.1.1. href + + The value of the "href" link description property indicates the + target URI of the related resource. The value of the instance + property should be resolved as a URI-Reference per [RFC3986] and may + be a relative URI. The base URI to be used for relative resolution + should be the URI used to retrieve the instance object (not the + schema) when used in the context of a schema. Also, the URI may be + parametrized by the property values of the instance object. + + Instance property values should be substituted into the URIs where + matching braces ('{', '}') are found surrounding zero or more + characters, creating an expanded URI. Instance property value + substitutions are resolved by using the text between the braces to + denote the property name from the instance to get the value to + substitute. For example, if an href value is defined: + + + http://somesite.com/{id} + + Then it would be resolved by replace the value of the "id" property + value from the instance object. If the value of the "id" property + was "45", the expanded URI would be: + + + http://somesite.com/45 + + If matching braces are found with the string "-this" (no quotes) + between the braces, than the actual instance value should be used to + replace the braces, rather than a property value. This should only + be used in situations where the instance is a scalar (string, + boolean, or number), and not for objects or arrays. + + + + + + + +Zyp Expires September 24, 2010 [Page 14] + +Internet-Draft JSON Schema Media Type March 2010 + + +6.1.1.2. rel + + The value of the "rel" property indicates the name of the relation to + the target resource. The relation to the target should be + interpreted as specifically from the instance object that the schema + (or sub-schema) applies to, not just the top level resource that + contains the object within its hierarchy. If a resource JSON + representation contains a sub object with a property interpreted as a + link, that sub-object holds the relation with the target. A relation + to target from the top level resource must be indicated with the + schema describing the top level JSON representation. + + Relationship definitions SHOULD NOT be media type dependent, and + users are encouraged to utilize existing accepted relation + definitions, including those in existing relation registries (see + &rfc4287). However, we define these relation here for clarity of + normative interpretation within the context of JSON hyper schema + defined relations: + + self - If the relation value is "self", when this property is + encountered in the instance object, the object represents a + resource and the instance object is treated as a full + representation of the target resource identified by the specified + URI. + + full - This indicates that the target of the link is the full + representation for the instance object. The object that contains + this link may not be the full representation. + + describedby - This indicates the target of the link is the schema + for the instance object. This may be used to specifically denote + the schemas of objects within a JSON object hierarchy, + facilitating polymorphic type data structures. + + The following relations are applicable for schemas (the schema as + the "from" resource in the relation). + + instances - This indicates the target resource that represents + collection of instances of a schema. + + create - This indicates a target to use for creating new instances + of a schema. This link definition SHOULD be a submission link + with a non-safe method (like POST). + + For example, if a schema is defined: + + + + + + +Zyp Expires September 24, 2010 [Page 15] + +Internet-Draft JSON Schema Media Type March 2010 + + + { + "links": [ + { + "rel": "self" + "href": "{id}" + }, + { + "rel": "up" + "href": "{upId}" + }, + { + "rel": "children" + "href": "?upId={id}" + } + ] + } + + And if a collection of instance resource's JSON representation was + retrieved: + + + GET /Resource/ + + [ + { + "id": "thing", + "upId": "parent" + }, + { + "id": "thing2", + "upId": "parent" + } + ] + + This would indicate that for the first item in the collection, it's + own (self) URI would resolve to "/Resource/thing" and the first + item's "up" relation should be resolved to the resource at + "/Resource/parent". The "children" collection would be located at + "/Resource/?upId=thing". + +6.1.1.2.1. targetSchema + + This property value can be a schema that defines the expected + structure of the JSON representation of the target of the link. + + + + + + + +Zyp Expires September 24, 2010 [Page 16] + +Internet-Draft JSON Schema Media Type March 2010 + + +6.1.1.3. Submission Link Properties + + The following properties also apply to link definition objects, and + provide functionality analogous to HTML forms, in providing a means + for submitting extra (often user supplied) information to send to a + server. + +6.1.1.3.1. method + + This indicates which method should be used to access the target + resource. In an HTTP environment, this would be "GET" or "POST" + (other HTTP methods such as "PUT" and "DELETE" have semantics that + are clearly implied by accessed resources, and do not need to be + defined here). This defaults to "GET". + +6.1.1.3.2. enctype + + If present, this property indicates a query media type format that + the server supports for querying or posting to the collection of + instances at the target resource. The query can be suffixed to the + target URI to query the collection with property-based constraints on + the resources that SHOULD be returned from the server or used to post + data to the resource (depending on the method). For example, with + the following schema: + + + { + "links":[ + { + "enctype": "application/x-www-form-urlencoded", + "method": "GET", + "href": "/Product/", + "properties":{ + "name":{"description":"name of the product"} + } + } + ] + } + + This indicates that the client can query the server for instances + that have a specific name: + + + /Product/?name=Slinky + + If no enctype or method is specified, only the single URI specified + by the href property is defined. If the method is POST, application/ + json is the default media type. + + + +Zyp Expires September 24, 2010 [Page 17] + +Internet-Draft JSON Schema Media Type March 2010 + + +6.1.1.3.3. properties + + This is inherited from the base JSON schema definition, and can + follow the same structure, but its meaning should be used to define + the acceptable property names and values for the action (whether it + be for the GET query or POST body). If properties are omitted, and + this form is the child of a schema, the properties from the parent + schema should be used as the basis for the form action. + +6.2. fragmentResolution + + This property indicates the fragment resolution protocol to use for + resolving fragment identifiers in URIs within the instance + representations. This applies to the instance object URIs and all + children of the instance object's URIs. The default fragment + resolution protocol is "slash-delimited", which is defined below. + Other fragment resolution protocols may be used, but are not defined + in this document. + + The fragment identifier is based on RFC 2396 Sec 5, and defines the + mechanism for resolving references to entities within a document. + +6.2.1. dot-delimited fragment resolution + + With the dot-delimited fragment resolution protocol, the fragment + identifier is interpreted as a series of property reference tokens + that are delimited by the "." character (\x2E). Each property + reference token is a series of any legal URI component characters + except the "." character. Each property reference token should be + interpreted, starting from the beginning of the fragment identifier, + as a path reference in the target JSON structure. The final target + value of the fragment can be determined by starting with the root of + the JSON structure from the representation of the resource identified + by the pre-fragment URI. If the target is a JSON object, than the + new target is the value of the property with the name identified by + the next property reference token in the fragment. If the target is + a JSON array, than the target is determined by finding the item in + array the array with the index defined by the next property reference + token (which MUST be a number). The target is successively updated + for each property reference token, until the entire fragment has been + traversed. + + Property names SHOULD be URI-encoded. In particular, any "." in a + property name MUST be encoded to avoid being interpreted as a + property delimiter. + + For example, for the following JSON representation: + + + + +Zyp Expires September 24, 2010 [Page 18] + +Internet-Draft JSON Schema Media Type March 2010 + + + { + "foo":{ + "anArray":[ + {"prop":44} + ], + "another prop":{ + "baz":"A string" + } + } + } + + The following fragment identifiers would be resolved: + + + fragment identifier resolution + ------------------- ---------- + # self, the root of the resource itself + #foo the object referred to by the foo property + #foo.another prop the object referred to by the "another prop" + property of the object referred to by the + "foo" property + #foo.another prop.baz the string referred to by the value of "baz" + property of the "another prop" property of + the object referred to by the "foo" property + #foo.anArray.0 the first object in the "anArray" array + +6.2.2. slash-delimited fragment resolution + + The slash-delimited fragment resolution protocol is exactly the same + as dot-delimited fragment resolution protocol except that the "/" + character (\x2F) is used as the delimiter between property names + (instead of "."). + +6.3. root + + This attribute indicates that the value of the instance property + value SHOULD be treated as the root or the body of the representation + for the purposes of user agent interaction and fragment resolution + (all other properties of the instance objects are can be regarded as + meta-data descriptions for the data). + +6.4. readonly + + This indicates that the instance property should not be changed. + Attempts by a user agent to modify the value of this property are + expected to be rejected by a server. + + + + + +Zyp Expires September 24, 2010 [Page 19] + +Internet-Draft JSON Schema Media Type March 2010 + + +6.5. pathStart + + This property value is a URI-Reference that indicates the URI that + all the URIs for the instances of the schema should start with. When + multiple schemas have been referenced for an instance, the user agent + can determine if this schema is applicable for a particular instance + by determining if URI of the instance begins with the pathStart's + referenced URI. pathStart MUST be resolved as per [RFC3986] section + 5. If the URI of the instance does not start with URI indicated by + pathStart, or if another schema specifies a starting URI that is + longer and also matches the instance, this schema should not be + applied to the instance. Any schema that does not have a pathStart + attribute should be considered applicable to all the instances for + which it is referenced. + +6.6. mediaType + + This indicates the media type of the instance representations that + this schema is defining. + +6.7. alternate + + This is an array of JSON schema definitions that define any other + schemas for alternate JSON-based representations of the instance + resources. + +7. Security Considerations + + This specification is a sub-type of the JSON format, and consequently + the security considerations are generally the same as RFC 4627. + However, an additional issue is that when link relation of "self" is + used to denote a full representation of an object, the user agent + SHOULD NOT consider the representation to be the authoritative + representation of the resource denoted by the target URI if the + target URI is not equivalent to or a sub-path of the the URI used to + request the resource representation which contains the target URI + with the "self" link. For example, if a hyper schema was defined: + + + { + "links":[ + { + "rel":"self", + "href":"{id}" + } + ] + } + + + + +Zyp Expires September 24, 2010 [Page 20] + +Internet-Draft JSON Schema Media Type March 2010 + + + And a resource was requested from somesite.com: + + + GET /foo/ + + With a response of: + + +Content-Type: application/json; profile=/schema-for-this-data +[ + {"id":"bar", "name":"This representation can be safely treated \ + as authoritative "}, + {"id":"/baz", "name":"This representation should not be treated as \ + authoritative the user agent should make request the resource\ + from "/baz" to ensure it has the authoritative representation"}, + {"id":"http://othersite.com/something", "name":"This representation\ + should also not be treated as authoritative and the target\ + resource representation should be retrieved for the\ + authoritative representation"} +] + +8. IANA Considerations + + The proposed MIME media type for JSON Schema is application/ + schema+json + + Type name: application + + Subtype name: schema+json + + Required parameters: profile + + The value of the profile parameter should be a URI (relative or + absolute) that refers to the schema used to define the structure of + this structure (the meta-schema). Normally the value would be + http://json-schema.org/hyper-schema, but it is allowable to use other + schemas that extend the hyper schema's meta- schema. + + Optional parameters: pretty + + The value of the pretty parameter may be true or false to indicate if + additional whitespace has been included to make the JSON + representation easier to read. + +8.1. Registry of Link Relations + + This registry is maintained by IANA per RFC 4287 and this + specification adds three values: "full", "create", "instances". New + + + +Zyp Expires September 24, 2010 [Page 21] + +Internet-Draft JSON Schema Media Type March 2010 + + + assignments are subject to IESG Approval, as outlined in [RFC5226]. + Requests should be made by email to IANA, which will then forward the + request to the IESG, requesting approval. + +9. References + +9.1. Normative References + + [RFC3986] Berners-Lee, T., Fielding, R., and + L. Masinter, "Uniform Resource + Identifier (URI): Generic Syntax", + STD 66, RFC 3986, January 2005. + + [RFC2119] Bradner, S., "Key words for use in + RFCs to Indicate Requirement + Levels", BCP 14, RFC 2119, + March 1997. + + [RFC4287] Nottingham, M., Ed. and R. Sayre, + Ed., "The Atom Syndication + Format", RFC 4287, December 2005. + + [RFC3339] Klyne, G., Ed. and C. Newman, + "Date and Time on the Internet: + Timestamps", RFC 3339, July 2002. + + [RFC2045] Freed, N. and N. Borenstein, + "Multipurpose Internet Mail + Extensions (MIME) Part One: Format + of Internet Message Bodies", + RFC 2045, November 1996. + +9.2. Informative References + + [RFC4627] Crockford, D., "The application/ + json Media Type for JavaScript + Object Notation (JSON)", RFC 4627, + July 2006. + + [RFC2616] Fielding, R., Gettys, J., Mogul, + J., Frystyk, H., Masinter, L., + Leach, P., and T. Berners-Lee, + "Hypertext Transfer Protocol -- + HTTP/1.1", RFC 2616, June 1999. + + [RFC5226] Narten, T. and H. Alvestrand, + "Guidelines for Writing an IANA + Considerations Section in RFCs", + + + +Zyp Expires September 24, 2010 [Page 22] + +Internet-Draft JSON Schema Media Type March 2010 + + + BCP 26, RFC 5226, May 2008. + + [I-D.hammer-discovery] Hammer-Lahav, E., "LRDD: Link- + based Resource Descriptor + Discovery", + draft-hammer-discovery-04 (work in + progress), March 2010. + + [I-D.gregorio-uritemplate] Gregorio, J., Fielding, R., + Hadley, M., and M. Nottingham, + "URI Template", + draft-gregorio-uritemplate-04 + (work in progress), March 2010. + + [I-D.nottingham-http-link-header] Nottingham, M., "Web Linking", dra + ft-nottingham-http-link-header-08 + (work in progress), March 2010. + + [W3C.REC-html401-19991224] Hors, A., Jacobs, I., and D. + Raggett, "HTML 4.01 + Specification", World Wide Web + Consortium Recommendation REC- + html401-19991224, December 1999, < + http://www.w3.org/TR/1999/ + REC-html401-19991224>. + +Appendix A. Change Log + + -02 + + o Replaced maxDecimal attribute with divisibleBy attribute + + o Added slash-delimited fragment resolution protocol and made it the + default. + + o Added language about using links outside of schemas by referencing + it's normative URI. + + o Added uniqueItems attribute + + o Added targetSchema attribute to link description object + + -01 + + o Fixed category and updates from template + + -00 + + + + +Zyp Expires September 24, 2010 [Page 23] + +Internet-Draft JSON Schema Media Type March 2010 + + + o Initial draft + +Appendix B. Open Issues + + Should we give a preference to MIME headers over Link headers (or + only use one)? + + Should we use "profile" as the media type parameter instead? + + Should "root" be a MIME parameter instead of a schema attribute? + + Should "format" be renamed to "mediaType" or "contentType" to reflect + the usage MIME media types that are allowed. + + I still do not like how dates are handled. + + Should "slash-delimited" or "dot-delimited" be the default fragment + resolution protocol? + +Author's Address + + Kris Zyp (editor) + SitePen (USA) + 530 Lytton Avenue + Palo Alto, CA 94301 + USA + + Phone: +1 650 968 8787 + EMail: kris@sitepen.com + + + + + + + + + + + + + + + + + + + + + + +Zyp Expires September 24, 2010 [Page 24] + + diff --git a/doc/json-glib-docs.xml b/doc/json-glib-docs.xml new file mode 100644 index 0000000..5c2cf30 --- /dev/null +++ b/doc/json-glib-docs.xml @@ -0,0 +1,264 @@ + + + + %gtkdocentities; +]> + + + + &package_name; Reference Manual + + This document is the API reference for for &package_name; &package_version;. + + The latest version of this API reference is also available + online. + + + If you find any issues in this API reference, please report it + using the online + bug reporting tool at bugzilla.gnome.org. + + + + + 2007, 2008 + OpenedHand LTD + + + + 2009, 2010, 2011 + Intel Corporation + + + + + Permission is granted to copy, distribute and/or modify this + document under the terms of the GNU Free + Documentation License, Version 1.1 or any later + version published by the Free Software Foundation with no + Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. You may obtain a copy of the GNU Free + Documentation License from the Free Software + Foundation by visiting their Web site or by writing + to: + +
+ The Free Software Foundation, Inc., + 59 Temple Place - Suite 330, + Boston, MA 02111-1307, + USA +
+
+
+ +
+ + + JSON-GLib Overview + + + + + JSON-GLib is a library aimed at providing an API for efficient parsing + and writing of JSON (JavaScript Object Notation) streams, using GLib's + data types and API. + + + + JSON (JavaScript Object Notation) is a lightweight data-interchange + format. More information on the grammar is available on json.org. + + + + + + + + JSON-GLib Reference + + + + + JSON-GLib provides wrappers around the complex data types defined + by the JSON specification. The fundamental types are handled using + the Generic Value container (GValue) provided by GLib. + + + + JSON complex data types are either arrays (a n-tuple of items) + or objects (a mapping between a string and a value); arrays and + objects can contain multiple values, including other arrays and + objects. + + + + + + Data Types + + + + + + + + + Reading and writing + + + + + JSON-GLib provides a parser object to read any valid JSON data + stream and build the data object model in memory. + + + + + + Parser + + + + + + + Generator + + + + + + General Purpose API + + + + + + + JSON-GLib Advanced API + + + + + + + + + + JSON-GLib Additional Reference + + + JSON-GLib Tools + + + + + + Object Hierarchy + + + + + + + Index + + + + + Index of deprecated symbols + + + + + Index of new symbols in 0.4 + + + + + Index of new symbols in 0.6 + + + + + Index of new symbols in 0.8 + + + + + Index of new symbols in 0.10 + + + + + Index of new symbols in 0.12 + + + + + Index of new symbols in 0.14 + + + + + Index of new symbols in 0.16 + + + + + Index of new symbols in 1.0 + + + + + Index of new symbols in 1.2 + + + + + Index of new symbols in 1.4 + + + + + + + License + + + 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 may obtain a copy of the GNU Library General + Public License from the Free Software Foundation by + visiting their Web + site or by writing to: + +
+ Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307 + USA +
+
+
+ +
diff --git a/doc/json-glib-format.xml b/doc/json-glib-format.xml new file mode 100644 index 0000000..d4ba59e --- /dev/null +++ b/doc/json-glib-format.xml @@ -0,0 +1,81 @@ + + + + json-glib-format + JSON-GLib + + + Developer + Emmanuele + Bassi + + + + + + json-glib-format + 1 + User Commands + + + + json-glib-format + JSON-GLib formatting tool + + + + + json-glib-format + , + + SPACES + URI + + URI + + + + +Description +json-glib-format offers a simple command line +interface to format JSON data. It reads a list or URIs, applies the +spacified formatting rules on the JSON data, and outputs the formatted +JSON to the standard output. + + +The resources to operate on are specified by the URI +argument. + + + + +Commands + + + +, + +Prints help and exits. + + + + +, + +Prettifies the output, by adding spaces and indentation. This argument is +useful to improve the readability of JSON data, at the expense of its size. + + + + + SPACES + +Changes the number of spaces using to indent the JSON data from the default of 2. +This argument is only considered if is used. + + + + + + + diff --git a/doc/json-glib-overrides.txt b/doc/json-glib-overrides.txt new file mode 100644 index 0000000..68de4f0 --- /dev/null +++ b/doc/json-glib-overrides.txt @@ -0,0 +1,14 @@ + +JSON_MAJOR_VERSION +#define JSON_MAJOR_VERSION + + + +JSON_MINOR_VERSION +#define JSON_MINOR_VERSION + + + +JSON_MICRO_VERSION +#define JSON_MICRO_VERSION + diff --git a/doc/json-glib-sections.txt b/doc/json-glib-sections.txt new file mode 100644 index 0000000..44942c4 --- /dev/null +++ b/doc/json-glib-sections.txt @@ -0,0 +1,451 @@ +json-glib/json-glib.h + +
+json-object +JSON Object +JsonObject +json_object_new +json_object_ref +json_object_unref +json_object_seal +json_object_is_immutable +json_object_hash +json_object_equal + + +json_object_add_member +json_object_set_member +json_object_has_member +json_object_get_member +json_object_dup_member +json_object_get_members +json_object_get_values +json_object_get_size +json_object_remove_member +JsonObjectForeach +json_object_foreach_member +JsonObjectIter +json_object_iter_init +json_object_iter_next + + +json_object_set_array_member +json_object_get_array_member +json_object_set_boolean_member +json_object_get_boolean_member +json_object_set_double_member +json_object_get_double_member +json_object_set_int_member +json_object_get_int_member +json_object_set_null_member +json_object_get_null_member +json_object_set_object_member +json_object_get_object_member +json_object_set_string_member +json_object_get_string_member + + +JSON_TYPE_OBJECT +json_object_get_type +
+ +
+json-array +JSON Array +JsonArray +json_array_new +json_array_sized_new +json_array_ref +json_array_unref +json_array_seal +json_array_is_immutable +json_array_hash +json_array_equal + + +json_array_add_element +json_array_get_element +json_array_dup_element +json_array_get_elements +json_array_get_length +json_array_remove_element +JsonArrayForeach +json_array_foreach_element + + +json_array_add_array_element +json_array_get_array_element +json_array_add_boolean_element +json_array_get_boolean_element +json_array_add_double_element +json_array_get_double_element +json_array_add_int_element +json_array_get_int_element +json_array_add_null_element +json_array_get_null_element +json_array_add_object_element +json_array_get_object_element +json_array_add_string_element +json_array_get_string_element + + +JSON_TYPE_ARRAY +json_array_get_type +
+ +
+json-node +JSON Node +JsonNodeType +JsonNode +JSON_NODE_TYPE +JSON_NODE_HOLDS +JSON_NODE_HOLDS_VALUE +JSON_NODE_HOLDS_OBJECT +JSON_NODE_HOLDS_ARRAY +JSON_NODE_HOLDS_NULL +json_node_alloc +json_node_init +json_node_init_int +json_node_init_double +json_node_init_boolean +json_node_init_string +json_node_init_null +json_node_init_object +json_node_init_array +json_node_new +json_node_copy +json_node_free +json_node_ref +json_node_unref +json_node_is_immutable +json_node_seal +json_node_hash +json_node_equal + + +json_node_set_array +json_node_take_array +json_node_get_array +json_node_dup_array + + +json_node_set_object +json_node_take_object +json_node_get_object +json_node_dup_object + + +json_node_set_value +json_node_get_value +json_node_set_boolean +json_node_get_boolean +json_node_set_double +json_node_get_double +json_node_set_int +json_node_get_int +json_node_set_string +json_node_get_string +json_node_dup_string + + +json_node_set_parent +json_node_get_parent +json_node_type_name +json_node_get_value_type +json_node_get_node_type +json_node_is_null + + +json_string_hash +json_string_equal +json_string_compare + + +JSON_DEPRECATED +JSON_DEPRECATED_FOR +JSON_TYPE_NODE +json_node_get_type +
+ +
+json-parser +JsonParser +JsonParserError + + +JsonParser +JsonParserClass +json_parser_new +json_parser_new_immutable +json_parser_load_from_file +json_parser_load_from_data +json_parser_load_from_stream +json_parser_load_from_stream_async +json_parser_load_from_stream_finish + + +json_parser_get_root +json_parser_steal_root + + +json_parser_get_current_line +json_parser_get_current_pos +json_parser_has_assignment + + +JSON_TYPE_PARSER +JSON_PARSER +JSON_IS_PARSER +JSON_PARSER_CLASS +JSON_IS_PARSER_CLASS +JSON_PARSER_ERROR +JSON_PARSER_GET_CLASS + + +JsonParserPrivate +json_parser_get_type +json_parser_error_quark +
+ +
+json-generator +JsonGenerator + +JsonGenerator +JsonGeneratorClass +json_generator_new +json_generator_set_root +json_generator_get_root +json_generator_set_pretty +json_generator_get_pretty +json_generator_set_indent +json_generator_get_indent +json_generator_set_indent_char +json_generator_get_indent_char + + +json_generator_to_file +json_generator_to_data +json_generator_to_gstring +json_generator_to_stream + + +JSON_TYPE_GENERATOR +JSON_GENERATOR +JSON_IS_GENERATOR +JSON_GENERATOR_CLASS +JSON_IS_GENERATOR_CLASS +JSON_GENERATOR_GET_CLASS + + +JsonGeneratorPrivate +json_generator_get_type +
+ +
+json-serializable +Serializable Interface +JsonSerializableIface +json_serializable_serialize_property +json_serializable_deserialize_property +json_serializable_find_property +json_serializable_get_property +json_serializable_list_properties +json_serializable_set_property + + +json_serializable_default_serialize_property +json_serializable_default_deserialize_property + + +JSON_TYPE_SERIALIZABLE +JSON_SERIALIZABLE +JSON_IS_SERIALIZABLE +JSON_SERIALIZABLE_GET_IFACE + + +JsonSerializable +json_serializable_get_type +
+ +
+json-gboxed +Boxed Types Serialization +JsonBoxedSerializeFunc +JsonBoxedDeserializeFunc +json_boxed_register_serialize_func +json_boxed_register_deserialize_func + + +json_boxed_can_serialize +json_boxed_can_deserialize +json_boxed_serialize +json_boxed_deserialize +
+ +
+json-gobject +GObject Serialization +json_gobject_serialize +json_gobject_deserialize +json_gobject_to_data +json_gobject_from_data + + +json_construct_gobject +json_serialize_gobject +
+ +
+json-gvariant + + +json_gvariant_serialize +json_gvariant_serialize_data +json_gvariant_deserialize +json_gvariant_deserialize_data +
+ +
+json-version +Versioning information +JSON_MAJOR_VERSION +JSON_MINOR_VERSION +JSON_MICRO_VERSION + + +JSON_VERSION +JSON_VERSION_S +JSON_VERSION_HEX + + +JSON_CHECK_VERSION +JSON_VERSION_MIN_REQUIRED +JSON_VERSION_MAX_ALLOWED + + +JSON_VERSION_CUR_STABLE +JSON_VERSION_PREV_STABLE +JSON_VERSION_1_0 +JSON_AVAILABLE_IN_1_0 +JSON_DEPRECATED_IN_1_0 +JSON_DEPRECATED_IN_1_0_FOR +JSON_VERSION_1_2 +JSON_AVAILABLE_IN_1_2 +JSON_DEPRECATED_IN_1_2 +JSON_DEPRECATED_IN_1_2_FOR +JSON_VERSION_1_4 +JSON_AVAILABLE_IN_1_4 +JSON_DEPRECATED_IN_1_4 +JSON_DEPRECATED_IN_1_4_FOR + + +JSON_ENCODE_VERSION +JSON_DEPRECATED +JSON_DEPRECATED_FOR +JSON_UNAVAILABLE +_JSON_EXTERN +
+ +
+json-builder +JsonBuilder +JsonBuilderClass +json_builder_new +json_builder_new_immutable +json_builder_get_root +json_builder_reset + +json_builder_begin_array +json_builder_end_array +json_builder_begin_object +json_builder_set_member_name +json_builder_end_object + +json_builder_add_value +json_builder_add_int_value +json_builder_add_double_value +json_builder_add_boolean_value +json_builder_add_string_value +json_builder_add_null_value + +JSON_TYPE_BUILDER +JSON_BUILDER +JSON_BUILDER_CLASS +JSON_IS_BUILDER +JSON_IS_BUILDER_CLASS +JSON_BUILDER_GET_CLASS + +JsonBuilderPrivate +json_builder_get_type +
+ +
+json-reader +JsonReader +JsonReaderClass +json_reader_new +json_reader_set_root + +json_reader_read_element +json_reader_end_element +json_reader_is_array +json_reader_count_elements + +json_reader_read_member +json_reader_end_member +json_reader_is_object +json_reader_count_members +json_reader_list_members +json_reader_get_member_name + +json_reader_is_value +json_reader_get_value +json_reader_get_int_value +json_reader_get_double_value +json_reader_get_string_value +json_reader_get_boolean_value +json_reader_get_null_value + +JsonReaderError +JSON_READER_ERROR +json_reader_get_error + +JSON_READER +JSON_READER_CLASS +JSON_IS_READER +JSON_IS_READER_CLASS +JSON_READER_GET_CLASS +JSON_TYPE_READER + +JsonReaderPrivate +json_reader_get_type +json_reader_error_quark +
+ +
+json-path +JsonPath +JsonPathClass +json_path_new +JSON_PATH_ERROR +JsonPathError +json_path_compile +json_path_match + +json_path_query + +JSON_TYPE_PATH +JSON_PATH +JSON_IS_PATH + +json_path_get_type +json_path_error_quark +
+ +
+json-utils +json_from_string +json_to_string +
diff --git a/doc/json-glib-validate.xml b/doc/json-glib-validate.xml new file mode 100644 index 0000000..1cd5c6d --- /dev/null +++ b/doc/json-glib-validate.xml @@ -0,0 +1,67 @@ + + + + json-glib-validate + JSON-GLib + + + Developer + Emmanuele + Bassi + + + + + + json-glib-validate + 1 + User Commands + + + + json-glib-validate + JSON-GLib validation tool + + + + + json-glib-validate + , + URI + + URI + + + + +Description +json-glib-validate offers a simple command line +interface to validate JSON data. It lets you list URIs that point to JSON +data and checks that the data conforms to the JSON syntax. + + +The resources to operate on are specified by the URI +argument. + + + +If the JSON data is valid, json-glib-validate will terminate +with an exit code of 0; if the data is invalid, an error will be printed on +stderr and json-glib-validate will +terminate with a nonzero exit code. + + +Commands + + + +, + +Prints help and exits. + + + + + + + diff --git a/doc/meson.build b/doc/meson.build new file mode 100644 index 0000000..7223b2d --- /dev/null +++ b/doc/meson.build @@ -0,0 +1,73 @@ +subdir('xml') + +private_headers = [ + 'config.h', + + 'json-debug.h', + 'json-enum-types.h', + 'json-glib.h', + 'json-gobject-private.h', + 'json-marshal.h', + 'json-private.h', + 'json-scanner.h', + 'json-types-private.h', +] + +glib_prefix = dependency('glib-2.0').get_pkgconfig_variable('prefix') +glib_docpath = join_paths(glib_prefix, 'share', 'gtk-doc', 'html') +docpath = join_paths(json_datadir, 'gtk-doc', 'html') + +if get_option('docs') + gnome.gtkdoc('json-glib', + main_xml: 'json-glib-docs.xml', + src_dir: [ + join_paths(meson.source_root(), 'json-glib'), + join_paths(meson.build_root(), 'json-glib'), + ], + dependencies: json_glib_dep, + gobject_typesfile: 'json-glib.types', + scan_args: [ + '--rebuild-types', + '--ignore-decorators=_JSON_EXTERN', + '--ignore-headers=' + ' '.join(private_headers), + ], + fixxref_args: [ + '--html-dir=@0@'.format(docpath), + '--extra-dir=@0@'.format(join_paths(glib_docpath, 'glib')), + '--extra-dir=@0@'.format(join_paths(glib_docpath, 'gobject')), + '--extra-dir=@0@'.format(join_paths(glib_docpath, 'gio')), + ], + install: true) +endif + +xsltproc = find_program('xsltproc', required: false) +if get_option('man') and xsltproc.found() + xlstproc_flags = [ + '--nonet', + '--stringparam', 'man.output.quietly', '1', + '--stringparam', 'funcsynopsis.style', 'ansi', + '--stringparam', 'man.th.extra1.suppress', '1', + '--stringparam', 'man.authors.section.enabled', '1', + '--stringparam', 'man.copyright.section.enabled', '1', + ] + + man_files = [ + 'json-glib-format', + 'json-glib-validate', + ] + + foreach m: man_files + custom_target(m + ' man page', + input: '@0@.xml'.format(m), + output: '@0@.1'.format(m), + command: [ + xsltproc, + xlstproc_flags, + '-o', '@OUTPUT@', + 'http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl', + '@INPUT@', + ], + install: true, + install_dir: join_paths(json_mandir, 'man1')) + endforeach +endif diff --git a/doc/rfc4627.txt b/doc/rfc4627.txt new file mode 100644 index 0000000..67b8909 --- /dev/null +++ b/doc/rfc4627.txt @@ -0,0 +1,563 @@ + + + + + + +Network Working Group D. Crockford +Request for Comments: 4627 JSON.org +Category: Informational July 2006 + + + The application/json Media Type for JavaScript Object Notation (JSON) + +Status of This Memo + + This memo provides information for the Internet community. It does + not specify an Internet standard of any kind. Distribution of this + memo is unlimited. + +Copyright Notice + + Copyright (C) The Internet Society (2006). + +Abstract + + JavaScript Object Notation (JSON) is a lightweight, text-based, + language-independent data interchange format. It was derived from + the ECMAScript Programming Language Standard. JSON defines a small + set of formatting rules for the portable representation of structured + data. + +1. Introduction + + JavaScript Object Notation (JSON) is a text format for the + serialization of structured data. It is derived from the object + literals of JavaScript, as defined in the ECMAScript Programming + Language Standard, Third Edition [ECMA]. + + JSON can represent four primitive types (strings, numbers, booleans, + and null) and two structured types (objects and arrays). + + A string is a sequence of zero or more Unicode characters [UNICODE]. + + An object is an unordered collection of zero or more name/value + pairs, where a name is a string and a value is a string, number, + boolean, null, object, or array. + + An array is an ordered sequence of zero or more values. + + The terms "object" and "array" come from the conventions of + JavaScript. + + JSON's design goals were for it to be minimal, portable, textual, and + a subset of JavaScript. + + + +Crockford Informational [Page 1] + +RFC 4627 JSON July 2006 + + +1.1. Conventions Used in This Document + + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this + document are to be interpreted as described in [RFC2119]. + + The grammatical rules in this document are to be interpreted as + described in [RFC4234]. + +2. JSON Grammar + + A JSON text is a sequence of tokens. The set of tokens includes six + structural characters, strings, numbers, and three literal names. + + A JSON text is a serialized object or array. + + JSON-text = object / array + + These are the six structural characters: + + begin-array = ws %x5B ws ; [ left square bracket + + begin-object = ws %x7B ws ; { left curly bracket + + end-array = ws %x5D ws ; ] right square bracket + + end-object = ws %x7D ws ; } right curly bracket + + name-separator = ws %x3A ws ; : colon + + value-separator = ws %x2C ws ; , comma + + Insignificant whitespace is allowed before or after any of the six + structural characters. + + ws = *( + %x20 / ; Space + %x09 / ; Horizontal tab + %x0A / ; Line feed or New line + %x0D ; Carriage return + ) + +2.1. Values + + A JSON value MUST be an object, array, number, or string, or one of + the following three literal names: + + false null true + + + +Crockford Informational [Page 2] + +RFC 4627 JSON July 2006 + + + The literal names MUST be lowercase. No other literal names are + allowed. + + value = false / null / true / object / array / number / string + + false = %x66.61.6c.73.65 ; false + + null = %x6e.75.6c.6c ; null + + true = %x74.72.75.65 ; true + +2.2. Objects + + An object structure is represented as a pair of curly brackets + surrounding zero or more name/value pairs (or members). A name is a + string. A single colon comes after each name, separating the name + from the value. A single comma separates a value from a following + name. The names within an object SHOULD be unique. + + object = begin-object [ member *( value-separator member ) ] + end-object + + member = string name-separator value + +2.3. Arrays + + An array structure is represented as square brackets surrounding zero + or more values (or elements). Elements are separated by commas. + + array = begin-array [ value *( value-separator value ) ] end-array + +2.4. Numbers + + The representation of numbers is similar to that used in most + programming languages. A number contains an integer component that + may be prefixed with an optional minus sign, which may be followed by + a fraction part and/or an exponent part. + + Octal and hex forms are not allowed. Leading zeros are not allowed. + + A fraction part is a decimal point followed by one or more digits. + + An exponent part begins with the letter E in upper or lowercase, + which may be followed by a plus or minus sign. The E and optional + sign are followed by one or more digits. + + Numeric values that cannot be represented as sequences of digits + (such as Infinity and NaN) are not permitted. + + + +Crockford Informational [Page 3] + +RFC 4627 JSON July 2006 + + + number = [ minus ] int [ frac ] [ exp ] + + decimal-point = %x2E ; . + + digit1-9 = %x31-39 ; 1-9 + + e = %x65 / %x45 ; e E + + exp = e [ minus / plus ] 1*DIGIT + + frac = decimal-point 1*DIGIT + + int = zero / ( digit1-9 *DIGIT ) + + minus = %x2D ; - + + plus = %x2B ; + + + zero = %x30 ; 0 + +2.5. Strings + + The representation of strings is similar to conventions used in the C + family of programming languages. A string begins and ends with + quotation marks. All Unicode characters may be placed within the + quotation marks except for the characters that must be escaped: + quotation mark, reverse solidus, and the control characters (U+0000 + through U+001F). + + Any character may be escaped. If the character is in the Basic + Multilingual Plane (U+0000 through U+FFFF), then it may be + represented as a six-character sequence: a reverse solidus, followed + by the lowercase letter u, followed by four hexadecimal digits that + encode the character's code point. The hexadecimal letters A though + F can be upper or lowercase. So, for example, a string containing + only a single reverse solidus character may be represented as + "\u005C". + + Alternatively, there are two-character sequence escape + representations of some popular characters. So, for example, a + string containing only a single reverse solidus character may be + represented more compactly as "\\". + + To escape an extended character that is not in the Basic Multilingual + Plane, the character is represented as a twelve-character sequence, + encoding the UTF-16 surrogate pair. So, for example, a string + containing only the G clef character (U+1D11E) may be represented as + "\uD834\uDD1E". + + + +Crockford Informational [Page 4] + +RFC 4627 JSON July 2006 + + + string = quotation-mark *char quotation-mark + + char = unescaped / + escape ( + %x22 / ; " quotation mark U+0022 + %x5C / ; \ reverse solidus U+005C + %x2F / ; / solidus U+002F + %x62 / ; b backspace U+0008 + %x66 / ; f form feed U+000C + %x6E / ; n line feed U+000A + %x72 / ; r carriage return U+000D + %x74 / ; t tab U+0009 + %x75 4HEXDIG ) ; uXXXX U+XXXX + + escape = %x5C ; \ + + quotation-mark = %x22 ; " + + unescaped = %x20-21 / %x23-5B / %x5D-10FFFF + +3. Encoding + + JSON text SHALL be encoded in Unicode. The default encoding is + UTF-8. + + Since the first two characters of a JSON text will always be ASCII + characters [RFC0020], it is possible to determine whether an octet + stream is UTF-8, UTF-16 (BE or LE), or UTF-32 (BE or LE) by looking + at the pattern of nulls in the first four octets. + + 00 00 00 xx UTF-32BE + 00 xx 00 xx UTF-16BE + xx 00 00 00 UTF-32LE + xx 00 xx 00 UTF-16LE + xx xx xx xx UTF-8 + +4. Parsers + + A JSON parser transforms a JSON text into another representation. A + JSON parser MUST accept all texts that conform to the JSON grammar. + A JSON parser MAY accept non-JSON forms or extensions. + + An implementation may set limits on the size of texts that it + accepts. An implementation may set limits on the maximum depth of + nesting. An implementation may set limits on the range of numbers. + An implementation may set limits on the length and character contents + of strings. + + + + +Crockford Informational [Page 5] + +RFC 4627 JSON July 2006 + + +5. Generators + + A JSON generator produces JSON text. The resulting text MUST + strictly conform to the JSON grammar. + +6. IANA Considerations + + The MIME media type for JSON text is application/json. + + Type name: application + + Subtype name: json + + Required parameters: n/a + + Optional parameters: n/a + + Encoding considerations: 8bit if UTF-8; binary if UTF-16 or UTF-32 + + JSON may be represented using UTF-8, UTF-16, or UTF-32. When JSON + is written in UTF-8, JSON is 8bit compatible. When JSON is + written in UTF-16 or UTF-32, the binary content-transfer-encoding + must be used. + + Security considerations: + + Generally there are security issues with scripting languages. JSON + is a subset of JavaScript, but it is a safe subset that excludes + assignment and invocation. + + A JSON text can be safely passed into JavaScript's eval() function + (which compiles and executes a string) if all the characters not + enclosed in strings are in the set of characters that form JSON + tokens. This can be quickly determined in JavaScript with two + regular expressions and calls to the test and replace methods. + + var my_JSON_object = !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test( + text.replace(/"(\\.|[^"\\])*"/g, ''))) && + eval('(' + text + ')'); + + Interoperability considerations: n/a + + Published specification: RFC 4627 + + + + + + + + +Crockford Informational [Page 6] + +RFC 4627 JSON July 2006 + + + Applications that use this media type: + + JSON has been used to exchange data between applications written + in all of these programming languages: ActionScript, C, C#, + ColdFusion, Common Lisp, E, Erlang, Java, JavaScript, Lua, + Objective CAML, Perl, PHP, Python, Rebol, Ruby, and Scheme. + + Additional information: + + Magic number(s): n/a + File extension(s): .json + Macintosh file type code(s): TEXT + + Person & email address to contact for further information: + Douglas Crockford + douglas@crockford.com + + Intended usage: COMMON + + Restrictions on usage: none + + Author: + Douglas Crockford + douglas@crockford.com + + Change controller: + Douglas Crockford + douglas@crockford.com + +7. Security Considerations + + See Security Considerations in Section 6. + +8. Examples + + This is a JSON object: + + { + "Image": { + "Width": 800, + "Height": 600, + "Title": "View from 15th Floor", + "Thumbnail": { + "Url": "http://www.example.com/image/481989943", + "Height": 125, + "Width": "100" + }, + "IDs": [116, 943, 234, 38793] + + + +Crockford Informational [Page 7] + +RFC 4627 JSON July 2006 + + + } + } + + Its Image member is an object whose Thumbnail member is an object + and whose IDs member is an array of numbers. + + This is a JSON array containing two objects: + + [ + { + "precision": "zip", + "Latitude": 37.7668, + "Longitude": -122.3959, + "Address": "", + "City": "SAN FRANCISCO", + "State": "CA", + "Zip": "94107", + "Country": "US" + }, + { + "precision": "zip", + "Latitude": 37.371991, + "Longitude": -122.026020, + "Address": "", + "City": "SUNNYVALE", + "State": "CA", + "Zip": "94085", + "Country": "US" + } + ] + +9. References + +9.1. Normative References + + [ECMA] European Computer Manufacturers Association, "ECMAScript + Language Specification 3rd Edition", December 1999, + . + + [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, + October 1969. + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + + [RFC4234] Crocker, D. and P. Overell, "Augmented BNF for Syntax + Specifications: ABNF", RFC 4234, October 2005. + + + +Crockford Informational [Page 8] + +RFC 4627 JSON July 2006 + + + [UNICODE] The Unicode Consortium, "The Unicode Standard Version 4.0", + 2003, . + +Author's Address + + Douglas Crockford + JSON.org + EMail: douglas@crockford.com + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Crockford Informational [Page 9] + +RFC 4627 JSON July 2006 + + +Full Copyright Statement + + Copyright (C) The Internet Society (2006). + + This document is subject to the rights, licenses and restrictions + contained in BCP 78, and except as set forth therein, the authors + retain all their rights. + + This document and the information contained herein are provided on an + "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS + OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET + ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE + INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED + WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + +Intellectual Property + + The IETF takes no position regarding the validity or scope of any + Intellectual Property Rights or other rights that might be claimed to + pertain to the implementation or use of the technology described in + this document or the extent to which any license under such rights + might or might not be available; nor does it represent that it has + made any independent effort to identify any such rights. Information + on the procedures with respect to rights in RFC documents can be + found in BCP 78 and BCP 79. + + Copies of IPR disclosures made to the IETF Secretariat and any + assurances of licenses to be made available, or the result of an + attempt made to obtain a general license or permission for the use of + such proprietary rights by implementers or users of this + specification can be obtained from the IETF on-line IPR repository at + http://www.ietf.org/ipr. + + The IETF invites any interested party to bring to its attention any + copyrights, patents or patent applications, or other proprietary + rights that may cover technology that may be required to implement + this standard. Please address the information to the IETF at + ietf-ipr@ietf.org. + +Acknowledgement + + Funding for the RFC Editor function is provided by the IETF + Administrative Support Activity (IASA). + + + + + + + +Crockford Informational [Page 10] + diff --git a/doc/xml/gtkdocentities.ent.in b/doc/xml/gtkdocentities.ent.in new file mode 100644 index 0000000..f12c9ff --- /dev/null +++ b/doc/xml/gtkdocentities.ent.in @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/doc/xml/meson.build b/doc/xml/meson.build new file mode 100644 index 0000000..587d773 --- /dev/null +++ b/doc/xml/meson.build @@ -0,0 +1,11 @@ +ent_conf = configuration_data() +ent_conf.set('PACKAGE', 'JSON-GLib') +ent_conf.set('PACKAGE_BUGREPORT', 'https://bugzilla.gnome.org/enter_bug.cgi?product=json-glib') +ent_conf.set('PACKAGE_NAME', 'JSON-GLib') +ent_conf.set('PACKAGE_STRING', meson.project_name()) +ent_conf.set('PACKAGE_TARNAME', '@0@-@1@'.format(meson.project_name(), meson.project_version())) +ent_conf.set('PACKAGE_URL', 'http://wiki.gnome.org/Project/JsonGlib') +ent_conf.set('PACKAGE_VERSION', meson.project_version()) +ent_conf.set('PACKAGE_API_VERSION', json_api_version) +configure_file(input: 'gtkdocentities.ent.in', output: 'gtkdocentities.ent', configuration: ent_conf) + diff --git a/json-glib.doap b/json-glib.doap new file mode 100644 index 0000000..7ea3795 --- /dev/null +++ b/json-glib.doap @@ -0,0 +1,43 @@ + + + JSON-GLib + json-glib + GLib-based JSON manipulation library + JSON-GLib implements a full JSON parser using GLib and GObject. Use JSON-GLib it is possible to parse and generate valid JSON data structures, using a DOM-like API. JSON-GLib also offers GObject integration, providing the ability to serialize and deserialize GObject instances to and from JSON data types. + + + + + + + + + + + + + + + C + + + + Emmanuele Bassi + + ebassi + + + + + + Emmanuele Bassi + + ebassi + + + + diff --git a/json-glib/json-array.c b/json-glib/json-array.c new file mode 100644 index 0000000..4834cdc --- /dev/null +++ b/json-glib/json-array.c @@ -0,0 +1,835 @@ +/* json-array.c - JSON array implementation + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#include "config.h" + +#include "json-types-private.h" + +/** + * SECTION:json-array + * @short_description: a JSON array representation + * + * #JsonArray is the representation of the array type inside JSON. It contains + * #JsonNode elements, which may contain fundamental types, other arrays or + * objects. + * + * Since arrays can be expensive, they are reference counted. You can control + * the lifetime of a #JsonArray using json_array_ref() and json_array_unref(). + * + * To append an element, use json_array_add_element(). + * To extract an element at a given index, use json_array_get_element(). + * To retrieve the entire array in list form, use json_array_get_elements(). + * To retrieve the length of the array, use json_array_get_length(). + */ + +G_DEFINE_BOXED_TYPE (JsonArray, json_array, json_array_ref, json_array_unref); + +/** + * json_array_new: (constructor) + * + * Creates a new #JsonArray. + * + * Return value: (transfer full): the newly created #JsonArray + */ +JsonArray * +json_array_new (void) +{ + JsonArray *array; + + array = g_slice_new0 (JsonArray); + + array->ref_count = 1; + array->elements = g_ptr_array_new (); + + return array; +} + +/** + * json_array_sized_new: (constructor) + * @n_elements: number of slots to pre-allocate + * + * Creates a new #JsonArray with @n_elements slots already allocated. + * + * Return value: (transfer full): the newly created #JsonArray + */ +JsonArray * +json_array_sized_new (guint n_elements) +{ + JsonArray *array; + + array = g_slice_new0 (JsonArray); + + array->ref_count = 1; + array->elements = g_ptr_array_sized_new (n_elements); + + return array; +} + +/** + * json_array_ref: + * @array: a #JsonArray + * + * Increase by one the reference count of a #JsonArray. + * + * Return value: (transfer none): the passed #JsonArray, with the reference count + * increased by one. + */ +JsonArray * +json_array_ref (JsonArray *array) +{ + g_return_val_if_fail (array != NULL, NULL); + g_return_val_if_fail (array->ref_count > 0, NULL); + + array->ref_count++; + + return array; +} + +/** + * json_array_unref: + * @array: a #JsonArray + * + * Decreases by one the reference count of a #JsonArray. If the + * reference count reaches zero, the array is destroyed and all + * its allocated resources are freed. + */ +void +json_array_unref (JsonArray *array) +{ + g_return_if_fail (array != NULL); + g_return_if_fail (array->ref_count > 0); + + if (--array->ref_count == 0) + { + guint i; + + for (i = 0; i < array->elements->len; i++) + json_node_unref (g_ptr_array_index (array->elements, i)); + + g_ptr_array_free (array->elements, TRUE); + array->elements = NULL; + + g_slice_free (JsonArray, array); + } +} + +/** + * json_array_seal: + * @array: a #JsonArray + * + * Seals the #JsonArray, making it immutable to further changes. This will + * recursively seal all elements in the array too. + * + * If the @array is already immutable, this is a no-op. + * + * Since: 1.2 + */ +void +json_array_seal (JsonArray *array) +{ + guint i; + + g_return_if_fail (array != NULL); + g_return_if_fail (array->ref_count > 0); + + if (array->immutable) + return; + + /* Propagate to all members. */ + for (i = 0; i < array->elements->len; i++) + json_node_seal (g_ptr_array_index (array->elements, i)); + + array->immutable_hash = json_array_hash (array); + array->immutable = TRUE; +} + +/** + * json_array_is_immutable: + * @array: a #JsonArray + * + * Check whether the given @array has been marked as immutable by calling + * json_array_seal() on it. + * + * Since: 1.2 + * Returns: %TRUE if the @array is immutable + */ +gboolean +json_array_is_immutable (JsonArray *array) +{ + g_return_val_if_fail (array != NULL, FALSE); + g_return_val_if_fail (array->ref_count > 0, FALSE); + + return array->immutable; +} + +/** + * json_array_get_elements: + * @array: a #JsonArray + * + * Gets the elements of a #JsonArray as a list of #JsonNode instances. + * + * Return value: (element-type JsonNode) (transfer container): a #GList + * containing the elements of the array. The contents of the list are + * owned by the array and should never be modified or freed. Use + * g_list_free() on the returned list when done using it + */ +GList * +json_array_get_elements (JsonArray *array) +{ + GList *retval; + guint i; + + g_return_val_if_fail (array != NULL, NULL); + + retval = NULL; + for (i = 0; i < array->elements->len; i++) + retval = g_list_prepend (retval, + g_ptr_array_index (array->elements, i)); + + return g_list_reverse (retval); +} + +/** + * json_array_dup_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Retrieves a copy of the #JsonNode containing the value of the + * element at @index_ inside a #JsonArray + * + * Return value: (transfer full): a copy of the #JsonNode at the requested + * index. Use json_node_unref() when done. + * + * Since: 0.6 + */ +JsonNode * +json_array_dup_element (JsonArray *array, + guint index_) +{ + JsonNode *retval; + + g_return_val_if_fail (array != NULL, NULL); + g_return_val_if_fail (index_ < array->elements->len, NULL); + + retval = json_array_get_element (array, index_); + if (!retval) + return NULL; + + return json_node_copy (retval); +} + +/** + * json_array_get_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Retrieves the #JsonNode containing the value of the element at @index_ + * inside a #JsonArray. + * + * Return value: (transfer none): a pointer to the #JsonNode at the requested index + */ +JsonNode * +json_array_get_element (JsonArray *array, + guint index_) +{ + g_return_val_if_fail (array != NULL, NULL); + g_return_val_if_fail (index_ < array->elements->len, NULL); + + return g_ptr_array_index (array->elements, index_); +} + +/** + * json_array_get_int_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Conveniently retrieves the integer value of the element at @index_ + * inside @array + * + * See also: json_array_get_element(), json_node_get_int() + * + * Return value: the integer value + * + * Since: 0.8 + */ +gint64 +json_array_get_int_element (JsonArray *array, + guint index_) +{ + JsonNode *node; + + g_return_val_if_fail (array != NULL, 0); + g_return_val_if_fail (index_ < array->elements->len, 0); + + node = g_ptr_array_index (array->elements, index_); + g_return_val_if_fail (node != NULL, 0); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0); + + return json_node_get_int (node); +} + +/** + * json_array_get_double_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Conveniently retrieves the floating point value of the element at + * @index_ inside @array + * + * See also: json_array_get_element(), json_node_get_double() + * + * Return value: the floating point value + * + * Since: 0.8 + */ +gdouble +json_array_get_double_element (JsonArray *array, + guint index_) +{ + JsonNode *node; + + g_return_val_if_fail (array != NULL, 0.0); + g_return_val_if_fail (index_ < array->elements->len, 0.0); + + node = g_ptr_array_index (array->elements, index_); + g_return_val_if_fail (node != NULL, 0.0); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0); + + return json_node_get_double (node); +} + +/** + * json_array_get_boolean_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Conveniently retrieves the boolean value of the element at @index_ + * inside @array + * + * See also: json_array_get_element(), json_node_get_boolean() + * + * Return value: the integer value + * + * Since: 0.8 + */ +gboolean +json_array_get_boolean_element (JsonArray *array, + guint index_) +{ + JsonNode *node; + + g_return_val_if_fail (array != NULL, FALSE); + g_return_val_if_fail (index_ < array->elements->len, FALSE); + + node = g_ptr_array_index (array->elements, index_); + g_return_val_if_fail (node != NULL, FALSE); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE); + + return json_node_get_boolean (node); +} + +/** + * json_array_get_string_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Conveniently retrieves the string value of the element at @index_ + * inside @array + * + * See also: json_array_get_element(), json_node_get_string() + * + * Return value: the string value; the returned string is owned by + * the #JsonArray and should not be modified or freed + * + * Since: 0.8 + */ +const gchar * +json_array_get_string_element (JsonArray *array, + guint index_) +{ + JsonNode *node; + + g_return_val_if_fail (array != NULL, NULL); + g_return_val_if_fail (index_ < array->elements->len, NULL); + + node = g_ptr_array_index (array->elements, index_); + g_return_val_if_fail (node != NULL, NULL); + g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL); + + if (JSON_NODE_HOLDS_NULL (node)) + return NULL; + + return json_node_get_string (node); +} + +/** + * json_array_get_null_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Conveniently retrieves whether the element at @index_ is set to null + * + * See also: json_array_get_element(), JSON_NODE_TYPE(), %JSON_NODE_NULL + * + * Return value: %TRUE if the element is null + * + * Since: 0.8 + */ +gboolean +json_array_get_null_element (JsonArray *array, + guint index_) +{ + JsonNode *node; + + g_return_val_if_fail (array != NULL, FALSE); + g_return_val_if_fail (index_ < array->elements->len, FALSE); + + node = g_ptr_array_index (array->elements, index_); + g_return_val_if_fail (node != NULL, FALSE); + + if (JSON_NODE_HOLDS_NULL (node)) + return TRUE; + + if (JSON_NODE_HOLDS_ARRAY (node)) + return json_node_get_array (node) == NULL; + + if (JSON_NODE_HOLDS_OBJECT (node)) + return json_node_get_object (node) == NULL; + + return FALSE; +} + +/** + * json_array_get_array_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Conveniently retrieves the array from the element at @index_ + * inside @array + * + * See also: json_array_get_element(), json_node_get_array() + * + * Return value: (transfer none): the array + * + * Since: 0.8 + */ +JsonArray * +json_array_get_array_element (JsonArray *array, + guint index_) +{ + JsonNode *node; + + g_return_val_if_fail (array != NULL, NULL); + g_return_val_if_fail (index_ < array->elements->len, NULL); + + node = g_ptr_array_index (array->elements, index_); + g_return_val_if_fail (node != NULL, NULL); + g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL); + + if (JSON_NODE_HOLDS_NULL (node)) + return NULL; + + return json_node_get_array (node); +} + +/** + * json_array_get_object_element: + * @array: a #JsonArray + * @index_: the index of the element to retrieve + * + * Conveniently retrieves the object from the element at @index_ + * inside @array + * + * See also: json_array_get_element(), json_node_get_object() + * + * Return value: (transfer none): the object + * + * Since: 0.8 + */ +JsonObject * +json_array_get_object_element (JsonArray *array, + guint index_) +{ + JsonNode *node; + + g_return_val_if_fail (array != NULL, NULL); + g_return_val_if_fail (index_ < array->elements->len, NULL); + + node = g_ptr_array_index (array->elements, index_); + g_return_val_if_fail (node != NULL, NULL); + g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL); + + if (JSON_NODE_HOLDS_NULL (node)) + return NULL; + + return json_node_get_object (node); +} + +/** + * json_array_get_length: + * @array: a #JsonArray + * + * Retrieves the length of a #JsonArray + * + * Return value: the length of the array + */ +guint +json_array_get_length (JsonArray *array) +{ + g_return_val_if_fail (array != NULL, 0); + + return array->elements->len; +} + +/** + * json_array_add_element: + * @array: a #JsonArray + * @node: (transfer full): a #JsonNode + * + * Appends @node inside @array. The array will take ownership of the + * #JsonNode. + */ +void +json_array_add_element (JsonArray *array, + JsonNode *node) +{ + g_return_if_fail (array != NULL); + g_return_if_fail (node != NULL); + + g_ptr_array_add (array->elements, node); +} + +/** + * json_array_add_int_element: + * @array: a #JsonArray + * @value: an integer value + * + * Conveniently adds an integer @value into @array + * + * See also: json_array_add_element(), json_node_set_int() + * + * Since: 0.8 + */ +void +json_array_add_int_element (JsonArray *array, + gint64 value) +{ + g_return_if_fail (array != NULL); + + json_array_add_element (array, json_node_init_int (json_node_alloc (), value)); +} + +/** + * json_array_add_double_element: + * @array: a #JsonArray + * @value: a floating point value + * + * Conveniently adds a floating point @value into @array + * + * See also: json_array_add_element(), json_node_set_double() + * + * Since: 0.8 + */ +void +json_array_add_double_element (JsonArray *array, + gdouble value) +{ + g_return_if_fail (array != NULL); + + json_array_add_element (array, json_node_init_double (json_node_alloc (), value)); +} + +/** + * json_array_add_boolean_element: + * @array: a #JsonArray + * @value: a boolean value + * + * Conveniently adds a boolean @value into @array + * + * See also: json_array_add_element(), json_node_set_boolean() + * + * Since: 0.8 + */ +void +json_array_add_boolean_element (JsonArray *array, + gboolean value) +{ + g_return_if_fail (array != NULL); + + json_array_add_element (array, json_node_init_boolean (json_node_alloc (), value)); +} + +/** + * json_array_add_string_element: + * @array: a #JsonArray + * @value: a string value + * + * Conveniently adds a string @value into @array + * + * See also: json_array_add_element(), json_node_set_string() + * + * Since: 0.8 + */ +void +json_array_add_string_element (JsonArray *array, + const gchar *value) +{ + JsonNode *node; + + g_return_if_fail (array != NULL); + + node = json_node_alloc (); + + if (value != NULL) + json_node_init_string (node, value); + else + json_node_init_null (node); + + json_array_add_element (array, node); +} + +/** + * json_array_add_null_element: + * @array: a #JsonArray + * + * Conveniently adds a null element into @array + * + * See also: json_array_add_element(), %JSON_NODE_NULL + * + * Since: 0.8 + */ +void +json_array_add_null_element (JsonArray *array) +{ + g_return_if_fail (array != NULL); + + json_array_add_element (array, json_node_init_null (json_node_alloc ())); +} + +/** + * json_array_add_array_element: + * @array: a #JsonArray + * @value: (allow-none) (transfer full): a #JsonArray + * + * Conveniently adds an array into @array. The @array takes ownership + * of the newly added #JsonArray + * + * See also: json_array_add_element(), json_node_take_array() + * + * Since: 0.8 + */ +void +json_array_add_array_element (JsonArray *array, + JsonArray *value) +{ + JsonNode *node; + + g_return_if_fail (array != NULL); + + node = json_node_alloc (); + + if (value != NULL) + { + json_node_init_array (node, value); + json_array_unref (value); + } + else + json_node_init_null (node); + + json_array_add_element (array, node); +} + +/** + * json_array_add_object_element: + * @array: a #JsonArray + * @value: (transfer full): a #JsonObject + * + * Conveniently adds an object into @array. The @array takes ownership + * of the newly added #JsonObject + * + * See also: json_array_add_element(), json_node_take_object() + * + * Since: 0.8 + */ +void +json_array_add_object_element (JsonArray *array, + JsonObject *value) +{ + JsonNode *node; + + g_return_if_fail (array != NULL); + + node = json_node_alloc (); + + if (value != NULL) + { + json_node_init_object (node, value); + json_object_unref (value); + } + else + json_node_init_null (node); + + json_array_add_element (array, node); +} + +/** + * json_array_remove_element: + * @array: a #JsonArray + * @index_: the position of the element to be removed + * + * Removes the #JsonNode inside @array at @index_ freeing its allocated + * resources. + */ +void +json_array_remove_element (JsonArray *array, + guint index_) +{ + g_return_if_fail (array != NULL); + g_return_if_fail (index_ < array->elements->len); + + json_node_unref (g_ptr_array_remove_index (array->elements, index_)); +} + +/** + * json_array_foreach_element: + * @array: a #JsonArray + * @func: (scope call): the function to be called on each element + * @data: (closure): data to be passed to the function + * + * Iterates over all elements of @array and calls @func on + * each one of them. + * + * It is safe to change the value of a #JsonNode of the @array + * from within the iterator @func, but it is not safe to add or + * remove elements from the @array. + * + * Since: 0.8 + */ +void +json_array_foreach_element (JsonArray *array, + JsonArrayForeach func, + gpointer data) +{ + gint i; + + g_return_if_fail (array != NULL); + g_return_if_fail (func != NULL); + + for (i = 0; i < array->elements->len; i++) + { + JsonNode *element_node; + + element_node = g_ptr_array_index (array->elements, i); + + (* func) (array, i, element_node, data); + } +} + +/** + * json_array_hash: + * @key: (type JsonArray): a JSON array to hash + * + * Calculate a hash value for the given @key (a #JsonArray). + * + * The hash is calculated over the array and all its elements, recursively. If + * the array is immutable, this is a fast operation; otherwise, it scales + * proportionally with the length of the array. + * + * Returns: hash value for @key + * Since: 1.2 + */ +guint +json_array_hash (gconstpointer key) +{ + JsonArray *array; /* unowned */ + guint hash = 0; + guint i; + + g_return_val_if_fail (key != NULL, 0); + + array = (JsonArray *) key; + + /* If the array is immutable, we can use the calculated hash. */ + if (array->immutable) + return array->immutable_hash; + + /* Otherwise, calculate the hash. */ + for (i = 0; i < array->elements->len; i++) + { + JsonNode *node = g_ptr_array_index (array->elements, i); + hash ^= (i ^ json_node_hash (node)); + } + + return hash; +} + +/** + * json_array_equal: + * @a: (type JsonArray): a JSON array + * @b: (type JsonArray): another JSON array + * + * Check whether @a and @b are equal #JsonArrays, meaning they have the same + * number of elements, and the values of elements in corresponding positions + * are equal. + * + * Returns: %TRUE if @a and @b are equal; %FALSE otherwise + * Since: 1.2 + */ +gboolean +json_array_equal (gconstpointer a, + gconstpointer b) +{ + JsonArray *array_a, *array_b; /* unowned */ + guint length_a, length_b, i; + + g_return_val_if_fail (a != NULL, FALSE); + g_return_val_if_fail (b != NULL, FALSE); + + array_a = (JsonArray *) a; + array_b = (JsonArray *) b; + + /* Identity comparison. */ + if (array_a == array_b) + return TRUE; + + /* Check lengths. */ + length_a = json_array_get_length (array_a); + length_b = json_array_get_length (array_b); + + if (length_a != length_b) + return FALSE; + + /* Check elements. */ + for (i = 0; i < length_a; i++) + { + JsonNode *child_a, *child_b; /* unowned */ + + child_a = json_array_get_element (array_a, i); + child_b = json_array_get_element (array_b, i); + + if (!json_node_equal (child_a, child_b)) + return FALSE; + } + + return TRUE; +} diff --git a/json-glib/json-builder.c b/json-glib/json-builder.c new file mode 100644 index 0000000..f8af1cd --- /dev/null +++ b/json-glib/json-builder.c @@ -0,0 +1,804 @@ +/* json-generator.c - JSON tree builder + * + * This file is part of JSON-GLib + * Copyright (C) 2010 Luca Bruno + * Copyright (C) 2015 Collabora Ltd. + * + * 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, see . + * + * Author: + * Luca Bruno + * Philip Withnall + */ + +/** + * SECTION:json-builder + * @Title: JsonBuilder + * @short_description: Generates JSON trees + * @See_Also: JsonGenerator + * + * #JsonBuilder provides an object for generating a JSON tree. + * You can generate only one tree with one #JsonBuilder instance. + * + * The root of the JSON tree can be either a #JsonObject or a #JsonArray. + * Thus the first call must necessarily be either + * json_builder_begin_object() or json_builder_begin_array(). + * + * For convenience to language bindings, #JsonBuilder returns itself from + * most of functions, making it easy to chain function calls. + */ + +#include "config.h" + +#include +#include + +#include "json-types-private.h" + +#include "json-builder.h" + +struct _JsonBuilderPrivate +{ + GQueue *stack; + JsonNode *root; + gboolean immutable; +}; + +enum +{ + PROP_IMMUTABLE = 1, + PROP_LAST +}; + +static GParamSpec *builder_props[PROP_LAST] = { NULL, }; + +typedef enum +{ + JSON_BUILDER_MODE_OBJECT, + JSON_BUILDER_MODE_ARRAY, + JSON_BUILDER_MODE_MEMBER +} JsonBuilderMode; + +typedef struct +{ + JsonBuilderMode mode; + + union + { + JsonObject *object; + JsonArray *array; + } data; + gchar *member_name; +} JsonBuilderState; + +static void +json_builder_state_free (JsonBuilderState *state) +{ + if (G_LIKELY (state)) + { + switch (state->mode) + { + case JSON_BUILDER_MODE_OBJECT: + case JSON_BUILDER_MODE_MEMBER: + json_object_unref (state->data.object); + g_free (state->member_name); + state->data.object = NULL; + state->member_name = NULL; + break; + + case JSON_BUILDER_MODE_ARRAY: + json_array_unref (state->data.array); + state->data.array = NULL; + break; + + default: + g_assert_not_reached (); + } + + g_slice_free (JsonBuilderState, state); + } +} + +G_DEFINE_TYPE_WITH_PRIVATE (JsonBuilder, json_builder, G_TYPE_OBJECT) + +static void +json_builder_free_all_state (JsonBuilder *builder) +{ + JsonBuilderState *state; + + while (!g_queue_is_empty (builder->priv->stack)) + { + state = g_queue_pop_head (builder->priv->stack); + json_builder_state_free (state); + } + + if (builder->priv->root) + { + json_node_unref (builder->priv->root); + builder->priv->root = NULL; + } +} + +static void +json_builder_finalize (GObject *gobject) +{ + JsonBuilderPrivate *priv = json_builder_get_instance_private ((JsonBuilder *) gobject); + + json_builder_free_all_state (JSON_BUILDER (gobject)); + + g_queue_free (priv->stack); + priv->stack = NULL; + + G_OBJECT_CLASS (json_builder_parent_class)->finalize (gobject); +} + +static void +json_builder_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + JsonBuilderPrivate *priv = JSON_BUILDER (gobject)->priv; + + switch (prop_id) + { + case PROP_IMMUTABLE: + /* Construct-only. */ + priv->immutable = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +json_builder_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + JsonBuilderPrivate *priv = JSON_BUILDER (gobject)->priv; + + switch (prop_id) + { + case PROP_IMMUTABLE: + g_value_set_boolean (value, priv->immutable); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +json_builder_class_init (JsonBuilderClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + /** + * JsonBuilder:immutable: + * + * Whether the #JsonNode tree built by the #JsonBuilder should be immutable + * when created. Making the output immutable on creation avoids the expense + * of traversing it to make it immutable later. + * + * Since: 1.2 + */ + builder_props[PROP_IMMUTABLE] = + g_param_spec_boolean ("immutable", + "Immutable Output", + "Whether the builder output is immutable.", + FALSE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + + gobject_class->set_property = json_builder_set_property; + gobject_class->get_property = json_builder_get_property; + gobject_class->finalize = json_builder_finalize; + + g_object_class_install_properties (gobject_class, PROP_LAST, builder_props); +} + +static void +json_builder_init (JsonBuilder *builder) +{ + JsonBuilderPrivate *priv = json_builder_get_instance_private (builder); + + builder->priv = priv; + + priv->stack = g_queue_new (); + priv->root = NULL; +} + +static inline JsonBuilderMode +json_builder_current_mode (JsonBuilder *builder) +{ + JsonBuilderState *state = g_queue_peek_head (builder->priv->stack); + return state->mode; +} + +static inline gboolean +json_builder_is_valid_add_mode (JsonBuilder *builder) +{ + JsonBuilderMode mode = json_builder_current_mode (builder); + return mode == JSON_BUILDER_MODE_MEMBER || mode == JSON_BUILDER_MODE_ARRAY; +} + +/** + * json_builder_new: + * + * Creates a new #JsonBuilder. You can use this object to generate a + * JSON tree and obtain the root #JsonNode. + * + * Return value: the newly created #JsonBuilder instance + */ +JsonBuilder * +json_builder_new (void) +{ + return g_object_new (JSON_TYPE_BUILDER, NULL); +} + +/** + * json_builder_new_immutable: + * + * Creates a new #JsonBuilder instance with its #JsonBuilder:immutable property + * set to %TRUE to create immutable output trees. + * + * Since: 1.2 + * Returns: (transfer full): a new #JsonBuilder + */ +JsonBuilder * +json_builder_new_immutable (void) +{ + return g_object_new (JSON_TYPE_BUILDER, "immutable", TRUE, NULL); +} + +/** + * json_builder_get_root: + * @builder: a #JsonBuilder + * + * Returns the root of the current constructed tree, if the build is complete + * (ie: all opened objects, object members and arrays are being closed). + * + * Return value: (nullable) (transfer full): the #JsonNode, or %NULL if the + * build is not complete. Free the returned value with json_node_unref(). + */ +JsonNode * +json_builder_get_root (JsonBuilder *builder) +{ + JsonNode *root = NULL; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + + if (builder->priv->root) + root = json_node_copy (builder->priv->root); + + /* Sanity check. */ + g_return_val_if_fail (!builder->priv->immutable || + root == NULL || + json_node_is_immutable (root), NULL); + + return root; +} + +/** + * json_builder_reset: + * @builder: a #JsonBuilder + * + * Resets the state of the @builder back to its initial state. + */ +void +json_builder_reset (JsonBuilder *builder) +{ + g_return_if_fail (JSON_IS_BUILDER (builder)); + + json_builder_free_all_state (builder); +} + +/** + * json_builder_begin_object: + * @builder: a #JsonBuilder + * + * Opens a subobject inside the given @builder. When done adding members to + * the subobject, json_builder_end_object() must be called. + * + * Can be called for first or only if the call is associated to an object member + * or an array element. + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_begin_object (JsonBuilder *builder) +{ + JsonObject *object; + JsonBuilderState *state; + JsonBuilderState *cur_state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (builder->priv->root == NULL, NULL); + g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL); + + object = json_object_new (); + cur_state = g_queue_peek_head (builder->priv->stack); + if (cur_state) + { + switch (cur_state->mode) + { + case JSON_BUILDER_MODE_ARRAY: + json_array_add_object_element (cur_state->data.array, json_object_ref (object)); + break; + + case JSON_BUILDER_MODE_MEMBER: + json_object_set_object_member (cur_state->data.object, cur_state->member_name, json_object_ref (object)); + g_free (cur_state->member_name); + cur_state->member_name = NULL; + cur_state->mode = JSON_BUILDER_MODE_OBJECT; + break; + + default: + g_assert_not_reached (); + } + } + + state = g_slice_new (JsonBuilderState); + state->data.object = object; + state->member_name = NULL; + state->mode = JSON_BUILDER_MODE_OBJECT; + g_queue_push_head (builder->priv->stack, state); + + return builder; +} + +/** + * json_builder_end_object: + * @builder: a #JsonBuilder + * + * Closes the subobject inside the given @builder that was opened by the most + * recent call to json_builder_begin_object(). + * + * Cannot be called after json_builder_set_member_name(). + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_end_object (JsonBuilder *builder) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL); + + state = g_queue_pop_head (builder->priv->stack); + + if (builder->priv->immutable) + json_object_seal (state->data.object); + + if (g_queue_is_empty (builder->priv->stack)) + { + builder->priv->root = json_node_new (JSON_NODE_OBJECT); + json_node_take_object (builder->priv->root, json_object_ref (state->data.object)); + + if (builder->priv->immutable) + json_node_seal (builder->priv->root); + } + + json_builder_state_free (state); + + return builder; +} + +/** + * json_builder_begin_array: + * @builder: a #JsonBuilder + * + * Opens a subarray inside the given @builder. When done adding members to + * the subarray, json_builder_end_array() must be called. + * + * Can be called for first or only if the call is associated to an object member + * or an array element. + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_begin_array (JsonBuilder *builder) +{ + JsonArray *array; + JsonBuilderState *state; + JsonBuilderState *cur_state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (builder->priv->root == NULL, NULL); + g_return_val_if_fail (g_queue_is_empty (builder->priv->stack) || json_builder_is_valid_add_mode (builder), NULL); + + array = json_array_new (); + cur_state = g_queue_peek_head (builder->priv->stack); + if (cur_state) + { + switch (cur_state->mode) + { + case JSON_BUILDER_MODE_ARRAY: + json_array_add_array_element (cur_state->data.array, json_array_ref (array)); + break; + + case JSON_BUILDER_MODE_MEMBER: + json_object_set_array_member (cur_state->data.object, cur_state->member_name, json_array_ref (array)); + g_free (cur_state->member_name); + cur_state->member_name = NULL; + cur_state->mode = JSON_BUILDER_MODE_OBJECT; + break; + + default: + g_assert_not_reached (); + } + } + + state = g_slice_new (JsonBuilderState); + state->data.array = array; + state->mode = JSON_BUILDER_MODE_ARRAY; + g_queue_push_head (builder->priv->stack, state); + + return builder; +} + +/** + * json_builder_end_array: + * @builder: a #JsonBuilder + * + * Closes the subarray inside the given @builder that was opened by the most + * recent call to json_builder_begin_array(). + * + * Cannot be called after json_builder_set_member_name(). + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_end_array (JsonBuilder *builder) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_ARRAY, NULL); + + state = g_queue_pop_head (builder->priv->stack); + + if (builder->priv->immutable) + json_array_seal (state->data.array); + + if (g_queue_is_empty (builder->priv->stack)) + { + builder->priv->root = json_node_new (JSON_NODE_ARRAY); + json_node_take_array (builder->priv->root, json_array_ref (state->data.array)); + + if (builder->priv->immutable) + json_node_seal (builder->priv->root); + } + + json_builder_state_free (state); + + return builder; +} + +/** + * json_builder_set_member_name: + * @builder: a #JsonBuilder + * @member_name: the name of the member + * + * Set the name of the next member in an object. The next call must add a value, + * open an object or an array. + * + * Can be called only if the call is associated to an object. + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_set_member_name (JsonBuilder *builder, + const gchar *member_name) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (member_name != NULL, NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_current_mode (builder) == JSON_BUILDER_MODE_OBJECT, NULL); + + state = g_queue_peek_head (builder->priv->stack); + state->member_name = g_strdup (member_name); + state->mode = JSON_BUILDER_MODE_MEMBER; + + return builder; +} + +/** + * json_builder_add_value: + * @builder: a #JsonBuilder + * @node: (transfer full): the value of the member or element + * + * If called after json_builder_set_member_name(), sets @node as member of the + * most recent opened object, otherwise @node is added as element of the most + * recent opened array. + * + * The builder will take ownership of the #JsonNode. + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_add_value (JsonBuilder *builder, + JsonNode *node) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (node != NULL, NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL); + + state = g_queue_peek_head (builder->priv->stack); + + if (builder->priv->immutable) + json_node_seal (node); + + switch (state->mode) + { + case JSON_BUILDER_MODE_MEMBER: + json_object_set_member (state->data.object, state->member_name, node); + g_free (state->member_name); + state->member_name = NULL; + state->mode = JSON_BUILDER_MODE_OBJECT; + break; + + case JSON_BUILDER_MODE_ARRAY: + json_array_add_element (state->data.array, node); + break; + + default: + g_assert_not_reached (); + } + + return builder; +} + +/** + * json_builder_add_int_value: + * @builder: a #JsonBuilder + * @value: the value of the member or element + * + * If called after json_builder_set_member_name(), sets @value as member of the + * most recent opened object, otherwise @value is added as element of the most + * recent opened array. + * + * See also: json_builder_add_value() + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_add_int_value (JsonBuilder *builder, + gint64 value) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL); + + state = g_queue_peek_head (builder->priv->stack); + switch (state->mode) + { + case JSON_BUILDER_MODE_MEMBER: + json_object_set_int_member (state->data.object, state->member_name, value); + g_free (state->member_name); + state->member_name = NULL; + state->mode = JSON_BUILDER_MODE_OBJECT; + break; + + case JSON_BUILDER_MODE_ARRAY: + json_array_add_int_element (state->data.array, value); + break; + + default: + g_assert_not_reached (); + } + + return builder; +} + +/** + * json_builder_add_double_value: + * @builder: a #JsonBuilder + * @value: the value of the member or element + * + * If called after json_builder_set_member_name(), sets @value as member of the + * most recent opened object, otherwise @value is added as element of the most + * recent opened array. + * + * See also: json_builder_add_value() + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_add_double_value (JsonBuilder *builder, + gdouble value) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL); + + state = g_queue_peek_head (builder->priv->stack); + + switch (state->mode) + { + case JSON_BUILDER_MODE_MEMBER: + json_object_set_double_member (state->data.object, state->member_name, value); + g_free (state->member_name); + state->member_name = NULL; + state->mode = JSON_BUILDER_MODE_OBJECT; + break; + + case JSON_BUILDER_MODE_ARRAY: + json_array_add_double_element (state->data.array, value); + break; + + default: + g_assert_not_reached (); + } + + return builder; +} + +/** + * json_builder_add_boolean_value: + * @builder: a #JsonBuilder + * @value: the value of the member or element + * + * If called after json_builder_set_member_name(), sets @value as member of the + * most recent opened object, otherwise @value is added as element of the most + * recent opened array. + * + * See also: json_builder_add_value() + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_add_boolean_value (JsonBuilder *builder, + gboolean value) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL); + + state = g_queue_peek_head (builder->priv->stack); + + switch (state->mode) + { + case JSON_BUILDER_MODE_MEMBER: + json_object_set_boolean_member (state->data.object, state->member_name, value); + g_free (state->member_name); + state->member_name = NULL; + state->mode = JSON_BUILDER_MODE_OBJECT; + break; + + case JSON_BUILDER_MODE_ARRAY: + json_array_add_boolean_element (state->data.array, value); + break; + + default: + g_assert_not_reached (); + } + + return builder; +} + +/** + * json_builder_add_string_value: + * @builder: a #JsonBuilder + * @value: the value of the member or element + * + * If called after json_builder_set_member_name(), sets @value as member of the + * most recent opened object, otherwise @value is added as element of the most + * recent opened array. + * + * See also: json_builder_add_value() + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if the + * call was inconsistent + */ +JsonBuilder * +json_builder_add_string_value (JsonBuilder *builder, + const gchar *value) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL); + + state = g_queue_peek_head (builder->priv->stack); + + switch (state->mode) + { + case JSON_BUILDER_MODE_MEMBER: + json_object_set_string_member (state->data.object, state->member_name, value); + g_free (state->member_name); + state->member_name = NULL; + state->mode = JSON_BUILDER_MODE_OBJECT; + break; + + case JSON_BUILDER_MODE_ARRAY: + json_array_add_string_element (state->data.array, value); + break; + + default: + g_assert_not_reached (); + } + + return builder; +} + +/** + * json_builder_add_null_value: + * @builder: a #JsonBuilder + * + * If called after json_builder_set_member_name(), sets null as member of the + * most recent opened object, otherwise null is added as element of the most + * recent opened array. + * + * See also: json_builder_add_value() + * + * Return value: (nullable) (transfer none): the #JsonBuilder, or %NULL if + * the call was inconsistent + */ +JsonBuilder * +json_builder_add_null_value (JsonBuilder *builder) +{ + JsonBuilderState *state; + + g_return_val_if_fail (JSON_IS_BUILDER (builder), NULL); + g_return_val_if_fail (!g_queue_is_empty (builder->priv->stack), NULL); + g_return_val_if_fail (json_builder_is_valid_add_mode (builder), NULL); + + state = g_queue_peek_head (builder->priv->stack); + + switch (state->mode) + { + case JSON_BUILDER_MODE_MEMBER: + json_object_set_null_member (state->data.object, state->member_name); + g_free (state->member_name); + state->member_name = NULL; + state->mode = JSON_BUILDER_MODE_OBJECT; + break; + + case JSON_BUILDER_MODE_ARRAY: + json_array_add_null_element (state->data.array); + break; + + default: + g_assert_not_reached (); + } + + return builder; +} diff --git a/json-glib/json-builder.h b/json-glib/json-builder.h new file mode 100644 index 0000000..b35230e --- /dev/null +++ b/json-glib/json-builder.h @@ -0,0 +1,126 @@ +/* json-builder.h: JSON tree builder + * + * This file is part of JSON-GLib + * Copyright (C) 2010 Luca Bruno + * + * 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, see . + * + * Author: + * Luca Bruno + */ + +#ifndef __JSON_BUILDER_H__ +#define __JSON_BUILDER_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define JSON_TYPE_BUILDER (json_builder_get_type ()) +#define JSON_BUILDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_BUILDER, JsonBuilder)) +#define JSON_IS_BUILDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_BUILDER)) +#define JSON_BUILDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), JSON_TYPE_BUILDER, JsonBuilderClass)) +#define JSON_IS_BUILDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), JSON_TYPE_BUILDER)) +#define JSON_BUILDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), JSON_TYPE_BUILDER, JsonBuilderClass)) + +typedef struct _JsonBuilder JsonBuilder; +typedef struct _JsonBuilderPrivate JsonBuilderPrivate; +typedef struct _JsonBuilderClass JsonBuilderClass; + +/** + * JsonBuilder: + * + * The `JsonBuilder` structure contains only private data and should be + * accessed using the provided API + * + * Since: 0.12 + */ +struct _JsonBuilder +{ + /*< private >*/ + GObject parent_instance; + + JsonBuilderPrivate *priv; +}; + +/** + * JsonBuilderClass: + * + * The `JsonBuilderClass` structure contains only private data + * + * Since: 0.12 + */ +struct _JsonBuilderClass +{ + /*< private >*/ + GObjectClass parent_class; + + /* padding, for future expansion */ + void (* _json_reserved1) (void); + void (* _json_reserved2) (void); +}; + +JSON_AVAILABLE_IN_1_0 +GType json_builder_get_type (void) G_GNUC_CONST; + +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_new (void); +JSON_AVAILABLE_IN_1_2 +JsonBuilder *json_builder_new_immutable (void); +JSON_AVAILABLE_IN_1_0 +JsonNode *json_builder_get_root (JsonBuilder *builder); +JSON_AVAILABLE_IN_1_0 +void json_builder_reset (JsonBuilder *builder); + +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_begin_array (JsonBuilder *builder); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_end_array (JsonBuilder *builder); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_begin_object (JsonBuilder *builder); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_end_object (JsonBuilder *builder); + +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_set_member_name (JsonBuilder *builder, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_add_value (JsonBuilder *builder, + JsonNode *node); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_add_int_value (JsonBuilder *builder, + gint64 value); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_add_double_value (JsonBuilder *builder, + gdouble value); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_add_boolean_value (JsonBuilder *builder, + gboolean value); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_add_string_value (JsonBuilder *builder, + const gchar *value); +JSON_AVAILABLE_IN_1_0 +JsonBuilder *json_builder_add_null_value (JsonBuilder *builder); + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonBuilder, g_object_unref) +#endif + +G_END_DECLS + +#endif /* __JSON_BUILDER_H__ */ diff --git a/json-glib/json-debug.c b/json-glib/json-debug.c new file mode 100644 index 0000000..b9c3b8f --- /dev/null +++ b/json-glib/json-debug.c @@ -0,0 +1,38 @@ +#include "config.h" + +#include "json-debug.h" + +static unsigned int json_debug_flags = 0; + +#ifdef JSON_ENABLE_DEBUG +static const GDebugKey json_debug_keys[] = { + { "parser", JSON_DEBUG_PARSER }, + { "gobject", JSON_DEBUG_GOBJECT }, + { "path", JSON_DEBUG_PATH }, + { "node", JSON_DEBUG_NODE }, +}; +#endif /* JSON_ENABLE_DEBUG */ + +JsonDebugFlags +json_get_debug_flags (void) +{ +#ifdef JSON_ENABLE_DEBUG + static gboolean json_debug_flags_set; + const gchar *env_str; + + if (G_LIKELY (json_debug_flags_set)) + return json_debug_flags; + + env_str = g_getenv ("JSON_DEBUG"); + if (env_str != NULL && *env_str != '\0') + { + json_debug_flags |= g_parse_debug_string (env_str, + json_debug_keys, + G_N_ELEMENTS (json_debug_keys)); + } + + json_debug_flags_set = TRUE; +#endif /* JSON_ENABLE_DEBUG */ + + return json_debug_flags; +} diff --git a/json-glib/json-debug.h b/json-glib/json-debug.h new file mode 100644 index 0000000..1b3da52 --- /dev/null +++ b/json-glib/json-debug.h @@ -0,0 +1,51 @@ +#ifndef __JSON_DEBUG_H__ +#define __JSON_DEBUG_H__ + +#include + +G_BEGIN_DECLS + +typedef enum { + JSON_DEBUG_PARSER = 1 << 0, + JSON_DEBUG_GOBJECT = 1 << 1, + JSON_DEBUG_PATH = 1 << 2, + JSON_DEBUG_NODE = 1 << 3 +} JsonDebugFlags; + +#define JSON_HAS_DEBUG(flag) (json_get_debug_flags () & JSON_DEBUG_##flag) + +#ifdef JSON_ENABLE_DEBUG + +# ifdef __GNUC__ + +# define JSON_NOTE(type,x,a...) G_STMT_START { \ + if (JSON_HAS_DEBUG (type)) { \ + g_message ("[" #type "] " G_STRLOC ": " x, ##a); \ + } } G_STMT_END + +# else +/* Try the C99 version; unfortunately, this does not allow us to pass + * empty arguments to the macro, which means we have to + * do an intemediate printf. + */ +# define JSON_NOTE(type,...) G_STMT_START { \ + if (JSON_HAS_DEBUG (type)) { \ + gchar * _fmt = g_strdup_printf (__VA_ARGS__); \ + g_message ("[" #type "] " G_STRLOC ": %s",_fmt); \ + g_free (_fmt); \ + } } G_STMT_END + +# endif /* __GNUC__ */ + +#else + +#define JSON_NOTE(type,...) G_STMT_START { } G_STMT_END + +#endif /* JSON_ENABLE_DEBUG */ + +G_GNUC_INTERNAL +JsonDebugFlags json_get_debug_flags (void); + +G_END_DECLS + +#endif /* __JSON_DEBUG_H__ */ diff --git a/json-glib/json-enum-types.c.in b/json-glib/json-enum-types.c.in new file mode 100644 index 0000000..da07c46 --- /dev/null +++ b/json-glib/json-enum-types.c.in @@ -0,0 +1,44 @@ +/*** BEGIN file-header ***/ +#ifndef JSON_COMPILATION +#define JSON_COMPILATION +#endif + +#include "config.h" +#include "json-enum-types.h" +/*** END file-header ***/ + +/*** BEGIN file-production ***/ + +/* enumerations from "@filename@" */ +#include "@filename@" + +/*** END file-production ***/ + +/*** BEGIN value-header ***/ +GType +@enum_name@_get_type (void) +{ + static volatile gsize g_enum_type_id__volatile = 0; + + if (g_once_init_enter (&g_enum_type_id__volatile)) + { + static const G@Type@Value values[] = { +/*** END value-header ***/ + +/*** BEGIN value-production ***/ + { @VALUENAME@, "@VALUENAME@", "@valuenick@" }, +/*** END value-production ***/ + +/*** BEGIN value-tail ***/ + { 0, NULL, NULL } + }; + + GType g_enum_type_id = + g_@type@_register_static (g_intern_static_string ("@EnumName@"), values); + + g_once_init_leave (&g_enum_type_id__volatile, g_enum_type_id); + } + + return g_enum_type_id__volatile; +} +/*** END value-tail ***/ diff --git a/json-glib/json-enum-types.h.in b/json-glib/json-enum-types.h.in new file mode 100644 index 0000000..06720bc --- /dev/null +++ b/json-glib/json-enum-types.h.in @@ -0,0 +1,32 @@ +/*** BEGIN file-header ***/ +#ifndef __JSON_ENUM_TYPES_H__ +#define __JSON_ENUM_TYPES_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +/*** END file-header ***/ + +/*** BEGIN file-production ***/ +/* enumerations from "@basename@" */ +/*** END file-production ***/ + +/*** BEGIN file-tail ***/ +G_END_DECLS + +#endif /* !__JSON_ENUM_TYPES_H__ */ +/*** END file-tail ***/ + +/*** BEGIN value-header ***/ +JSON_AVAILABLE_IN_1_0 +GType @enum_name@_get_type (void) G_GNUC_CONST; +#define JSON_TYPE_@ENUMSHORT@ (@enum_name@_get_type()) + +/*** END value-header ***/ + diff --git a/json-glib/json-gboxed.c b/json-glib/json-gboxed.c new file mode 100644 index 0000000..f274e6d --- /dev/null +++ b/json-glib/json-gboxed.c @@ -0,0 +1,352 @@ +/* json-gboxed.c - JSON GBoxed integration + * + * This file is part of JSON-GLib + * + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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. + * + * Author: + * Emmanuele Bassi + */ + +/** + * SECTION:json-gboxed + * @short_description: Serialize and deserialize GBoxed types + * + * GLib's #GBoxed type is a generic wrapper for arbitrary C structures. + * + * JSON-GLib allows serialization and deserialization of a #GBoxed type + * by registering functions mapping a #JsonNodeType to a specific + * #GType. + * + * When registering a #GBoxed type you should also register the + * corresponding transformation functions, e.g.: + * + * |[ + * GType + * my_struct_get_type (void) + * { + * static GType boxed_type = 0; + * + * if (boxed_type == 0) + * { + * boxed_type = + * g_boxed_type_register_static (g_intern_static_string ("MyStruct"), + * (GBoxedCopyFunc) my_struct_copy, + * (GBoxedFreeFunc) my_struct_free); + * + * json_boxed_register_serialize_func (boxed_type, JSON_NODE_OBJECT, + * my_struct_serialize); + * json_boxed_register_deserialize_func (boxed_type, JSON_NODE_OBJECT, + * my_struct_deserialize); + * } + * + * return boxed_type; + * } + * ]| + * + * The serialization function will be invoked by json_boxed_serialize(): + * it will be passed a pointer to the C structure and it must return a + * #JsonNode. The deserialization function will be invoked by + * json_boxed_deserialize(): it will be passed a #JsonNode for the + * declared type and it must return a newly allocated C structure. + * + * It is possible to check whether a #GBoxed type can be deserialized + * from a specific #JsonNodeType, and whether a #GBoxed can be serialized + * and to which specific #JsonNodeType. + */ + +#include "config.h" + +#include +#include + +#include "json-types-private.h" +#include "json-gobject.h" + +typedef struct _BoxedTransform BoxedTransform; + +struct _BoxedTransform +{ + GType boxed_type; + gint node_type; + + JsonBoxedSerializeFunc serialize; + JsonBoxedDeserializeFunc deserialize; +}; + +G_LOCK_DEFINE_STATIC (boxed_serialize); +static GSList *boxed_serialize = NULL; + +G_LOCK_DEFINE_STATIC (boxed_deserialize); +static GSList *boxed_deserialize = NULL; + +static gint +boxed_transforms_cmp (gconstpointer a, + gconstpointer b) +{ + const BoxedTransform *ta = a; + const BoxedTransform *tb = b; + + return tb->boxed_type - ta->boxed_type; +} + +static gint +boxed_transforms_find (gconstpointer a, + gconstpointer b) +{ + const BoxedTransform *haystack = a; + const BoxedTransform *needle = b; + + if (needle->node_type != -1) + return (haystack->boxed_type == needle->boxed_type && + haystack->node_type == needle->node_type) ? 0 : 1; + else + return (haystack->boxed_type == needle->boxed_type) ? 0 : 1; +} + +static BoxedTransform * +lookup_boxed_transform (GSList *transforms, + GType gboxed_type, + JsonNodeType node_type) +{ + BoxedTransform lookup; + GSList *t; + + lookup.boxed_type = gboxed_type; + lookup.node_type = node_type; + + t = g_slist_find_custom (transforms, &lookup, boxed_transforms_find); + if (t == NULL) + return NULL; + + return t->data; +} + +/** + * json_boxed_register_serialize_func: (skip) + * @gboxed_type: a boxed type + * @node_type: a node type + * @serialize_func: serialization function for @boxed_type into + * a #JsonNode of type @node_type + * + * Registers a serialization function for a #GBoxed of type @gboxed_type + * to a #JsonNode of type @node_type + * + * Since: 0.10 + */ +void +json_boxed_register_serialize_func (GType gboxed_type, + JsonNodeType node_type, + JsonBoxedSerializeFunc serialize_func) +{ + BoxedTransform *t; + + g_return_if_fail (G_TYPE_IS_BOXED (gboxed_type)); + g_return_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE); + + G_LOCK (boxed_serialize); + + t = lookup_boxed_transform (boxed_serialize, gboxed_type, node_type); + if (t == NULL) + { + t = g_slice_new (BoxedTransform); + + t->boxed_type = gboxed_type; + t->node_type = node_type; + t->serialize = serialize_func; + + boxed_serialize = g_slist_insert_sorted (boxed_serialize, t, + boxed_transforms_cmp); + } + else + g_warning ("A serialization function for the boxed type %s into " + "JSON nodes of type %s already exists", + g_type_name (gboxed_type), + json_node_type_get_name (node_type)); + + G_UNLOCK (boxed_serialize); +} + +/** + * json_boxed_register_deserialize_func: (skip) + * @gboxed_type: a boxed type + * @node_type: a node type + * @deserialize_func: deserialization function for @boxed_type from + * a #JsonNode of type @node_type + * + * Registers a deserialization function for a #GBoxed of type @gboxed_type + * from a #JsonNode of type @node_type + * + * Since: 0.10 + */ +void +json_boxed_register_deserialize_func (GType gboxed_type, + JsonNodeType node_type, + JsonBoxedDeserializeFunc deserialize_func) +{ + BoxedTransform *t; + + g_return_if_fail (G_TYPE_IS_BOXED (gboxed_type)); + g_return_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE); + + G_LOCK (boxed_deserialize); + + t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type); + if (t == NULL) + { + t = g_slice_new (BoxedTransform); + + t->boxed_type = gboxed_type; + t->node_type = node_type; + t->deserialize = deserialize_func; + + boxed_deserialize = g_slist_insert_sorted (boxed_deserialize, t, + boxed_transforms_cmp); + } + else + g_warning ("A deserialization function for the boxed type %s from " + "JSON nodes of type %s already exists", + g_type_name (gboxed_type), + json_node_type_get_name (node_type)); + + G_UNLOCK (boxed_deserialize); +} + +/** + * json_boxed_can_serialize: + * @gboxed_type: a boxed type + * @node_type: (out): the #JsonNode type to which the boxed type can be + * serialized into + * + * Checks whether it is possible to serialize a #GBoxed of + * type @gboxed_type into a #JsonNode. The type of the + * #JsonNode is placed inside @node_type if the function + * returns %TRUE and it's undefined otherwise. + * + * Return value: %TRUE if the type can be serialized, + * and %FALSE otherwise. + * + * Since: 0.10 + */ +gboolean +json_boxed_can_serialize (GType gboxed_type, + JsonNodeType *node_type) +{ + BoxedTransform *t; + + g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), FALSE); + g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, FALSE); + + t = lookup_boxed_transform (boxed_serialize, gboxed_type, -1); + if (t != NULL) + { + if (node_type) + *node_type = t->node_type; + + return TRUE; + } + + return FALSE; +} + +/** + * json_boxed_can_deserialize: + * @gboxed_type: a boxed type + * @node_type: a #JsonNode type + * + * Checks whether it is possible to deserialize a #GBoxed of + * type @gboxed_type from a #JsonNode of type @node_type + * + * Return value: %TRUE if the type can be deserialized, %FALSE otherwise + * + * Since: 0.10 + */ +gboolean +json_boxed_can_deserialize (GType gboxed_type, + JsonNodeType node_type) +{ + BoxedTransform *t; + + g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), FALSE); + g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, FALSE); + + t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type); + if (t != NULL) + return TRUE; + + return FALSE; +} + +/** + * json_boxed_serialize: + * @gboxed_type: a boxed type + * @boxed: a pointer to a #GBoxed of type @gboxed_type + * + * Serializes @boxed, a pointer to a #GBoxed of type @gboxed_type, + * into a #JsonNode + * + * Return value: (nullable) (transfer full): a #JsonNode with the serialization of + * the boxed type, or %NULL if serialization either failed or was not possible + * + * Since: 0.10 + */ +JsonNode * +json_boxed_serialize (GType gboxed_type, + gconstpointer boxed) +{ + BoxedTransform *t; + + g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), NULL); + g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, NULL); + g_return_val_if_fail (boxed != NULL, NULL); + + t = lookup_boxed_transform (boxed_serialize, gboxed_type, -1); + if (t != NULL && t->serialize != NULL) + return t->serialize (boxed); + + return NULL; +} + +/** + * json_boxed_deserialize: + * @gboxed_type: a boxed type + * @node: a #JsonNode + * + * Deserializes @node into a #GBoxed of @gboxed_type + * + * Return value: (transfer full): the newly allocated #GBoxed. Use + * g_boxed_free() to release the resources allocated by this + * function + * + * Since: 0.10 + */ +gpointer +json_boxed_deserialize (GType gboxed_type, + JsonNode *node) +{ + JsonNodeType node_type; + BoxedTransform *t; + + g_return_val_if_fail (G_TYPE_IS_BOXED (gboxed_type), NULL); + g_return_val_if_fail (G_TYPE_IS_ABSTRACT (gboxed_type) == FALSE, NULL); + g_return_val_if_fail (node != NULL, NULL); + + node_type = json_node_get_node_type (node); + + t = lookup_boxed_transform (boxed_deserialize, gboxed_type, node_type); + if (t != NULL && t->deserialize != NULL) + return t->deserialize (node); + + return NULL; +} diff --git a/json-glib/json-generator.c b/json-glib/json-generator.c new file mode 100644 index 0000000..346be65 --- /dev/null +++ b/json-glib/json-generator.c @@ -0,0 +1,796 @@ +/* json-generator.c - JSON streams generator + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +/** + * SECTION:json-generator + * @short_description: Generates JSON data streams + * + * #JsonGenerator provides an object for generating a JSON data stream and + * put it into a buffer or a file. + */ + +#include "config.h" + +#include +#include + +#include "json-types-private.h" + +#include "json-generator.h" + +struct _JsonGeneratorPrivate +{ + JsonNode *root; + + guint indent; + gunichar indent_char; + + guint pretty : 1; +}; + +enum +{ + PROP_0, + + PROP_PRETTY, + PROP_INDENT, + PROP_ROOT, + PROP_INDENT_CHAR, + + PROP_LAST +}; + +static void dump_value (GString *buffer, + gint level, + JsonNode *node); +static void dump_array (JsonGenerator *generator, + GString *buffer, + gint level, + JsonArray *array); +static void dump_object (JsonGenerator *generator, + GString *buffer, + gint level, + JsonObject *object); + +static GParamSpec *generator_props[PROP_LAST] = { NULL, }; + +G_DEFINE_TYPE_WITH_PRIVATE (JsonGenerator, json_generator, G_TYPE_OBJECT) + +static void +json_strescape (GString *output, + const gchar *str) +{ + const gchar *p; + const gchar *end; + gsize len; + + len = strlen (str); + end = str + len; + + for (p = str; p < end; p++) + { + if (*p == '\\' || *p == '"') + { + g_string_append_c (output, '\\'); + g_string_append_c (output, *p); + } + else if ((*p > 0 && *p < 0x1f) || *p == 0x7f) + { + switch (*p) + { + case '\b': + g_string_append (output, "\\b"); + break; + case '\f': + g_string_append (output, "\\f"); + break; + case '\n': + g_string_append (output, "\\n"); + break; + case '\r': + g_string_append (output, "\\r"); + break; + case '\t': + g_string_append (output, "\\t"); + break; + default: + g_string_append_printf (output, "\\u00%02x", (guint)*p); + break; + } + } + else + { + g_string_append_c (output, *p); + } + } +} + +static void +json_generator_finalize (GObject *gobject) +{ + JsonGeneratorPrivate *priv; + + priv = json_generator_get_instance_private ((JsonGenerator *) gobject); + if (priv->root != NULL) + json_node_unref (priv->root); + + G_OBJECT_CLASS (json_generator_parent_class)->finalize (gobject); +} + +static void +json_generator_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + JsonGenerator *generator = JSON_GENERATOR (gobject); + + switch (prop_id) + { + case PROP_PRETTY: + json_generator_set_pretty (generator, g_value_get_boolean (value)); + break; + + case PROP_INDENT: + json_generator_set_indent (generator, g_value_get_uint (value)); + break; + + case PROP_INDENT_CHAR: + json_generator_set_indent_char (generator, g_value_get_uint (value)); + break; + + case PROP_ROOT: + json_generator_set_root (generator, g_value_get_boxed (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +json_generator_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + JsonGeneratorPrivate *priv = JSON_GENERATOR (gobject)->priv; + + switch (prop_id) + { + case PROP_PRETTY: + g_value_set_boolean (value, priv->pretty); + break; + case PROP_INDENT: + g_value_set_uint (value, priv->indent); + break; + case PROP_INDENT_CHAR: + g_value_set_uint (value, priv->indent_char); + break; + case PROP_ROOT: + g_value_set_boxed (value, priv->root); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +json_generator_class_init (JsonGeneratorClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + /** + * JsonGenerator:pretty: + * + * Whether the output should be "pretty-printed", with indentation and + * newlines. The indentation level can be controlled by using the + * JsonGenerator:indent property + */ + generator_props[PROP_PRETTY] = + g_param_spec_boolean ("pretty", + "Pretty", + "Pretty-print the output", + FALSE, + G_PARAM_READWRITE); + + /** + * JsonGenerator:indent: + * + * Number of spaces to be used to indent when pretty printing. + */ + generator_props[PROP_INDENT] = + g_param_spec_uint ("indent", + "Indent", + "Number of indentation spaces", + 0, G_MAXUINT, + 2, + G_PARAM_READWRITE); + + /** + * JsonGenerator:root: + * + * The root #JsonNode to be used when constructing a JSON data + * stream. + * + * Since: 0.4 + */ + generator_props[PROP_ROOT] = + g_param_spec_boxed ("root", + "Root", + "Root of the JSON data tree", + JSON_TYPE_NODE, + G_PARAM_READWRITE); + + /** + * JsonGenerator:indent-char: + * + * The character that should be used when indenting in pretty print. + * + * Since: 0.6 + */ + generator_props[PROP_INDENT_CHAR] = + g_param_spec_unichar ("indent-char", + "Indent Char", + "Character that should be used when indenting", + ' ', + G_PARAM_READWRITE); + + gobject_class->set_property = json_generator_set_property; + gobject_class->get_property = json_generator_get_property; + gobject_class->finalize = json_generator_finalize; + g_object_class_install_properties (gobject_class, PROP_LAST, generator_props); +} + +static void +json_generator_init (JsonGenerator *generator) +{ + JsonGeneratorPrivate *priv = json_generator_get_instance_private (generator); + + generator->priv = priv; + + priv->pretty = FALSE; + priv->indent = 2; + priv->indent_char = ' '; +} + +static void +dump_node (JsonGenerator *generator, + GString *buffer, + gint level, + const gchar *name, + JsonNode *node) +{ + JsonGeneratorPrivate *priv = generator->priv; + gboolean pretty = priv->pretty; + guint indent = priv->indent; + + if (pretty) + { + guint i; + + for (i = 0; i < (level * indent); i++) + g_string_append_c (buffer, priv->indent_char); + } + + if (name) + { + g_string_append_c (buffer, '"'); + json_strescape (buffer, name); + g_string_append_c (buffer, '"'); + + if (pretty) + g_string_append (buffer, " : "); + else + g_string_append_c (buffer, ':'); + } + + switch (JSON_NODE_TYPE (node)) + { + case JSON_NODE_NULL: + g_string_append (buffer, "null"); + break; + + case JSON_NODE_VALUE: + dump_value (buffer, level, node); + break; + + case JSON_NODE_ARRAY: + dump_array (generator, buffer, level, + json_node_get_array (node)); + break; + + case JSON_NODE_OBJECT: + dump_object (generator, buffer, level, + json_node_get_object (node)); + break; + } +} + +static void +dump_value (GString *buffer, + gint level, + JsonNode *node) +{ + const JsonValue *value; + + value = node->data.value; + + switch (value->type) + { + case JSON_VALUE_INT: + g_string_append_printf (buffer, "%" G_GINT64_FORMAT, json_value_get_int (value)); + break; + + case JSON_VALUE_STRING: + { + g_string_append_c (buffer, '"'); + json_strescape (buffer, json_value_get_string (value)); + g_string_append_c (buffer, '"'); + } + break; + + case JSON_VALUE_DOUBLE: + { + gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; + + g_string_append (buffer, + g_ascii_dtostr (buf, sizeof (buf), + json_value_get_double (value))); + /* ensure doubles don't become ints */ + if (g_strstr_len (buf, G_ASCII_DTOSTR_BUF_SIZE, ".") == NULL) + { + g_string_append (buffer, ".0"); + } + } + break; + + case JSON_VALUE_BOOLEAN: + g_string_append (buffer, json_value_get_boolean (value) ? "true" : "false"); + break; + + case JSON_VALUE_NULL: + g_string_append (buffer, "null"); + break; + + default: + break; + } +} + +static void +dump_array (JsonGenerator *generator, + GString *buffer, + gint level, + JsonArray *array) +{ + JsonGeneratorPrivate *priv = generator->priv; + guint array_len = json_array_get_length (array); + guint i; + gboolean pretty = priv->pretty; + guint indent = priv->indent; + + g_string_append_c (buffer, '['); + + if (pretty) + g_string_append_c (buffer, '\n'); + + for (i = 0; i < array_len; i++) + { + JsonNode *cur = json_array_get_element (array, i); + + dump_node (generator, buffer, level + 1, NULL, cur); + + if ((i + 1) != array_len) + g_string_append_c (buffer, ','); + + if (pretty) + g_string_append_c (buffer, '\n'); + } + + if (pretty) + { + for (i = 0; i < (level * indent); i++) + g_string_append_c (buffer, priv->indent_char); + } + + g_string_append_c (buffer, ']'); +} + +static void +dump_object (JsonGenerator *generator, + GString *buffer, + gint level, + JsonObject *object) +{ + JsonGeneratorPrivate *priv = generator->priv; + GQueue *members; + GList *l; + gboolean pretty = priv->pretty; + guint indent = priv->indent; + guint i; + + g_string_append_c (buffer, '{'); + + if (pretty) + g_string_append_c (buffer, '\n'); + + members = json_object_get_members_internal (object); + + for (l = members->head; l != NULL; l = l->next) + { + const gchar *member_name = l->data; + JsonNode *cur = json_object_get_member (object, member_name); + + dump_node (generator, buffer, level + 1, member_name, cur); + + if (l->next != NULL) + g_string_append_c (buffer, ','); + + if (pretty) + g_string_append_c (buffer, '\n'); + } + + if (pretty) + { + for (i = 0; i < (level * indent); i++) + g_string_append_c (buffer, priv->indent_char); + } + + g_string_append_c (buffer, '}'); +} + +/** + * json_generator_new: + * + * Creates a new #JsonGenerator. You can use this object to generate a + * JSON data stream starting from a data object model composed by + * #JsonNodes. + * + * Return value: the newly created #JsonGenerator instance + */ +JsonGenerator * +json_generator_new (void) +{ + return g_object_new (JSON_TYPE_GENERATOR, NULL); +} + +/** + * json_generator_to_gstring: + * @generator: a #JsonGenerator + * @string: a #GString + * + * Generates a JSON data stream from @generator + * and appends it to @string. + * + * Return value: (transfer none): a #GString holding a JSON data stream. + * Use g_string_free() to free the allocated resources. + * + * Since: 1.4 + */ +GString * +json_generator_to_gstring (JsonGenerator *generator, + GString *string) +{ + JsonNode *root; + + g_return_val_if_fail (JSON_IS_GENERATOR (generator), NULL); + g_return_val_if_fail (string != NULL, NULL); + + root = generator->priv->root; + if (root != NULL) + dump_node (generator, string, 0, NULL, root); + + return string; +} + +/** + * json_generator_to_data: + * @generator: a #JsonGenerator + * @length: (out): return location for the length of the returned + * buffer, or %NULL + * + * Generates a JSON data stream from @generator and returns it as a + * buffer. + * + * Return value: a newly allocated buffer holding a JSON data stream. + * Use g_free() to free the allocated resources. + */ +gchar * +json_generator_to_data (JsonGenerator *generator, + gsize *length) +{ + GString *string; + + g_return_val_if_fail (JSON_IS_GENERATOR (generator), NULL); + + string = g_string_new (""); + json_generator_to_gstring (generator, string); + + if (length) + *length = string->len; + + return g_string_free (string, FALSE); +} + +/** + * json_generator_to_file: + * @generator: a #JsonGenerator + * @filename: path to the target file + * @error: return location for a #GError, or %NULL + * + * Creates a JSON data stream and puts it inside @filename, overwriting the + * current file contents. This operation is atomic. + * + * Return value: %TRUE if saving was successful. + */ +gboolean +json_generator_to_file (JsonGenerator *generator, + const gchar *filename, + GError **error) +{ + gchar *buffer; + gsize len; + gboolean retval; + + g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + + buffer = json_generator_to_data (generator, &len); + retval = g_file_set_contents (filename, buffer, len, error); + g_free (buffer); + + return retval; +} + +/** + * json_generator_to_stream: + * @generator: a #JsonGenerator + * @stream: a #GOutputStream + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @error: return location for a #GError, or %NULL + * + * Outputs JSON data and streams it (synchronously) to @stream. + * + * Return value: %TRUE if the write operation was successful, and %FALSE + * on failure. In case of error, the #GError will be filled accordingly + * + * Since: 0.12 + */ +gboolean +json_generator_to_stream (JsonGenerator *generator, + GOutputStream *stream, + GCancellable *cancellable, + GError **error) +{ + gboolean retval; + gchar *buffer; + gsize len; + + g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE); + g_return_val_if_fail (G_IS_OUTPUT_STREAM (stream), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + buffer = json_generator_to_data (generator, &len); + retval = g_output_stream_write (stream, buffer, len, cancellable, error); + g_free (buffer); + + return retval; +} + +/** + * json_generator_set_root: + * @generator: a #JsonGenerator + * @node: a #JsonNode + * + * Sets @node as the root of the JSON data stream to be serialized by + * the #JsonGenerator. + * + * The passed @node is copied by the generator object, so it can be + * safely freed after calling this function. + */ +void +json_generator_set_root (JsonGenerator *generator, + JsonNode *node) +{ + g_return_if_fail (JSON_IS_GENERATOR (generator)); + + if (generator->priv->root == node) + return; + + if (generator->priv->root != NULL) + { + json_node_unref (generator->priv->root); + generator->priv->root = NULL; + } + + if (node != NULL) + generator->priv->root = json_node_copy (node); + + g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_ROOT]); +} + +/** + * json_generator_get_root: + * @generator: a #JsonGenerator + * + * Retrieves a pointer to the root #JsonNode set using + * json_generator_set_root(). + * + * Return value: (nullable) (transfer none): a #JsonNode, or %NULL. The returned + * node is owned by the #JsonGenerator and it should not be freed + * + * Since: 0.14 + */ +JsonNode * +json_generator_get_root (JsonGenerator *generator) +{ + g_return_val_if_fail (JSON_IS_GENERATOR (generator), NULL); + + return generator->priv->root; +} + +/** + * json_generator_set_pretty: + * @generator: a #JsonGenerator + * @is_pretty: whether the generated string should be pretty printed + * + * Sets whether the generated JSON should be pretty printed, using the + * indentation character specified in the #JsonGenerator:indent-char + * property and the spacing specified in #JsonGenerator:indent property. + * + * Since: 0.14 + */ +void +json_generator_set_pretty (JsonGenerator *generator, + gboolean is_pretty) +{ + JsonGeneratorPrivate *priv; + + g_return_if_fail (JSON_IS_GENERATOR (generator)); + + priv = generator->priv; + + is_pretty = !!is_pretty; + + if (priv->pretty != is_pretty) + { + priv->pretty = is_pretty; + + g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_PRETTY]); + } +} + +/** + * json_generator_get_pretty: + * @generator: a #JsonGenerator + * + * Retrieves the value set using json_generator_set_pretty(). + * + * Return value: %TRUE if the generated JSON should be pretty-printed, and + * %FALSE otherwise + * + * Since: 0.14 + */ +gboolean +json_generator_get_pretty (JsonGenerator *generator) +{ + g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE); + + return generator->priv->pretty; +} + +/** + * json_generator_set_indent: + * @generator: a #JsonGenerator + * @indent_level: the number of repetitions of the indentation character + * that should be applied when pretty printing + * + * Sets the number of repetitions for each indentation level. + * + * Since: 0.14 + */ +void +json_generator_set_indent (JsonGenerator *generator, + guint indent_level) +{ + JsonGeneratorPrivate *priv; + + g_return_if_fail (JSON_IS_GENERATOR (generator)); + + priv = generator->priv; + + if (priv->indent != indent_level) + { + priv->indent = indent_level; + + g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_INDENT]); + } +} + +/** + * json_generator_get_indent: + * @generator: a #JsonGenerator + * + * Retrieves the value set using json_generator_set_indent(). + * + * Return value: the number of repetitions per indentation level + * + * Since: 0.14 + */ +guint +json_generator_get_indent (JsonGenerator *generator) +{ + g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE); + + return generator->priv->indent; +} + +/** + * json_generator_set_indent_char: + * @generator: a #JsonGenerator + * @indent_char: a Unicode character to be used when indenting + * + * Sets the character to be used when indenting + * + * Since: 0.14 + */ +void +json_generator_set_indent_char (JsonGenerator *generator, + gunichar indent_char) +{ + JsonGeneratorPrivate *priv; + + g_return_if_fail (JSON_IS_GENERATOR (generator)); + + priv = generator->priv; + + if (priv->indent_char != indent_char) + { + priv->indent_char = indent_char; + + g_object_notify_by_pspec (G_OBJECT (generator), generator_props[PROP_INDENT_CHAR]); + } +} + +/** + * json_generator_get_indent_char: + * @generator: a #JsonGenerator + * + * Retrieves the value set using json_generator_set_indent_char(). + * + * Return value: the character to be used when indenting + * + * Since: 0.14 + */ +gunichar +json_generator_get_indent_char (JsonGenerator *generator) +{ + g_return_val_if_fail (JSON_IS_GENERATOR (generator), FALSE); + + return generator->priv->indent_char; +} diff --git a/json-glib/json-generator.h b/json-glib/json-generator.h new file mode 100644 index 0000000..30a28dc --- /dev/null +++ b/json-glib/json-generator.h @@ -0,0 +1,128 @@ +/* json-generator.h - JSON streams generator + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_GENERATOR_H__ +#define __JSON_GENERATOR_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define JSON_TYPE_GENERATOR (json_generator_get_type ()) +#define JSON_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_GENERATOR, JsonGenerator)) +#define JSON_IS_GENERATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_GENERATOR)) +#define JSON_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), JSON_TYPE_GENERATOR, JsonGeneratorClass)) +#define JSON_IS_GENERATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), JSON_TYPE_GENERATOR)) +#define JSON_GENERATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), JSON_TYPE_GENERATOR, JsonGeneratorClass)) + +typedef struct _JsonGenerator JsonGenerator; +typedef struct _JsonGeneratorPrivate JsonGeneratorPrivate; +typedef struct _JsonGeneratorClass JsonGeneratorClass; + +/** + * JsonGenerator: + * + * JSON data streams generator. The contents of the #JsonGenerator structure + * are private and should only be accessed via the provided API. + */ +struct _JsonGenerator +{ + /*< private >*/ + GObject parent_instance; + + JsonGeneratorPrivate *priv; +}; + +/** + * JsonGeneratorClass: + * + * #JsonGenerator class + */ +struct _JsonGeneratorClass +{ + /*< private >*/ + GObjectClass parent_class; + + /* padding, for future expansion */ + void (* _json_reserved1) (void); + void (* _json_reserved2) (void); + void (* _json_reserved3) (void); + void (* _json_reserved4) (void); +}; + +JSON_AVAILABLE_IN_1_0 +GType json_generator_get_type (void) G_GNUC_CONST; + +JSON_AVAILABLE_IN_1_0 +JsonGenerator * json_generator_new (void); + +JSON_AVAILABLE_IN_1_0 +void json_generator_set_pretty (JsonGenerator *generator, + gboolean is_pretty); +JSON_AVAILABLE_IN_1_0 +gboolean json_generator_get_pretty (JsonGenerator *generator); +JSON_AVAILABLE_IN_1_0 +void json_generator_set_indent (JsonGenerator *generator, + guint indent_level); +JSON_AVAILABLE_IN_1_0 +guint json_generator_get_indent (JsonGenerator *generator); +JSON_AVAILABLE_IN_1_0 +void json_generator_set_indent_char (JsonGenerator *generator, + gunichar indent_char); +JSON_AVAILABLE_IN_1_0 +gunichar json_generator_get_indent_char (JsonGenerator *generator); +JSON_AVAILABLE_IN_1_0 +void json_generator_set_root (JsonGenerator *generator, + JsonNode *node); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_generator_get_root (JsonGenerator *generator); + +JSON_AVAILABLE_IN_1_4 +GString *json_generator_to_gstring (JsonGenerator *generator, + GString *string); + +JSON_AVAILABLE_IN_1_0 +gchar * json_generator_to_data (JsonGenerator *generator, + gsize *length); +JSON_AVAILABLE_IN_1_0 +gboolean json_generator_to_file (JsonGenerator *generator, + const gchar *filename, + GError **error); +JSON_AVAILABLE_IN_1_0 +gboolean json_generator_to_stream (JsonGenerator *generator, + GOutputStream *stream, + GCancellable *cancellable, + GError **error); + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonGenerator, g_object_unref) +#endif + +G_END_DECLS + +#endif /* __JSON_GENERATOR_H__ */ diff --git a/json-glib/json-glib-format.c b/json-glib/json-glib-format.c new file mode 100644 index 0000000..52a40ec --- /dev/null +++ b/json-glib/json-glib-format.c @@ -0,0 +1,221 @@ +/* json-glib-format - Formats JSON data + * + * This file is part of JSON-GLib + * + * Copyright © 2013 Emmanuele Bassi + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#include "config.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#if defined (G_OS_WIN32) && !defined (HAVE_UNISTD_H) +#include + +#define STDOUT_FILENO 1 +#endif + +static char **files = NULL; +static gboolean prettify = FALSE; +static int indent_spaces = 2; + +static GOptionEntry entries[] = { + { "prettify", 'p', 0, G_OPTION_ARG_NONE, &prettify, N_("Prettify output"), NULL }, + { "indent-spaces", 'i', 0, G_OPTION_ARG_INT, &indent_spaces, N_("Indentation spaces"), NULL }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files, NULL, NULL }, + { NULL }, +}; + +static gboolean +format (JsonParser *parser, + JsonGenerator *generator, + GFile *file) +{ + GInputStream *in; + GError *error; + gboolean res = TRUE; + gboolean parse_res; + gboolean close_res; + char *data, *p; + gsize len; + + error = NULL; + + in = (GInputStream *) g_file_read (file, NULL, &error); + if (in == NULL) + { + /* Translators: the first %s is the program name, the second one + * is the URI of the file, the third is the error message. + */ + g_printerr (_("%s: %s: error opening file: %s\n"), + g_get_prgname (), g_file_get_uri (file), error->message); + g_error_free (error); + return FALSE; + } + + parse_res = json_parser_load_from_stream (parser, in, NULL, &error); + if (!parse_res) + { + /* Translators: the first %s is the program name, the second one + * is the URI of the file, the third is the error message. + */ + g_printerr (_("%s: %s: error parsing file: %s\n"), + g_get_prgname (), g_file_get_uri (file), error->message); + g_clear_error (&error); + res = FALSE; + goto out; + } + + json_generator_set_root (generator, json_parser_get_root (parser)); + data = json_generator_to_data (generator, &len); + p = data; + while (len > 0) + { + gssize written = write (STDOUT_FILENO, p, len); + + if (written == -1 && errno != EINTR) + { + /* Translators: the first %s is the program name, the + * second one is the URI of the file. + */ + g_printerr (_("%s: %s: error writing to stdout"), g_get_prgname (), g_file_get_uri (file)); + res = FALSE; + goto out; + } + + len -= written; + p += written; + } + + if (write (STDOUT_FILENO, "\n", 1) < 0) + g_error ("%s: %s", g_get_prgname (), g_strerror (errno)); + + g_free (data); + +out: + close_res = g_input_stream_close (in, NULL, &error); + if (!close_res) + { + /* Translators: the first %s is the program name, the second one + * is the URI of the file, the third is the error message. + */ + g_printerr (_("%s: %s: error closing: %s\n"), + g_get_prgname (), g_file_get_uri (file), error->message); + g_clear_error (&error); + res = FALSE; + } + + return res; +} + +int +main (int argc, + char *argv[]) +{ + GOptionContext *context = NULL; + GError *error = NULL; + const char *description; + const char *summary; + gchar *param; + JsonParser *parser; + JsonGenerator *generator; + gboolean res; + int i; + + setlocale (LC_ALL, ""); + + bindtextdomain (GETTEXT_PACKAGE, JSON_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + param = g_strdup_printf (("%s..."), _("FILE")); + /* Translators: this message will appear after the usage string */ + /* and before the list of options. */ + summary = _("Format JSON files."); + description = _("json-glib-format formats JSON resources."); + + context = g_option_context_new (param); + g_option_context_set_summary (context, summary); + g_option_context_set_description (context, description); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + g_option_context_parse (context, &argc, &argv, &error); + g_option_context_free (context); + + g_free (param); + + if (error != NULL) + { + /* Translators: the %s is the program name. This error message + * means the user is calling json-glib-validate without any + * argument. + */ + g_printerr (_("Error parsing commandline options: %s\n"), error->message); + g_printerr ("\n"); + g_printerr (_("Try “%s --help” for more information."), g_get_prgname ()); + g_printerr ("\n"); + g_error_free (error); + return 1; + } + + if (files == NULL) + { + /* Translators: the %s is the program name. This error message + * means the user is calling json-glib-validate without any + * argument. + */ + g_printerr (_("%s: missing files"), g_get_prgname ()); + g_printerr ("\n"); + g_printerr (_("Try “%s --help” for more information."), g_get_prgname ()); + g_printerr ("\n"); + return 1; + } + + generator = json_generator_new (); + json_generator_set_pretty (generator, prettify); + json_generator_set_indent (generator, indent_spaces); + + parser = json_parser_new (); + res = TRUE; + i = 0; + + do + { + GFile *file = g_file_new_for_commandline_arg (files[i]); + + res = format (parser, generator, file) && res; + g_object_unref (file); + } + while (files[++i] != NULL); + + g_object_unref (parser); + g_object_unref (generator); + + return res ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/json-glib/json-glib-validate.c b/json-glib/json-glib-validate.c new file mode 100644 index 0000000..b717275 --- /dev/null +++ b/json-glib/json-glib-validate.c @@ -0,0 +1,173 @@ +/* json-glib-validate - Checks JSON data for errors + * + * This file is part of JSON-GLib + * + * Copyright © 2013 Emmanuele Bassi + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#include "config.h" + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include + +#include +#include +#include + +static char **files = NULL; + +static GOptionEntry entries[] = { + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &files, NULL, NULL }, + { NULL }, +}; + +static gboolean +validate (JsonParser *parser, + GFile *file) +{ + GInputStream *in; + GError *error; + gboolean res = TRUE; + gboolean parse_res; + gboolean close_res; + + error = NULL; + + in = (GInputStream *) g_file_read (file, NULL, &error); + if (in == NULL) + { + /* Translators: the first %s is the program name, the second one + * is the URI of the file, the third is the error message. + */ + g_printerr (_("%s: %s: error opening file: %s\n"), + g_get_prgname (), g_file_get_uri (file), error->message); + g_error_free (error); + return FALSE; + } + + parse_res = json_parser_load_from_stream (parser, in, NULL, &error); + if (!parse_res) + { + /* Translators: the first %s is the program name, the second one + * is the URI of the file, the third is the error message. + */ + g_printerr (_("%s: %s: error parsing file: %s\n"), + g_get_prgname (), g_file_get_uri (file), error->message); + g_clear_error (&error); + res = FALSE; + } + + close_res = g_input_stream_close (in, NULL, &error); + if (!close_res) + { + /* Translators: the first %s is the program name, the second one + * is the URI of the file, the third is the error message. + */ + g_printerr (_("%s: %s: error closing: %s\n"), + g_get_prgname (), g_file_get_uri (file), error->message); + g_clear_error (&error); + res = FALSE; + } + + return res; +} + +int +main (int argc, + char *argv[]) +{ + GOptionContext *context = NULL; + GError *error = NULL; + const char *description; + const char *summary; + gchar *param; + JsonParser *parser; + gboolean res; + int i; + + setlocale (LC_ALL, ""); + + bindtextdomain (GETTEXT_PACKAGE, JSON_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + param = g_strdup_printf (("%s..."), _("FILE")); + /* Translators: this message will appear after the usage string */ + /* and before the list of options. */ + summary = _("Validate JSON files."); + description = _("json-glib-validate validates JSON data at the given URI."); + + context = g_option_context_new (param); + g_option_context_set_summary (context, summary); + g_option_context_set_description (context, description); + g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + g_option_context_parse (context, &argc, &argv, &error); + g_option_context_free (context); + + g_free (param); + + if (error != NULL) + { + /* Translators: the %s is the program name. This error message + * means the user is calling json-glib-validate without any + * argument. + */ + g_printerr (_("Error parsing commandline options: %s\n"), error->message); + g_printerr ("\n"); + g_printerr (_("Try “%s --help” for more information."), g_get_prgname ()); + g_printerr ("\n"); + g_error_free (error); + return 1; + } + + if (files == NULL) + { + /* Translators: the %s is the program name. This error message + * means the user is calling json-glib-validate without any + * argument. + */ + g_printerr (_("%s: missing files"), g_get_prgname ()); + g_printerr ("\n"); + g_printerr (_("Try “%s --help” for more information."), g_get_prgname ()); + g_printerr ("\n"); + return 1; + } + + parser = json_parser_new (); + res = TRUE; + i = 0; + + do + { + GFile *file = g_file_new_for_commandline_arg (files[i]); + + res = validate (parser, file) && res; + g_object_unref (file); + } + while (files[++i] != NULL); + + g_object_unref (parser); + + return res ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/json-glib/json-glib.h b/json-glib/json-glib.h new file mode 100644 index 0000000..939ce0e --- /dev/null +++ b/json-glib/json-glib.h @@ -0,0 +1,48 @@ +/* json-glib.h: Main header + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_GLIB_H__ +#define __JSON_GLIB_H__ + +#define __JSON_GLIB_INSIDE__ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#undef __JSON_GLIB_INSIDE__ + +#endif /* __JSON_GLIB_H__ */ diff --git a/json-glib/json-gobject-private.h b/json-glib/json-gobject-private.h new file mode 100644 index 0000000..5369ebf --- /dev/null +++ b/json-glib/json-gobject-private.h @@ -0,0 +1,39 @@ +/* json-gobject-private.h - GObject private + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_GOBJECT_PRIVATE_H__ +#define __JSON_GOBJECT_PRIVATE_H__ + +#include "json-gobject.h" + +G_BEGIN_DECLS + +JsonNode *json_serialize_pspec (const GValue *real_value, + GParamSpec *pspec); +gboolean json_deserialize_pspec (GValue *value, + GParamSpec *pspec, + JsonNode *node); + +G_END_DECLS + +#endif /* __JSON_GOBJECT_PRIVATE_H__ */ diff --git a/json-glib/json-gobject.c b/json-glib/json-gobject.c new file mode 100644 index 0000000..076517b --- /dev/null +++ b/json-glib/json-gobject.c @@ -0,0 +1,1015 @@ +/* json-gobject.c - JSON GObject integration + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * + * 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 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. + * + * Author: + * Emmanuele Bassi + */ + +/** + * SECTION:json-gobject + * @short_description: Serialize and deserialize GObjects + * + * JSON-GLib provides API for serializing and deserializing #GObject + * instances to and from JSON data streams. + * + * Simple #GObject classes can be (de)serialized into JSON objects, if the + * properties have compatible types with the native JSON types (integers, + * booleans, strings, string vectors). If the class to be (de)serialized has + * complex data types for properties (like boxed types or other objects) + * then the class should implement the provided #JsonSerializable interface + * and its virtual functions. + */ + +#include "config.h" + +#include +#include + +#include + +#include "json-types-private.h" +#include "json-gobject-private.h" + +#include "json-debug.h" +#include "json-parser.h" +#include "json-generator.h" + +static gboolean +enum_from_string (GType type, + const gchar *string, + gint *enum_value) +{ + GEnumClass *eclass; + GEnumValue *ev; + gchar *endptr; + gint value; + gboolean retval = TRUE; + + g_return_val_if_fail (G_TYPE_IS_ENUM (type), 0); + g_return_val_if_fail (string != NULL, 0); + + value = strtoul (string, &endptr, 0); + if (endptr != string) /* parsed a number */ + *enum_value = value; + else + { + eclass = g_type_class_ref (type); + ev = g_enum_get_value_by_name (eclass, string); + if (!ev) + ev = g_enum_get_value_by_nick (eclass, string); + + if (ev) + *enum_value = ev->value; + else + retval = FALSE; + + g_type_class_unref (eclass); + } + + return retval; +} + +static gboolean +flags_from_string (GType type, + const gchar *string, + gint *flags_value) +{ + GFlagsClass *fclass; + gchar *endptr, *prevptr; + guint i, j, ret, value; + gchar *flagstr; + GFlagsValue *fv; + const gchar *flag; + gunichar ch; + gboolean eos; + + g_return_val_if_fail (G_TYPE_IS_FLAGS (type), 0); + g_return_val_if_fail (string != 0, 0); + + ret = TRUE; + + value = strtoul (string, &endptr, 0); + if (endptr != string) /* parsed a number */ + *flags_value = value; + else + { + fclass = g_type_class_ref (type); + + flagstr = g_strdup (string); + for (value = i = j = 0; ; i++) + { + eos = flagstr[i] == '\0'; + + if (!eos && flagstr[i] != '|') + continue; + + flag = &flagstr[j]; + endptr = &flagstr[i]; + + if (!eos) + { + flagstr[i++] = '\0'; + j = i; + } + + /* trim spaces */ + for (;;) + { + ch = g_utf8_get_char (flag); + if (!g_unichar_isspace (ch)) + break; + flag = g_utf8_next_char (flag); + } + + while (endptr > flag) + { + prevptr = g_utf8_prev_char (endptr); + ch = g_utf8_get_char (prevptr); + if (!g_unichar_isspace (ch)) + break; + endptr = prevptr; + } + + if (endptr > flag) + { + *endptr = '\0'; + fv = g_flags_get_value_by_name (fclass, flag); + + if (!fv) + fv = g_flags_get_value_by_nick (fclass, flag); + + if (fv) + value |= fv->value; + else + { + ret = FALSE; + break; + } + } + + if (eos) + { + *flags_value = value; + break; + } + } + + g_free (flagstr); + + g_type_class_unref (fclass); + } + + return ret; +} + +static GObject * +json_gobject_new (GType gtype, + JsonObject *object) +{ + JsonSerializableIface *iface = NULL; + JsonSerializable *serializable = NULL; + gboolean find_property; + gboolean deserialize_property; + gboolean set_property; + GQueue *members; + GList *l; + GQueue members_left = G_QUEUE_INIT; + guint n_members; + GObjectClass *klass; + GObject *retval; + GArray *construct_params; + gint i; + + klass = g_type_class_ref (gtype); + + n_members = json_object_get_size (object); + members = json_object_get_members_internal (object); + + /* first pass: construct-only properties; here we cannot use Serializable + * because we don't have an instance yet; we use the default implementation + * of json_deserialize_pspec() to deserialize known types + * + * FIXME - find a way to allow deserialization for these properties + */ + construct_params = g_array_sized_new (FALSE, FALSE, sizeof (GParameter), n_members); + + for (l = members->head; l != NULL; l = l->next) + { + const gchar *member_name = l->data; + GParamSpec *pspec; + GParameter param = { NULL, }; + JsonNode *val; + gboolean res = FALSE; + + pspec = g_object_class_find_property (klass, member_name); + if (!pspec) + goto next_member; + + /* we only apply construct-only properties here */ + if ((pspec->flags & G_PARAM_CONSTRUCT_ONLY) == 0) + goto next_member; + + if (!(pspec->flags & G_PARAM_WRITABLE)) + goto next_member; + + g_value_init (¶m.value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + + val = json_object_get_member (object, member_name); + res = json_deserialize_pspec (¶m.value, pspec, val); + if (!res) + { + g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"", + pspec->name, G_VALUE_TYPE_NAME (¶m.value), g_type_name (gtype)); + + g_value_unset (¶m.value); + } + else + { + param.name = g_strdup (pspec->name); + + g_array_append_val (construct_params, param); + + continue; + } + + next_member: + g_queue_push_tail (&members_left, l->data); + } + + G_GNUC_BEGIN_IGNORE_DEPRECATIONS + retval = g_object_newv (gtype, + construct_params->len, + (GParameter *) construct_params->data); + G_GNUC_END_IGNORE_DEPRECATIONS + + /* free the contents of the GArray */ + for (i = 0; i < construct_params->len; i++) + { + GParameter *param = &g_array_index (construct_params, GParameter, i); + + g_free ((gchar *) param->name); + g_value_unset (¶m->value); + } + + g_array_free (construct_params, TRUE); + + /* do the Serializable type check once */ + if (g_type_is_a (gtype, JSON_TYPE_SERIALIZABLE)) + { + serializable = JSON_SERIALIZABLE (retval); + iface = JSON_SERIALIZABLE_GET_IFACE (serializable); + find_property = (iface->find_property != NULL); + deserialize_property = (iface->deserialize_property != NULL); + set_property = (iface->set_property != NULL); + } + else + { + find_property = FALSE; + deserialize_property = FALSE; + set_property = FALSE; + } + + g_object_freeze_notify (retval); + + for (l = members_left.head; l != NULL; l = l->next) + { + const gchar *member_name = l->data; + GParamSpec *pspec; + JsonNode *val; + GValue value = { 0, }; + gboolean res = FALSE; + + if (find_property) + pspec = json_serializable_find_property (serializable, member_name); + else + pspec = g_object_class_find_property (klass, member_name); + + if (pspec == NULL) + continue; + + /* we should have dealt with these above */ + if (pspec->flags & G_PARAM_CONSTRUCT_ONLY) + continue; + + if (!(pspec->flags & G_PARAM_WRITABLE)) + continue; + + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + + val = json_object_get_member (object, member_name); + + if (deserialize_property) + { + JSON_NOTE (GOBJECT, "Using JsonSerializable for property '%s'", pspec->name); + res = json_serializable_deserialize_property (serializable, + pspec->name, + &value, + pspec, + val); + } + + if (!res) + { + JSON_NOTE (GOBJECT, "Using json_deserialize_pspec for property '%s'", pspec->name); + res = json_deserialize_pspec (&value, pspec, val); + } + + if (res) + { + JSON_NOTE (GOBJECT, "Calling set_property('%s', '%s')", + pspec->name, + g_type_name (G_VALUE_TYPE (&value))); + + if (set_property) + json_serializable_set_property (serializable, pspec, &value); + else + g_object_set_property (retval, pspec->name, &value); + } + else + g_warning ("Failed to deserialize \"%s\" property of type \"%s\" for an object of type \"%s\"", + pspec->name, g_type_name (G_VALUE_TYPE (&value)), g_type_name (gtype)); + + g_value_unset (&value); + } + + g_queue_clear (&members_left); + + g_object_thaw_notify (retval); + + g_type_class_unref (klass); + + return retval; +} + +static JsonObject * +json_gobject_dump (GObject *gobject) +{ + JsonSerializableIface *iface = NULL; + JsonSerializable *serializable = NULL; + gboolean list_properties = FALSE; + gboolean serialize_property = FALSE; + gboolean get_property = FALSE; + JsonObject *object; + GParamSpec **pspecs; + guint n_pspecs, i; + + if (JSON_IS_SERIALIZABLE (gobject)) + { + serializable = JSON_SERIALIZABLE (gobject); + iface = JSON_SERIALIZABLE_GET_IFACE (gobject); + list_properties = (iface->list_properties != NULL); + serialize_property = (iface->serialize_property != NULL); + get_property = (iface->get_property != NULL); + } + + object = json_object_new (); + + if (list_properties) + pspecs = json_serializable_list_properties (serializable, &n_pspecs); + else + pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (gobject), &n_pspecs); + + for (i = 0; i < n_pspecs; i++) + { + GParamSpec *pspec = pspecs[i]; + GValue value = { 0, }; + JsonNode *node = NULL; + + /* read only what we can */ + if (!(pspec->flags & G_PARAM_READABLE)) + continue; + + g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec)); + + if (get_property) + json_serializable_get_property (serializable, pspec, &value); + else + g_object_get_property (gobject, pspec->name, &value); + + /* if there is a serialization vfunc, then it is completely responsible + * for serializing the property, possibly by calling the implementation + * of the default JsonSerializable interface through chaining up + */ + if (serialize_property) + { + node = json_serializable_serialize_property (serializable, + pspec->name, + &value, + pspec); + } + /* skip if the value is the default for the property */ + else if (!g_param_value_defaults (pspec, &value)) + node = json_serialize_pspec (&value, pspec); + + if (node) + json_object_set_member (object, pspec->name, node); + + g_value_unset (&value); + } + + g_free (pspecs); + + return object; +} + +gboolean +json_deserialize_pspec (GValue *value, + GParamSpec *pspec, + JsonNode *node) +{ + GValue node_value = { 0, }; + gboolean retval = FALSE; + + if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_BOXED) + { + JsonNodeType node_type = json_node_get_node_type (node); + GType boxed_type = G_VALUE_TYPE (value); + + if (json_boxed_can_deserialize (boxed_type, node_type)) + { + gpointer boxed = json_boxed_deserialize (boxed_type, node); + + g_value_take_boxed (value, boxed); + + return TRUE; + } + } + + switch (JSON_NODE_TYPE (node)) + { + case JSON_NODE_OBJECT: + if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT)) + { + GObject *object; + + object = json_gobject_new (G_VALUE_TYPE (value), json_node_get_object (node)); + if (object != NULL) + g_value_take_object (value, object); + else + g_value_set_object (value, NULL); + + retval = TRUE; + } + break; + + case JSON_NODE_ARRAY: + if (G_VALUE_HOLDS (value, G_TYPE_STRV)) + { + JsonArray *array = json_node_get_array (node); + guint i, array_len = json_array_get_length (array); + GPtrArray *str_array = g_ptr_array_sized_new (array_len + 1); + + for (i = 0; i < array_len; i++) + { + JsonNode *val = json_array_get_element (array, i); + + if (JSON_NODE_TYPE (val) != JSON_NODE_VALUE) + continue; + + if (json_node_get_string (val) != NULL) + g_ptr_array_add (str_array, (gpointer) json_node_get_string (val)); + } + + g_ptr_array_add (str_array, NULL); + + g_value_set_boxed (value, str_array->pdata); + + g_ptr_array_free (str_array, TRUE); + + retval = TRUE; + } + break; + + case JSON_NODE_VALUE: + json_node_get_value (node, &node_value); +#if 0 + { + gchar *node_str = g_strdup_value_contents (&node_value); + g_debug ("%s: value type '%s' := node value type '%s' -> '%s'", + G_STRLOC, + g_type_name (G_VALUE_TYPE (value)), + g_type_name (G_VALUE_TYPE (&node_value)), + node_str); + g_free (node_str); + } +#endif + + switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value))) + { + case G_TYPE_BOOLEAN: + case G_TYPE_INT64: + case G_TYPE_STRING: + if (G_VALUE_HOLDS (&node_value, G_VALUE_TYPE (value))) + { + g_value_copy (&node_value, value); + retval = TRUE; + } + break; + + case G_TYPE_INT: + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_int (value, (gint) g_value_get_int64 (&node_value)); + retval = TRUE; + } + break; + + case G_TYPE_CHAR: + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_schar (value, (gchar) g_value_get_int64 (&node_value)); + retval = TRUE; + } + break; + + case G_TYPE_UINT: + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_uint (value, (guint) g_value_get_int64 (&node_value)); + retval = TRUE; + } + break; + + case G_TYPE_UCHAR: + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_uchar (value, (guchar) g_value_get_int64 (&node_value)); + retval = TRUE; + } + break; + + case G_TYPE_LONG: + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_long (value, (glong) g_value_get_int64 (&node_value)); + retval = TRUE; + } + break; + + case G_TYPE_ULONG: + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_ulong (value, (gulong) g_value_get_int64 (&node_value)); + retval = TRUE; + } + break; + + case G_TYPE_UINT64: + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_uint64 (value, (guint64) g_value_get_int64 (&node_value)); + retval = TRUE; + } + break; + + case G_TYPE_DOUBLE: + + if (G_VALUE_HOLDS (&node_value, G_TYPE_DOUBLE)) + { + g_value_set_double (value, g_value_get_double (&node_value)); + retval = TRUE; + } + else if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_double (value, (gdouble) g_value_get_int64 (&node_value)); + retval = TRUE; + } + + break; + + case G_TYPE_FLOAT: + if (G_VALUE_HOLDS (&node_value, G_TYPE_DOUBLE)) + { + g_value_set_float (value, (gfloat) g_value_get_double (&node_value)); + retval = TRUE; + } + else if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + g_value_set_float (value, (gfloat) g_value_get_int64 (&node_value)); + retval = TRUE; + } + + break; + + case G_TYPE_ENUM: + { + gint enum_value = 0; + + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + enum_value = g_value_get_int64 (&node_value); + retval = TRUE; + } + else if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING)) + { + retval = enum_from_string (G_VALUE_TYPE (value), + g_value_get_string (&node_value), + &enum_value); + } + + if (retval) + g_value_set_enum (value, enum_value); + } + break; + + case G_TYPE_FLAGS: + { + gint flags_value = 0; + + if (G_VALUE_HOLDS (&node_value, G_TYPE_INT64)) + { + flags_value = g_value_get_int64 (&node_value); + retval = TRUE; + } + else if (G_VALUE_HOLDS (&node_value, G_TYPE_STRING)) + { + retval = flags_from_string (G_VALUE_TYPE (value), + g_value_get_string (&node_value), + &flags_value); + } + + if (retval) + g_value_set_flags (value, flags_value); + } + break; + + default: + retval = FALSE; + break; + } + + g_value_unset (&node_value); + break; + + case JSON_NODE_NULL: + if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_STRING) + { + g_value_set_string (value, NULL); + retval = TRUE; + } + else if (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (value)) == G_TYPE_OBJECT) + { + g_value_set_object (value, NULL); + retval = TRUE; + } + else + retval = FALSE; + + break; + } + + return retval; +} + +JsonNode * +json_serialize_pspec (const GValue *real_value, + GParamSpec *pspec) +{ + JsonNode *retval = NULL; + JsonNodeType node_type; + + switch (G_TYPE_FUNDAMENTAL (G_VALUE_TYPE (real_value))) + { + /* JSON native types */ + case G_TYPE_INT64: + retval = json_node_init_int (json_node_alloc (), g_value_get_int64 (real_value)); + break; + + case G_TYPE_BOOLEAN: + retval = json_node_init_boolean (json_node_alloc (), g_value_get_boolean (real_value)); + break; + + case G_TYPE_DOUBLE: + retval = json_node_init_double (json_node_alloc (), g_value_get_double (real_value)); + break; + + case G_TYPE_STRING: + retval = json_node_init_string (json_node_alloc (), g_value_get_string (real_value)); + break; + + /* auto-promoted types */ + case G_TYPE_INT: + retval = json_node_init_int (json_node_alloc (), g_value_get_int (real_value)); + break; + + case G_TYPE_UINT: + retval = json_node_init_int (json_node_alloc (), g_value_get_uint (real_value)); + break; + + case G_TYPE_LONG: + retval = json_node_init_int (json_node_alloc (), g_value_get_long (real_value)); + break; + + case G_TYPE_ULONG: + retval = json_node_init_int (json_node_alloc (), g_value_get_ulong (real_value)); + break; + + case G_TYPE_UINT64: + retval = json_node_init_int (json_node_alloc (), g_value_get_uint64 (real_value)); + break; + + case G_TYPE_FLOAT: + retval = json_node_init_double (json_node_alloc (), g_value_get_float (real_value)); + break; + + case G_TYPE_CHAR: + retval = json_node_alloc (); + json_node_init_int (retval, g_value_get_schar (real_value)); + break; + + case G_TYPE_UCHAR: + retval = json_node_init_int (json_node_alloc (), g_value_get_uchar (real_value)); + break; + + case G_TYPE_ENUM: + retval = json_node_init_int (json_node_alloc (), g_value_get_enum (real_value)); + break; + + case G_TYPE_FLAGS: + retval = json_node_init_int (json_node_alloc (), g_value_get_flags (real_value)); + break; + + /* complex types */ + case G_TYPE_BOXED: + if (G_VALUE_HOLDS (real_value, G_TYPE_STRV)) + { + gchar **strv = g_value_get_boxed (real_value); + gint i, strv_len; + JsonArray *array; + + strv_len = g_strv_length (strv); + array = json_array_sized_new (strv_len); + + for (i = 0; i < strv_len; i++) + { + JsonNode *str = json_node_new (JSON_NODE_VALUE); + + json_node_set_string (str, strv[i]); + json_array_add_element (array, str); + } + + retval = json_node_init_array (json_node_alloc (), array); + json_array_unref (array); + } + else if (json_boxed_can_serialize (G_VALUE_TYPE (real_value), &node_type)) + { + gpointer boxed = g_value_get_boxed (real_value); + + retval = json_boxed_serialize (G_VALUE_TYPE (real_value), boxed); + } + else + g_warning ("Boxed type '%s' is not handled by JSON-GLib", + g_type_name (G_VALUE_TYPE (real_value))); + break; + + case G_TYPE_OBJECT: + { + GObject *object = g_value_get_object (real_value); + + retval = json_node_alloc (); + + if (object != NULL) + { + json_node_init (retval, JSON_NODE_OBJECT); + json_node_take_object (retval, json_gobject_dump (object)); + } + else + json_node_init_null (retval); + } + break; + + case G_TYPE_NONE: + retval = json_node_new (JSON_NODE_NULL); + break; + + default: + g_warning ("Unsupported type `%s'", g_type_name (G_VALUE_TYPE (real_value))); + break; + } + + return retval; +} + +/** + * json_gobject_deserialize: + * @gtype: the type of the #GObject to create + * @node: a #JsonNode of type %JSON_NODE_OBJECT describing the + * instance of type @gtype + * + * Creates a new #GObject of type @gtype, and constructs it + * using the members of the passed #JsonObject + * + * Return value: (transfer full): The newly created #GObject + * instance. Use g_object_unref() to free the resources + * allocated by this function + * + * Since: 0.10 + */ +GObject * +json_gobject_deserialize (GType gtype, + JsonNode *node) +{ + g_return_val_if_fail (g_type_is_a (gtype, G_TYPE_OBJECT), NULL); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL); + + return json_gobject_new (gtype, json_node_get_object (node)); +} + +/** + * json_gobject_serialize: + * @gobject: a #GObject + * + * Creates a #JsonNode representing the passed #GObject + * instance. Each member of the returned JSON object will + * map to a property of the #GObject + * + * Return value: (transfer full): the newly created #JsonNode + * of type %JSON_NODE_OBJECT. Use json_node_unref() to free + * the resources allocated by this function + * + * Since: 0.10 + */ +JsonNode * +json_gobject_serialize (GObject *gobject) +{ + JsonNode *retval; + + g_return_val_if_fail (G_IS_OBJECT (gobject), NULL); + + retval = json_node_new (JSON_NODE_OBJECT); + json_node_take_object (retval, json_gobject_dump (gobject)); + + return retval; +} + +/** + * json_construct_gobject: + * @gtype: the #GType of object to construct + * @data: a JSON data stream + * @length: length of the data stream + * @error: return location for a #GError, or %NULL + * + * Deserializes a JSON data stream and creates the corresponding + * #GObject class. If @gtype implements the #JsonSerializableIface + * interface, it will be asked to deserialize all the JSON members + * into the respective properties; otherwise, the default implementation + * will be used to translate the compatible JSON native types. + * + * Note: the JSON data stream must be an object declaration. + * + * Return value: (transfer full): a #GObject or %NULL + * + * Since: 0.4 + * + * Deprecated: 0.10: Use json_gobject_from_data() instead + */ +GObject * +json_construct_gobject (GType gtype, + const gchar *data, + gsize length, + GError **error) +{ + return json_gobject_from_data (gtype, data, strlen (data), error); +} + +/** + * json_gobject_from_data: + * @gtype: the #GType of object to construct + * @data: a JSON data stream + * @length: length of the data stream, or -1 if it is NUL-terminated + * @error: return location for a #GError, or %NULL + * + * Deserializes a JSON data stream and creates the corresponding + * #GObject class. If @gtype implements the #JsonSerializableIface + * interface, it will be asked to deserialize all the JSON members + * into the respective properties; otherwise, the default implementation + * will be used to translate the compatible JSON native types. + * + * Note: the JSON data stream must be an object declaration. + * + * Return value: (transfer full): a #GObject or %NULL + * + * Since: 0.10 + */ +GObject * +json_gobject_from_data (GType gtype, + const gchar *data, + gssize length, + GError **error) +{ + JsonParser *parser; + JsonNode *root; + GError *parse_error; + GObject *retval; + + g_return_val_if_fail (gtype != G_TYPE_INVALID, NULL); + g_return_val_if_fail (data != NULL, NULL); + + if (length < 0) + length = strlen (data); + + parser = json_parser_new (); + + parse_error = NULL; + json_parser_load_from_data (parser, data, length, &parse_error); + if (parse_error) + { + g_propagate_error (error, parse_error); + g_object_unref (parser); + return NULL; + } + + root = json_parser_get_root (parser); + if (root == NULL || JSON_NODE_TYPE (root) != JSON_NODE_OBJECT) + { + g_set_error (error, JSON_PARSER_ERROR, + JSON_PARSER_ERROR_PARSE, + /* translators: the %s is the name of the data structure */ + _("Expecting a JSON object, but the root node is of type “%s”"), + json_node_type_name (root)); + g_object_unref (parser); + return NULL; + } + + retval = json_gobject_deserialize (gtype, root); + + g_object_unref (parser); + + return retval; +} + +/** + * json_serialize_gobject: + * @gobject: a #GObject + * @length: (out): return value for the length of the buffer, or %NULL + * + * Serializes a #GObject into a JSON data stream. If @gobject implements + * the #JsonSerializableIface interface, it will be asked to serizalize all + * its properties; otherwise, the default implementation will be use to + * translate the compatible types into JSON native types. + * + * Return value: a JSON data stream representing the passed #GObject + * + * Deprecated: 0.10: Use json_gobject_to_data() instead + */ +gchar * +json_serialize_gobject (GObject *gobject, + gsize *length) +{ + return json_gobject_to_data (gobject, length); +} + +/** + * json_gobject_to_data: + * @gobject: a #GObject + * @length: (out): return value for the length of the buffer, or %NULL + * + * Serializes a #GObject into a JSON data stream, iterating recursively + * over each property. + * + * If @gobject implements the #JsonSerializableIface interface, it will + * be asked to serialize all its properties; otherwise, the default + * implementation will be use to translate the compatible types into + * JSON native types. + * + * Return value: a JSON data stream representing the passed #GObject + * + * Since: 0.10 + */ +gchar * +json_gobject_to_data (GObject *gobject, + gsize *length) +{ + JsonGenerator *gen; + JsonNode *root; + gchar *data; + + g_return_val_if_fail (G_OBJECT (gobject), NULL); + + root = json_gobject_serialize (gobject); + + gen = g_object_new (JSON_TYPE_GENERATOR, + "root", root, + "pretty", TRUE, + "indent", 2, + NULL); + + data = json_generator_to_data (gen, length); + g_object_unref (gen); + + json_node_unref (root); + + return data; +} diff --git a/json-glib/json-gobject.h b/json-glib/json-gobject.h new file mode 100644 index 0000000..47ac125 --- /dev/null +++ b/json-glib/json-gobject.h @@ -0,0 +1,203 @@ +/* json-gobject.h - JSON GObject integration + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_GOBJECT_H__ +#define __JSON_GOBJECT_H__ + +#include + +G_BEGIN_DECLS + +#define JSON_TYPE_SERIALIZABLE (json_serializable_get_type ()) +#define JSON_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_SERIALIZABLE, JsonSerializable)) +#define JSON_IS_SERIALIZABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_SERIALIZABLE)) +#define JSON_SERIALIZABLE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), JSON_TYPE_SERIALIZABLE, JsonSerializableIface)) + +typedef struct _JsonSerializable JsonSerializable; /* dummy */ +typedef struct _JsonSerializableIface JsonSerializableIface; + +/** + * JsonSerializableIface: + * @serialize_property: virtual function for serializing a #GObject property + * into a #JsonNode + * @deserialize_property: virtual function for deserializing a #JsonNode + * into a #GObject property + * @find_property: virtual function for finding a property definition using + * its name + * @list_properties: virtual function for listing the installed property + * definitions + * @set_property: virtual function for setting a property + * @get_property: virtual function for getting a property + * + * Interface that allows serializing and deserializing #GObject instances + * with properties storing complex data types. The json_serialize_gobject() + * function will check if the passed #GObject implements this interface, + * so it can also be used to override the default property serialization + * sequence. + */ +struct _JsonSerializableIface +{ + /*< private >*/ + GTypeInterface g_iface; + + /*< public >*/ + JsonNode *(* serialize_property) (JsonSerializable *serializable, + const gchar *property_name, + const GValue *value, + GParamSpec *pspec); + gboolean (* deserialize_property) (JsonSerializable *serializable, + const gchar *property_name, + GValue *value, + GParamSpec *pspec, + JsonNode *property_node); + + GParamSpec * (* find_property) (JsonSerializable *serializable, + const char *name); + GParamSpec **(* list_properties) (JsonSerializable *serializable, + guint *n_pspecs); + void (* set_property) (JsonSerializable *serializable, + GParamSpec *pspec, + const GValue *value); + void (* get_property) (JsonSerializable *serializable, + GParamSpec *pspec, + GValue *value); +}; + +JSON_AVAILABLE_IN_1_0 +GType json_serializable_get_type (void) G_GNUC_CONST; + +JSON_AVAILABLE_IN_1_0 +JsonNode *json_serializable_serialize_property (JsonSerializable *serializable, + const gchar *property_name, + const GValue *value, + GParamSpec *pspec); +JSON_AVAILABLE_IN_1_0 +gboolean json_serializable_deserialize_property (JsonSerializable *serializable, + const gchar *property_name, + GValue *value, + GParamSpec *pspec, + JsonNode *property_node); + +JSON_AVAILABLE_IN_1_0 +GParamSpec * json_serializable_find_property (JsonSerializable *serializable, + const char *name); +JSON_AVAILABLE_IN_1_0 +GParamSpec ** json_serializable_list_properties (JsonSerializable *serializable, + guint *n_pspecs); +JSON_AVAILABLE_IN_1_0 +void json_serializable_set_property (JsonSerializable *serializable, + GParamSpec *pspec, + const GValue *value); +JSON_AVAILABLE_IN_1_0 +void json_serializable_get_property (JsonSerializable *serializable, + GParamSpec *pspec, + GValue *value); + +JSON_AVAILABLE_IN_1_0 +JsonNode *json_serializable_default_serialize_property (JsonSerializable *serializable, + const gchar *property_name, + const GValue *value, + GParamSpec *pspec); +JSON_AVAILABLE_IN_1_0 +gboolean json_serializable_default_deserialize_property (JsonSerializable *serializable, + const gchar *property_name, + GValue *value, + GParamSpec *pspec, + JsonNode *property_node); + +/** + * JsonBoxedSerializeFunc: + * @boxed: a #GBoxed + * + * Serializes the passed #GBoxed and stores it inside a #JsonNode + * + * Return value: the newly created #JsonNode + * + * Since: 0.10 + */ +typedef JsonNode *(* JsonBoxedSerializeFunc) (gconstpointer boxed); + +/** + * JsonBoxedDeserializeFunc: + * @node: a #JsonNode + * + * Deserializes the contents of the passed #JsonNode into a #GBoxed + * + * Return value: the newly created boxed type + * + * Since: 0.10 + */ +typedef gpointer (* JsonBoxedDeserializeFunc) (JsonNode *node); + +JSON_AVAILABLE_IN_1_0 +void json_boxed_register_serialize_func (GType gboxed_type, + JsonNodeType node_type, + JsonBoxedSerializeFunc serialize_func); +JSON_AVAILABLE_IN_1_0 +void json_boxed_register_deserialize_func (GType gboxed_type, + JsonNodeType node_type, + JsonBoxedDeserializeFunc deserialize_func); +JSON_AVAILABLE_IN_1_0 +gboolean json_boxed_can_serialize (GType gboxed_type, + JsonNodeType *node_type); +JSON_AVAILABLE_IN_1_0 +gboolean json_boxed_can_deserialize (GType gboxed_type, + JsonNodeType node_type); +JSON_AVAILABLE_IN_1_0 +JsonNode *json_boxed_serialize (GType gboxed_type, + gconstpointer boxed); +JSON_AVAILABLE_IN_1_0 +gpointer json_boxed_deserialize (GType gboxed_type, + JsonNode *node); + +JSON_AVAILABLE_IN_1_0 +JsonNode *json_gobject_serialize (GObject *gobject); +JSON_AVAILABLE_IN_1_0 +GObject * json_gobject_deserialize (GType gtype, + JsonNode *node); + +JSON_AVAILABLE_IN_1_0 +GObject * json_gobject_from_data (GType gtype, + const gchar *data, + gssize length, + GError **error); +JSON_AVAILABLE_IN_1_0 +gchar * json_gobject_to_data (GObject *gobject, + gsize *length); + +JSON_DEPRECATED_IN_1_0_FOR(json_gobject_from_data) +GObject * json_construct_gobject (GType gtype, + const gchar *data, + gsize length, + GError **error); +JSON_DEPRECATED_IN_1_0_FOR(json_gobject_to_data) +gchar * json_serialize_gobject (GObject *gobject, + gsize *length) G_GNUC_MALLOC; + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonSerializable, g_object_unref) +#endif + +G_END_DECLS + +#endif /* __JSON_GOBJECT_H__ */ diff --git a/json-glib/json-gvariant.c b/json-glib/json-gvariant.c new file mode 100644 index 0000000..8185cac --- /dev/null +++ b/json-glib/json-gvariant.c @@ -0,0 +1,1349 @@ +/* json-gvariant.c - JSON GVariant integration + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * + * 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 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. + * + * Author: + * Eduardo Lima Mitev + */ + +#include "config.h" + +#include +#include +#include + +#include + +#include + +#include "json-gvariant.h" + +#include "json-generator.h" +#include "json-parser.h" +#include "json-types-private.h" + +/** + * SECTION:json-gvariant + * @short_description: Serialize and deserialize GVariant types + * @Title: JSON GVariant Integration + * + * Use json_gvariant_serialize() and json_gvariant_serialize_data() to + * convert from any #GVariant value to a #JsonNode tree or its string + * representation. + * + * Use json_gvariant_deserialize() and json_gvariant_deserialize_data() to + * obtain the #GVariant value from a #JsonNode tree or directly from a JSON + * string. + * + * Since many #GVariant data types cannot be directly represented as + * JSON, a #GVariant type string (signature) should be provided to these + * methods in order to obtain a correct, type-contrained result. + * If no signature is provided, conversion can still be done, but the + * resulting #GVariant value will be "guessed" from the JSON data types + * using the following rules: + * + * ## Strings + * JSON strings map to GVariant `(s)`. + * + * ## Integers + * JSON integers map to GVariant int64 `(x)`. + * + * ## Booleans + * JSON booleans map to GVariant boolean `(b)`. + * + * ## Numbers + * JSON numbers map to GVariant double `(d)`. + * + * ## Arrays + * JSON arrays map to GVariant arrays of variants `(av)`. + * + * ## Objects + * JSON objects map to GVariant dictionaries of string to variants `(a{sv})`. + * + * ## Null values + * JSON null values map to GVariant maybe variants `(mv)`. + */ + +/* custom extension to the GVariantClass enumeration to differentiate + * a single dictionary entry from an array of dictionary entries + */ +#define JSON_G_VARIANT_CLASS_DICTIONARY 'c' + +typedef void (* GVariantForeachFunc) (GVariant *variant_child, + gpointer user_data); + +static GVariant * json_to_gvariant_recurse (JsonNode *json_node, + const gchar **signature, + GError **error); + +/* ========================================================================== */ +/* GVariant to JSON */ +/* ========================================================================== */ + +static void +gvariant_foreach (GVariant *variant, + GVariantForeachFunc func, + gpointer user_data) +{ + GVariantIter iter; + GVariant *variant_child; + + g_variant_iter_init (&iter, variant); + while ((variant_child = g_variant_iter_next_value (&iter)) != NULL) + { + func (variant_child, user_data); + g_variant_unref (variant_child); + } +} + +static void +gvariant_to_json_array_foreach (GVariant *variant_child, + gpointer user_data) +{ + JsonArray *array = user_data; + JsonNode *json_child; + + json_child = json_gvariant_serialize (variant_child); + json_array_add_element (array, json_child); +} + +static JsonNode * +gvariant_to_json_array (GVariant *variant) +{ + JsonArray *array; + JsonNode *json_node; + + array = json_array_new (); + json_node = json_node_new (JSON_NODE_ARRAY); + json_node_set_array (json_node, array); + json_array_unref (array); + + gvariant_foreach (variant, + gvariant_to_json_array_foreach, + array); + + return json_node; +} + +static gchar * +gvariant_simple_to_string (GVariant *variant) +{ + GVariantClass class; + gchar *str; + + class = g_variant_classify (variant); + switch (class) + { + case G_VARIANT_CLASS_BOOLEAN: + if (g_variant_get_boolean (variant)) + str = g_strdup ("true"); + else + str = g_strdup ("false"); + break; + + case G_VARIANT_CLASS_BYTE: + str = g_strdup_printf ("%u", g_variant_get_byte (variant)); + break; + case G_VARIANT_CLASS_INT16: + str = g_strdup_printf ("%d", g_variant_get_int16 (variant)); + break; + case G_VARIANT_CLASS_UINT16: + str = g_strdup_printf ("%u", g_variant_get_uint16 (variant)); + break; + case G_VARIANT_CLASS_INT32: + str = g_strdup_printf ("%d", g_variant_get_int32 (variant)); + break; + case G_VARIANT_CLASS_UINT32: + str = g_strdup_printf ("%u", g_variant_get_uint32 (variant)); + break; + case G_VARIANT_CLASS_INT64: + str = g_strdup_printf ("%" G_GINT64_FORMAT, + g_variant_get_int64 (variant)); + break; + case G_VARIANT_CLASS_UINT64: + str = g_strdup_printf ("%" G_GUINT64_FORMAT, + g_variant_get_uint64 (variant)); + break; + case G_VARIANT_CLASS_HANDLE: + str = g_strdup_printf ("%d", g_variant_get_handle (variant)); + break; + + case G_VARIANT_CLASS_DOUBLE: + { + gchar buf[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_formatd (buf, + G_ASCII_DTOSTR_BUF_SIZE, + "%f", + g_variant_get_double (variant)); + + str = g_strdup (buf); + break; + } + + case G_VARIANT_CLASS_STRING: + case G_VARIANT_CLASS_OBJECT_PATH: + case G_VARIANT_CLASS_SIGNATURE: + str = g_strdup (g_variant_get_string (variant, NULL)); + break; + + default: + g_assert_not_reached (); + break; + } + + return str; +} + +static JsonNode * +gvariant_dict_entry_to_json (GVariant *variant, gchar **member_name) +{ + GVariant *member; + GVariant *value; + JsonNode *json_node; + + member = g_variant_get_child_value (variant, 0); + *member_name = gvariant_simple_to_string (member); + + value = g_variant_get_child_value (variant, 1); + json_node = json_gvariant_serialize (value); + + g_variant_unref (member); + g_variant_unref (value); + + return json_node; +} + +static void +gvariant_to_json_object_foreach (GVariant *variant_child, gpointer user_data) +{ + gchar *member_name; + JsonNode *json_child; + JsonObject *object = (JsonObject *) user_data; + + json_child = gvariant_dict_entry_to_json (variant_child, &member_name); + json_object_set_member (object, member_name, json_child); + g_free (member_name); +} + +static JsonNode * +gvariant_to_json_object (GVariant *variant) +{ + JsonNode *json_node; + JsonObject *object; + + json_node = json_node_new (JSON_NODE_OBJECT); + object = json_object_new (); + json_node_set_object (json_node, object); + json_object_unref (object); + + gvariant_foreach (variant, + gvariant_to_json_object_foreach, + object); + + return json_node; +} + +/** + * json_gvariant_serialize: + * @variant: A #GVariant to convert + * + * Converts @variant to a JSON tree. + * + * Return value: (transfer full): A #JsonNode representing the root of the + * JSON data structure obtained from @variant + * + * Since: 0.14 + */ +JsonNode * +json_gvariant_serialize (GVariant *variant) +{ + JsonNode *json_node = NULL; + GVariantClass class; + + g_return_val_if_fail (variant != NULL, NULL); + + class = g_variant_classify (variant); + + if (! g_variant_is_container (variant)) + { + json_node = json_node_new (JSON_NODE_VALUE); + + switch (class) + { + case G_VARIANT_CLASS_BOOLEAN: + json_node_set_boolean (json_node, g_variant_get_boolean (variant)); + break; + + case G_VARIANT_CLASS_BYTE: + json_node_set_int (json_node, g_variant_get_byte (variant)); + break; + case G_VARIANT_CLASS_INT16: + json_node_set_int (json_node, g_variant_get_int16 (variant)); + break; + case G_VARIANT_CLASS_UINT16: + json_node_set_int (json_node, g_variant_get_uint16 (variant)); + break; + case G_VARIANT_CLASS_INT32: + json_node_set_int (json_node, g_variant_get_int32 (variant)); + break; + case G_VARIANT_CLASS_UINT32: + json_node_set_int (json_node, g_variant_get_uint32 (variant)); + break; + case G_VARIANT_CLASS_INT64: + json_node_set_int (json_node, g_variant_get_int64 (variant)); + break; + case G_VARIANT_CLASS_UINT64: + json_node_set_int (json_node, g_variant_get_uint64 (variant)); + break; + case G_VARIANT_CLASS_HANDLE: + json_node_set_int (json_node, g_variant_get_handle (variant)); + break; + + case G_VARIANT_CLASS_DOUBLE: + json_node_set_double (json_node, g_variant_get_double (variant)); + break; + + case G_VARIANT_CLASS_STRING: + case G_VARIANT_CLASS_OBJECT_PATH: + case G_VARIANT_CLASS_SIGNATURE: + json_node_set_string (json_node, g_variant_get_string (variant, NULL)); + break; + + default: + break; + } + } + else + { + switch (class) + { + case G_VARIANT_CLASS_MAYBE: + { + GVariant *value; + + value = g_variant_get_maybe (variant); + if (value == NULL) + { + json_node = json_node_new (JSON_NODE_NULL); + } + else + { + json_node = json_gvariant_serialize (value); + g_variant_unref (value); + } + + break; + } + + case G_VARIANT_CLASS_VARIANT: + { + GVariant *value; + + value = g_variant_get_variant (variant); + json_node = json_gvariant_serialize (value); + g_variant_unref (value); + + break; + } + + case G_VARIANT_CLASS_ARRAY: + { + const gchar *type; + + type = g_variant_get_type_string (variant); + + if (type[1] == G_VARIANT_CLASS_DICT_ENTRY) + { + /* array of dictionary entries => JsonObject */ + json_node = gvariant_to_json_object (variant); + } + else + { + /* array of anything else => JsonArray */ + json_node = gvariant_to_json_array (variant); + } + + break; + } + + case G_VARIANT_CLASS_DICT_ENTRY: + { + gchar *member_name; + JsonObject *object; + JsonNode *child; + + /* a single dictionary entry => JsonObject */ + json_node = json_node_new (JSON_NODE_OBJECT); + object = json_object_new (); + json_node_set_object (json_node, object); + json_object_unref (object); + + child = gvariant_dict_entry_to_json (variant, &member_name); + + json_object_set_member (object, member_name, child); + g_free (member_name); + + break; + } + + case G_VARIANT_CLASS_TUPLE: + json_node = gvariant_to_json_array (variant); + break; + + default: + break; + } + } + + return json_node; +} + +/** + * json_gvariant_serialize_data: + * @variant: A #GVariant to convert + * @length: (out) (allow-none): Return location for the length of the returned + * string, or %NULL + * + * Converts @variant to its JSON encoded string representation. This method + * is actually a helper function. It uses json_gvariant_serialize() to obtain the + * JSON tree, and then #JsonGenerator to stringify it. + * + * Return value: (transfer full): The JSON encoded string corresponding to + * @variant + * + * Since: 0.14 + */ +gchar * +json_gvariant_serialize_data (GVariant *variant, gsize *length) +{ + JsonNode *json_node; + JsonGenerator *generator; + gchar *json; + + json_node = json_gvariant_serialize (variant); + + generator = json_generator_new (); + + json_generator_set_root (generator, json_node); + json = json_generator_to_data (generator, length); + + g_object_unref (generator); + + json_node_unref (json_node); + + return json; +} + +/* ========================================================================== */ +/* JSON to GVariant */ +/* ========================================================================== */ + +static GVariantClass +json_to_gvariant_get_next_class (JsonNode *json_node, + const gchar **signature) +{ + if (signature == NULL) + { + GVariantClass class = 0; + + switch (json_node_get_node_type (json_node)) + { + case JSON_NODE_VALUE: + switch (json_node_get_value_type (json_node)) + { + case G_TYPE_BOOLEAN: + class = G_VARIANT_CLASS_BOOLEAN; + break; + + case G_TYPE_INT64: + class = G_VARIANT_CLASS_INT64; + break; + + case G_TYPE_DOUBLE: + class = G_VARIANT_CLASS_DOUBLE; + break; + + case G_TYPE_STRING: + class = G_VARIANT_CLASS_STRING; + break; + } + + break; + + case JSON_NODE_ARRAY: + class = G_VARIANT_CLASS_ARRAY; + break; + + case JSON_NODE_OBJECT: + class = JSON_G_VARIANT_CLASS_DICTIONARY; + break; + + case JSON_NODE_NULL: + class = G_VARIANT_CLASS_MAYBE; + break; + } + + return class; + } + else + { + if ((*signature)[0] == G_VARIANT_CLASS_ARRAY && + (*signature)[1] == G_VARIANT_CLASS_DICT_ENTRY) + return JSON_G_VARIANT_CLASS_DICTIONARY; + else + return (*signature)[0]; + } +} + +static gboolean +json_node_assert_type (JsonNode *json_node, + JsonNodeType type, + GType sub_type, + GError **error) +{ + if (JSON_NODE_TYPE (json_node) != type || + (type == JSON_NODE_VALUE && + (json_node_get_value_type (json_node) != sub_type))) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + /* translators: the '%s' is the type name */ + _("Unexpected type “%s” in JSON node"), + g_type_name (json_node_get_value_type (json_node))); + return FALSE; + } + else + { + return TRUE; + } +} + +static void +json_to_gvariant_foreach_add (gpointer data, gpointer user_data) +{ + GVariantBuilder *builder = (GVariantBuilder *) user_data; + GVariant *child = (GVariant *) data; + + g_variant_builder_add_value (builder, child); +} + +static void +json_to_gvariant_foreach_free (gpointer data, gpointer user_data) +{ + GVariant *child = (GVariant *) data; + + g_variant_unref (child); +} + +static GVariant * +json_to_gvariant_build_from_glist (GList *list, const gchar *signature) +{ + GVariantBuilder *builder; + GVariant *result; + + builder = g_variant_builder_new (G_VARIANT_TYPE (signature)); + + g_list_foreach (list, json_to_gvariant_foreach_add, builder); + result = g_variant_builder_end (builder); + + g_variant_builder_unref (builder); + + return result; +} + +static GVariant * +json_to_gvariant_tuple (JsonNode *json_node, + const gchar **signature, + GError **error) +{ + GVariant *variant = NULL; + JsonArray *array; + gint i; + GList *children = NULL; + gboolean roll_back = FALSE; + const gchar *initial_signature; + + array = json_node_get_array (json_node); + + initial_signature = *signature; + (*signature)++; + i = 1; + while ((*signature)[0] != ')' && (*signature)[0] != '\0') + { + JsonNode *json_child; + GVariant *variant_child; + + if (i - 1 >= json_array_get_length (array)) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("Missing elements in JSON array to conform to a tuple")); + roll_back = TRUE; + break; + } + + json_child = json_array_get_element (array, i - 1); + + variant_child = json_to_gvariant_recurse (json_child, signature, error); + if (variant_child != NULL) + { + children = g_list_append (children, variant_child); + } + else + { + roll_back = TRUE; + break; + } + + i++; + } + + if (! roll_back) + { + if ( (*signature)[0] != ')') + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("Missing closing symbol “)” in the GVariant tuple type")); + roll_back = TRUE; + } + else if (json_array_get_length (array) >= i) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("Unexpected extra elements in JSON array")); + roll_back = TRUE; + } + else + { + gchar *tuple_type; + + tuple_type = g_strndup (initial_signature, + (*signature) - initial_signature + 1); + + variant = json_to_gvariant_build_from_glist (children, tuple_type); + + g_free (tuple_type); + } + } + + if (roll_back) + g_list_foreach (children, json_to_gvariant_foreach_free, NULL); + + g_list_free (children); + + return variant; +} + +static gchar * +signature_get_next_complete_type (const gchar **signature) +{ + GVariantClass class; + const gchar *initial_signature; + gchar *result; + + /* here it is assumed that 'signature' is a valid type string */ + + initial_signature = *signature; + class = (*signature)[0]; + + if (class == G_VARIANT_CLASS_TUPLE || class == G_VARIANT_CLASS_DICT_ENTRY) + { + gchar stack[256] = {0}; + guint stack_len = 0; + + do + { + if ( (*signature)[0] == G_VARIANT_CLASS_TUPLE) + { + stack[stack_len] = ')'; + stack_len++; + } + else if ( (*signature)[0] == G_VARIANT_CLASS_DICT_ENTRY) + { + stack[stack_len] = '}'; + stack_len++; + } + + (*signature)++; + + if ( (*signature)[0] == stack[stack_len - 1]) + stack_len--; + } + while (stack_len > 0); + + (*signature)++; + } + else if (class == G_VARIANT_CLASS_ARRAY || class == G_VARIANT_CLASS_MAYBE) + { + gchar *tmp_sig; + + (*signature)++; + tmp_sig = signature_get_next_complete_type (signature); + g_free (tmp_sig); + } + else + { + (*signature)++; + } + + result = g_strndup (initial_signature, (*signature) - initial_signature); + + return result; +} + +static GVariant * +json_to_gvariant_maybe (JsonNode *json_node, + const gchar **signature, + GError **error) +{ + GVariant *variant = NULL; + GVariant *value; + gchar *maybe_signature; + + if (signature) + { + (*signature)++; + maybe_signature = signature_get_next_complete_type (signature); + } + else + { + maybe_signature = g_strdup ("v"); + } + + if (json_node_get_node_type (json_node) == JSON_NODE_NULL) + { + variant = g_variant_new_maybe (G_VARIANT_TYPE (maybe_signature), NULL); + } + else + { + const gchar *tmp_signature; + + tmp_signature = maybe_signature; + value = json_to_gvariant_recurse (json_node, + &tmp_signature, + error); + + if (value != NULL) + variant = g_variant_new_maybe (G_VARIANT_TYPE (maybe_signature), value); + } + + g_free (maybe_signature); + + /* compensate the (*signature)++ call at the end of 'recurse()' */ + if (signature) + (*signature)--; + + return variant; +} + +static GVariant * +json_to_gvariant_array (JsonNode *json_node, + const gchar **signature, + GError **error) +{ + GVariant *variant = NULL; + JsonArray *array; + GList *children = NULL; + gboolean roll_back = FALSE; + const gchar *orig_signature = NULL; + gchar *child_signature; + + array = json_node_get_array (json_node); + + if (signature != NULL) + { + orig_signature = *signature; + + (*signature)++; + child_signature = signature_get_next_complete_type (signature); + } + else + child_signature = g_strdup ("v"); + + if (json_array_get_length (array) > 0) + { + gint i; + guint len; + + len = json_array_get_length (array); + for (i = 0; i < len; i++) + { + JsonNode *json_child; + GVariant *variant_child; + const gchar *tmp_signature; + + json_child = json_array_get_element (array, i); + + tmp_signature = child_signature; + variant_child = json_to_gvariant_recurse (json_child, + &tmp_signature, + error); + if (variant_child != NULL) + { + children = g_list_append (children, variant_child); + } + else + { + roll_back = TRUE; + break; + } + } + } + + if (!roll_back) + { + gchar *array_signature; + + if (signature) + array_signature = g_strndup (orig_signature, (*signature) - orig_signature); + else + array_signature = g_strdup ("av"); + + variant = json_to_gvariant_build_from_glist (children, array_signature); + + g_free (array_signature); + + /* compensate the (*signature)++ call at the end of 'recurse()' */ + if (signature) + (*signature)--; + } + else + g_list_foreach (children, json_to_gvariant_foreach_free, NULL); + + g_list_free (children); + g_free (child_signature); + + return variant; +} + +static GVariant * +gvariant_simple_from_string (const gchar *st, + GVariantClass class, + GError **error) +{ + GVariant *variant = NULL; + gchar *nptr = NULL; + + errno = 0; + + switch (class) + { + case G_VARIANT_CLASS_BOOLEAN: + if (g_strcmp0 (st, "true") == 0) + variant = g_variant_new_boolean (TRUE); + else if (g_strcmp0 (st, "false") == 0) + variant = g_variant_new_boolean (FALSE); + else + errno = 1; + break; + + case G_VARIANT_CLASS_BYTE: + variant = g_variant_new_byte (g_ascii_strtoll (st, &nptr, 10)); + break; + + case G_VARIANT_CLASS_INT16: + variant = g_variant_new_int16 (g_ascii_strtoll (st, &nptr, 10)); + break; + + case G_VARIANT_CLASS_UINT16: + variant = g_variant_new_uint16 (g_ascii_strtoll (st, &nptr, 10)); + break; + + case G_VARIANT_CLASS_INT32: + variant = g_variant_new_int32 (g_ascii_strtoll (st, &nptr, 10)); + break; + + case G_VARIANT_CLASS_UINT32: + variant = g_variant_new_uint32 (g_ascii_strtoull (st, &nptr, 10)); + break; + + case G_VARIANT_CLASS_INT64: + variant = g_variant_new_int64 (g_ascii_strtoll (st, &nptr, 10)); + break; + + case G_VARIANT_CLASS_UINT64: + variant = g_variant_new_uint64 (g_ascii_strtoull (st, &nptr, 10)); + break; + + case G_VARIANT_CLASS_HANDLE: + variant = g_variant_new_handle (strtol (st, &nptr, 10)); + break; + + case G_VARIANT_CLASS_DOUBLE: + variant = g_variant_new_double (g_ascii_strtod (st, &nptr)); + break; + + case G_VARIANT_CLASS_STRING: + case G_VARIANT_CLASS_OBJECT_PATH: + case G_VARIANT_CLASS_SIGNATURE: + variant = g_variant_new_string (st); + break; + + default: + g_assert_not_reached (); + break; + } + + if (errno != 0 || nptr == st) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("Invalid string value converting to GVariant")); + if (variant != NULL) + { + g_variant_unref (variant); + variant = NULL; + } + } + + return variant; +} + +static void +parse_dict_entry_signature (const gchar **signature, + gchar **entry_signature, + gchar **key_signature, + gchar **value_signature) +{ + const gchar *tmp_sig; + + if (signature != NULL) + *entry_signature = signature_get_next_complete_type (signature); + else + *entry_signature = g_strdup ("{sv}"); + + tmp_sig = (*entry_signature) + 1; + *key_signature = signature_get_next_complete_type (&tmp_sig); + *value_signature = signature_get_next_complete_type (&tmp_sig); +} + +static GVariant * +json_to_gvariant_dict_entry (JsonNode *json_node, + const gchar **signature, + GError **error) +{ + GVariant *variant = NULL; + JsonObject *obj; + + gchar *entry_signature; + gchar *key_signature; + gchar *value_signature; + const gchar *tmp_signature; + + GQueue *members; + const gchar *json_member; + JsonNode *json_value; + GVariant *variant_member; + GVariant *variant_value; + + obj = json_node_get_object (json_node); + + if (json_object_get_size (obj) != 1) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("A GVariant dictionary entry expects a JSON object with exactly one member")); + return NULL; + } + + parse_dict_entry_signature (signature, + &entry_signature, + &key_signature, + &value_signature); + + members = json_object_get_members_internal (obj); + json_member = (const gchar *) members->head->data; + variant_member = gvariant_simple_from_string (json_member, + key_signature[0], + error); + if (variant_member != NULL) + { + json_value = json_object_get_member (obj, json_member); + + tmp_signature = value_signature; + variant_value = json_to_gvariant_recurse (json_value, + &tmp_signature, + error); + + if (variant_value != NULL) + { + GVariantBuilder *builder; + + builder = g_variant_builder_new (G_VARIANT_TYPE (entry_signature)); + g_variant_builder_add_value (builder, variant_member); + g_variant_builder_add_value (builder, variant_value); + variant = g_variant_builder_end (builder); + + g_variant_builder_unref (builder); + } + } + + g_free (value_signature); + g_free (key_signature); + g_free (entry_signature); + + /* compensate the (*signature)++ call at the end of 'recurse()' */ + if (signature) + (*signature)--; + + return variant; +} + +static GVariant * +json_to_gvariant_dictionary (JsonNode *json_node, + const gchar **signature, + GError **error) +{ + GVariant *variant = NULL; + JsonObject *obj; + gboolean roll_back = FALSE; + + gchar *dict_signature; + gchar *entry_signature; + gchar *key_signature; + gchar *value_signature; + const gchar *tmp_signature; + + GVariantBuilder *builder; + GQueue *members; + GList *member; + + obj = json_node_get_object (json_node); + + if (signature != NULL) + (*signature)++; + + parse_dict_entry_signature (signature, + &entry_signature, + &key_signature, + &value_signature); + + dict_signature = g_strdup_printf ("a%s", entry_signature); + + builder = g_variant_builder_new (G_VARIANT_TYPE (dict_signature)); + + members = json_object_get_members_internal (obj); + + for (member = members->head; member != NULL; member = member->next) + { + const gchar *json_member; + JsonNode *json_value; + GVariant *variant_member; + GVariant *variant_value; + + json_member = (const gchar *) member->data; + variant_member = gvariant_simple_from_string (json_member, + key_signature[0], + error); + if (variant_member == NULL) + { + roll_back = TRUE; + break; + } + + json_value = json_object_get_member (obj, json_member); + + tmp_signature = value_signature; + variant_value = json_to_gvariant_recurse (json_value, + &tmp_signature, + error); + + if (variant_value != NULL) + { + g_variant_builder_open (builder, G_VARIANT_TYPE (entry_signature)); + g_variant_builder_add_value (builder, variant_member); + g_variant_builder_add_value (builder, variant_value); + g_variant_builder_close (builder); + } + else + { + roll_back = TRUE; + break; + } + } + + if (! roll_back) + variant = g_variant_builder_end (builder); + + g_variant_builder_unref (builder); + g_free (value_signature); + g_free (key_signature); + g_free (entry_signature); + g_free (dict_signature); + + /* compensate the (*signature)++ call at the end of 'recurse()' */ + if (signature != NULL) + (*signature)--; + + return variant; +} + +static GVariant * +json_to_gvariant_recurse (JsonNode *json_node, + const gchar **signature, + GError **error) +{ + GVariant *variant = NULL; + GVariantClass class; + + class = json_to_gvariant_get_next_class (json_node, signature); + + if (class == JSON_G_VARIANT_CLASS_DICTIONARY) + { + if (json_node_assert_type (json_node, JSON_NODE_OBJECT, 0, error)) + variant = json_to_gvariant_dictionary (json_node, signature, error); + + goto out; + } + + if (JSON_NODE_TYPE (json_node) == JSON_NODE_VALUE && + json_node_get_value_type (json_node) == G_TYPE_STRING) + { + const gchar* str = json_node_get_string (json_node); + switch (class) + { + case G_VARIANT_CLASS_BOOLEAN: + case G_VARIANT_CLASS_BYTE: + case G_VARIANT_CLASS_INT16: + case G_VARIANT_CLASS_UINT16: + case G_VARIANT_CLASS_INT32: + case G_VARIANT_CLASS_UINT32: + case G_VARIANT_CLASS_INT64: + case G_VARIANT_CLASS_UINT64: + case G_VARIANT_CLASS_HANDLE: + case G_VARIANT_CLASS_DOUBLE: + case G_VARIANT_CLASS_STRING: + variant = gvariant_simple_from_string (str, class, error); + goto out; + default: + break; + } + } + + switch (class) + { + case G_VARIANT_CLASS_BOOLEAN: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_BOOLEAN, error)) + variant = g_variant_new_boolean (json_node_get_boolean (json_node)); + break; + + case G_VARIANT_CLASS_BYTE: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error)) + variant = g_variant_new_byte (json_node_get_int (json_node)); + break; + + case G_VARIANT_CLASS_INT16: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error)) + variant = g_variant_new_int16 (json_node_get_int (json_node)); + break; + + case G_VARIANT_CLASS_UINT16: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error)) + variant = g_variant_new_uint16 (json_node_get_int (json_node)); + break; + + case G_VARIANT_CLASS_INT32: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error)) + variant = g_variant_new_int32 (json_node_get_int (json_node)); + break; + + case G_VARIANT_CLASS_UINT32: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error)) + variant = g_variant_new_uint32 (json_node_get_int (json_node)); + break; + + case G_VARIANT_CLASS_INT64: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error)) + variant = g_variant_new_int64 (json_node_get_int (json_node)); + break; + + case G_VARIANT_CLASS_UINT64: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error)) + variant = g_variant_new_uint64 (json_node_get_int (json_node)); + break; + + case G_VARIANT_CLASS_HANDLE: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error)) + variant = g_variant_new_handle (json_node_get_int (json_node)); + break; + + case G_VARIANT_CLASS_DOUBLE: + /* Doubles can look like ints to the json parser: when they don't have a dot */ + if (JSON_NODE_TYPE (json_node) == JSON_NODE_VALUE && + json_node_get_value_type (json_node) == G_TYPE_INT64) + variant = g_variant_new_double (json_node_get_int (json_node)); + else if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_DOUBLE, error)) + variant = g_variant_new_double (json_node_get_double (json_node)); + break; + + case G_VARIANT_CLASS_STRING: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_STRING, error)) + variant = g_variant_new_string (json_node_get_string (json_node)); + break; + + case G_VARIANT_CLASS_OBJECT_PATH: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_STRING, error)) + variant = g_variant_new_object_path (json_node_get_string (json_node)); + break; + + case G_VARIANT_CLASS_SIGNATURE: + if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_STRING, error)) + variant = g_variant_new_signature (json_node_get_string (json_node)); + break; + + case G_VARIANT_CLASS_VARIANT: + variant = g_variant_new_variant (json_to_gvariant_recurse (json_node, + NULL, + error)); + break; + + case G_VARIANT_CLASS_MAYBE: + variant = json_to_gvariant_maybe (json_node, signature, error); + break; + + case G_VARIANT_CLASS_ARRAY: + if (json_node_assert_type (json_node, JSON_NODE_ARRAY, 0, error)) + variant = json_to_gvariant_array (json_node, signature, error); + break; + + case G_VARIANT_CLASS_TUPLE: + if (json_node_assert_type (json_node, JSON_NODE_ARRAY, 0, error)) + variant = json_to_gvariant_tuple (json_node, signature, error); + break; + + case G_VARIANT_CLASS_DICT_ENTRY: + if (json_node_assert_type (json_node, JSON_NODE_OBJECT, 0, error)) + variant = json_to_gvariant_dict_entry (json_node, signature, error); + break; + + default: + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("GVariant class “%c” not supported"), class); + break; + } + +out: + if (signature) + (*signature)++; + + return variant; +} + +/** + * json_gvariant_deserialize: + * @json_node: A #JsonNode to convert + * @signature: (allow-none): A valid #GVariant type string, or %NULL + * @error: A pointer to a #GError + * + * Converts a JSON data structure to a GVariant value using @signature to + * resolve ambiguous data types. If no error occurs, the resulting #GVariant + * is guaranteed to conform to @signature. + * + * If @signature is not %NULL but does not represent a valid GVariant type + * string, %NULL is returned and error is set to %G_IO_ERROR_INVALID_ARGUMENT. + * If a @signature is provided but the JSON structure cannot be mapped to it, + * %NULL is returned and error is set to %G_IO_ERROR_INVALID_DATA. + * If @signature is %NULL, the conversion is done based strictly on the types + * in the JSON nodes. + * + * The returned variant has a floating reference that will need to be sunk + * by the caller code. + * + * Return value: (transfer none): A newly created, floating #GVariant + * compliant with @signature, or %NULL on error + * + * Since: 0.14 + */ +GVariant * +json_gvariant_deserialize (JsonNode *json_node, + const gchar *signature, + GError **error) +{ + g_return_val_if_fail (json_node != NULL, NULL); + + if (signature != NULL && ! g_variant_type_string_is_valid (signature)) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Invalid GVariant signature")); + return NULL; + } + + return json_to_gvariant_recurse (json_node, signature ? &signature : NULL, error); +} + +/** + * json_gvariant_deserialize_data: + * @json: A JSON data string + * @length: The length of @json, or -1 if %NULL-terminated + * @signature: (allow-none): A valid #GVariant type string, or %NULL + * @error: A pointer to a #GError + * + * Converts a JSON string to a #GVariant value. This method works exactly + * like json_gvariant_deserialize(), but takes a JSON encoded string instead. + * The string is first converted to a #JsonNode using #JsonParser, and then + * json_gvariant_deserialize() is called. + * + * The returned variant has a floating reference that will need to be sunk + * by the caller code. + * + * Returns: (transfer none): A newly created, floating #GVariant compliant + * with @signature, or %NULL on error + * + * Since: 0.14 + */ +GVariant * +json_gvariant_deserialize_data (const gchar *json, + gssize length, + const gchar *signature, + GError **error) +{ + JsonParser *parser; + GVariant *variant = NULL; + JsonNode *root; + + parser = json_parser_new (); + + if (! json_parser_load_from_data (parser, json, length, error)) + return NULL; + + root = json_parser_get_root (parser); + if (root == NULL) + { + g_set_error_literal (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_DATA, + _("JSON data is empty")); + } + else + { + variant = + json_gvariant_deserialize (json_parser_get_root (parser), signature, error); + } + + g_object_unref (parser); + + return variant; +} diff --git a/json-glib/json-gvariant.h b/json-glib/json-gvariant.h new file mode 100644 index 0000000..38cfc94 --- /dev/null +++ b/json-glib/json-gvariant.h @@ -0,0 +1,53 @@ +/* json-gvariant.h - JSON GVariant integration + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Eduardo Lima Mitev + */ + +#ifndef __JSON_GVARIANT_H__ +#define __JSON_GVARIANT_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +JSON_AVAILABLE_IN_1_0 +JsonNode * json_gvariant_serialize (GVariant *variant); +JSON_AVAILABLE_IN_1_0 +gchar * json_gvariant_serialize_data (GVariant *variant, + gsize *length); + +JSON_AVAILABLE_IN_1_0 +GVariant * json_gvariant_deserialize (JsonNode *json_node, + const gchar *signature, + GError **error); +JSON_AVAILABLE_IN_1_0 +GVariant * json_gvariant_deserialize_data (const gchar *json, + gssize length, + const gchar *signature, + GError **error); + +G_END_DECLS + +#endif /* __JSON_GVARIANT_H__ */ diff --git a/json-glib/json-node.c b/json-glib/json-node.c new file mode 100644 index 0000000..a6898d9 --- /dev/null +++ b/json-glib/json-node.c @@ -0,0 +1,1503 @@ +/* json-node.c - JSON object model node + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * Copyright (C) 2015 Collabora Ltd. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + * Philip Withnall + */ + +#include "config.h" + +#include + +#include "json-types.h" +#include "json-types-private.h" +#include "json-debug.h" + +/** + * SECTION:json-node + * @short_description: Node in a JSON object model + * + * A #JsonNode is a generic container of elements inside a JSON stream. + * It can contain fundamental types (integers, booleans, floating point + * numbers, strings) and complex types (arrays and objects). + * + * When parsing a JSON data stream you extract the root node and walk + * the node tree by retrieving the type of data contained inside the + * node with the %JSON_NODE_TYPE macro. If the node contains a fundamental + * type you can retrieve a copy of the #GValue holding it with the + * json_node_get_value() function, and then use the #GValue API to extract + * the data; if the node contains a complex type you can retrieve the + * #JsonObject or the #JsonArray using json_node_get_object() or + * json_node_get_array() respectively, and then retrieve the nodes + * they contain. + * + * A #JsonNode may be marked as immutable using json_node_seal(). This marks the + * node and all its descendents as read-only, and means that subsequent calls to + * setter functions (such as json_node_set_array()) on them will abort as a + * programmer error. By marking a node tree as immutable, it may be referenced + * in multiple places and its hash value cached for fast lookups, without the + * possibility of a value deep within the tree changing and affecting hash + * values. Immutable #JsonNodes may be passed to functions which retain a + * reference to them without needing to take a copy. + * + * #JsonNode supports two types of memory management: alloc/free semantics, and + * ref/unref semantics. The two may be mixed to a limited extent: nodes may be + * allocated (which gives them a reference count of 1), referenced zero or more + * times, unreferenced exactly that number of times (using json_node_unref()), + * then either unreferenced exactly once more or freed (using json_node_free()) + * to destroy them. json_node_free() must not be used when a node might have a + * reference count not equal to 1. To this end, json-glib uses json_node_copy() + * and json_node_unref() internally. + */ + +G_DEFINE_BOXED_TYPE (JsonNode, json_node, json_node_copy, json_node_unref); + +/** + * json_node_get_value_type: + * @node: a #JsonNode + * + * Returns the #GType of the payload of the node. + * + * Return value: a #GType for the payload. + * + * Since: 0.4 + */ +GType +json_node_get_value_type (JsonNode *node) +{ + g_return_val_if_fail (node != NULL, G_TYPE_INVALID); + + switch (node->type) + { + case JSON_NODE_OBJECT: + return JSON_TYPE_OBJECT; + + case JSON_NODE_ARRAY: + return JSON_TYPE_ARRAY; + + case JSON_NODE_NULL: + return G_TYPE_INVALID; + + case JSON_NODE_VALUE: + if (node->data.value) + return JSON_VALUE_TYPE (node->data.value); + else + return G_TYPE_INVALID; + + default: + g_assert_not_reached (); + return G_TYPE_INVALID; + } +} + +/** + * json_node_alloc: (constructor) + * + * Allocates a new #JsonNode. Use json_node_init() and its variants + * to initialize the returned value. + * + * Return value: (transfer full): the newly allocated #JsonNode. Use + * json_node_free() to free the resources allocated by this function + * + * Since: 0.16 + */ +JsonNode * +json_node_alloc (void) +{ + JsonNode *node = NULL; + + node = g_slice_new0 (JsonNode); + node->ref_count = 1; + node->allocated = TRUE; + + return node; +} + +static void +json_node_unset (JsonNode *node) +{ + /* Note: Don't use JSON_NODE_IS_VALID here because this may legitimately be + * called with (node->ref_count == 0) from json_node_unref(). */ + g_assert (node != NULL); + + switch (node->type) + { + case JSON_NODE_OBJECT: + if (node->data.object) + json_object_unref (node->data.object); + break; + + case JSON_NODE_ARRAY: + if (node->data.array) + json_array_unref (node->data.array); + break; + + case JSON_NODE_VALUE: + if (node->data.value) + json_value_unref (node->data.value); + break; + + case JSON_NODE_NULL: + break; + } +} + +/** + * json_node_init: + * @node: the #JsonNode to initialize + * @type: the type of JSON node to initialize @node to + * + * Initializes a @node to a specific @type. + * + * If the node has already been initialized once, it will be reset to + * the given type, and any data contained will be cleared. + * + * Return value: (transfer none): the initialized #JsonNode + * + * Since: 0.16 + */ +JsonNode * +json_node_init (JsonNode *node, + JsonNodeType type) +{ + g_return_val_if_fail (type >= JSON_NODE_OBJECT && + type <= JSON_NODE_NULL, NULL); + g_return_val_if_fail (node->ref_count == 1, NULL); + + json_node_unset (node); + + node->type = type; + + return node; +} + +/** + * json_node_init_object: + * @node: the #JsonNode to initialize + * @object: (allow-none): the #JsonObject to initialize @node with, or %NULL + * + * Initializes @node to %JSON_NODE_OBJECT and sets @object into it. + * + * This function will take a reference on @object. + * + * If the node has already been initialized once, it will be reset to + * the given type, and any data contained will be cleared. + * + * Return value: (transfer none): the initialized #JsonNode + * + * Since: 0.16 + */ +JsonNode * +json_node_init_object (JsonNode *node, + JsonObject *object) +{ + g_return_val_if_fail (node != NULL, NULL); + + json_node_init (node, JSON_NODE_OBJECT); + json_node_set_object (node, object); + + return node; +} + +/** + * json_node_init_array: + * @node: the #JsonNode to initialize + * @array: (allow-none): the #JsonArray to initialize @node with, or %NULL + * + * Initializes @node to %JSON_NODE_ARRAY and sets @array into it. + * + * This function will take a reference on @array. + * + * If the node has already been initialized once, it will be reset to + * the given type, and any data contained will be cleared. + * + * Return value: (transfer none): the initialized #JsonNode + * + * Since: 0.16 + */ +JsonNode * +json_node_init_array (JsonNode *node, + JsonArray *array) +{ + g_return_val_if_fail (node != NULL, NULL); + + json_node_init (node, JSON_NODE_ARRAY); + json_node_set_array (node, array); + + return node; +} + +/** + * json_node_init_int: + * @node: the #JsonNode to initialize + * @value: an integer + * + * Initializes @node to %JSON_NODE_VALUE and sets @value into it. + * + * If the node has already been initialized once, it will be reset to + * the given type, and any data contained will be cleared. + * + * Return value: (transfer none): the initialized #JsonNode + * + * Since: 0.16 + */ +JsonNode * +json_node_init_int (JsonNode *node, + gint64 value) +{ + g_return_val_if_fail (node != NULL, NULL); + + json_node_init (node, JSON_NODE_VALUE); + json_node_set_int (node, value); + + return node; +} + +/** + * json_node_init_double: + * @node: the #JsonNode to initialize + * @value: a floating point value + * + * Initializes @node to %JSON_NODE_VALUE and sets @value into it. + * + * If the node has already been initialized once, it will be reset to + * the given type, and any data contained will be cleared. + * + * Return value: (transfer none): the initialized #JsonNode + * + * Since: 0.16 + */ +JsonNode * +json_node_init_double (JsonNode *node, + gdouble value) +{ + g_return_val_if_fail (node != NULL, NULL); + + json_node_init (node, JSON_NODE_VALUE); + json_node_set_double (node, value); + + return node; +} + +/** + * json_node_init_boolean: + * @node: the #JsonNode to initialize + * @value: a boolean value + * + * Initializes @node to %JSON_NODE_VALUE and sets @value into it. + * + * If the node has already been initialized once, it will be reset to + * the given type, and any data contained will be cleared. + * + * Return value: (transfer none): the initialized #JsonNode + * + * Since: 0.16 + */ +JsonNode * +json_node_init_boolean (JsonNode *node, + gboolean value) +{ + g_return_val_if_fail (node != NULL, NULL); + + json_node_init (node, JSON_NODE_VALUE); + json_node_set_boolean (node, value); + + return node; +} + +/** + * json_node_init_string: + * @node: the #JsonNode to initialize + * @value: (allow-none): a string value + * + * Initializes @node to %JSON_NODE_VALUE and sets @value into it. + * + * If the node has already been initialized once, it will be reset to + * the given type, and any data contained will be cleared. + * + * Return value: (transfer none): the initialized #JsonNode + * + * Since: 0.16 + */ +JsonNode * +json_node_init_string (JsonNode *node, + const char *value) +{ + g_return_val_if_fail (node != NULL, NULL); + + json_node_init (node, JSON_NODE_VALUE); + json_node_set_string (node, value); + + return node; +} + +/** + * json_node_init_null: + * @node: the #JsonNode to initialize + * + * Initializes @node to %JSON_NODE_NULL. + * + * If the node has already been initialized once, it will be reset to + * the given type, and any data contained will be cleared. + * + * Return value: (transfer none): the initialized #JsonNode + * + * Since: 0.16 + */ +JsonNode * +json_node_init_null (JsonNode *node) +{ + g_return_val_if_fail (node != NULL, NULL); + + return json_node_init (node, JSON_NODE_NULL); +} + +/** + * json_node_new: (constructor) + * @type: a #JsonNodeType + * + * Creates a new #JsonNode of @type. + * + * This is a convenience function for json_node_alloc() and json_node_init(), + * and it's the equivalent of: + * + * |[ + json_node_init (json_node_alloc (), type); + * ]| + * + * Return value: (transfer full): the newly created #JsonNode + */ +JsonNode * +json_node_new (JsonNodeType type) +{ + g_return_val_if_fail (type >= JSON_NODE_OBJECT && + type <= JSON_NODE_NULL, NULL); + + return json_node_init (json_node_alloc (), type); +} + +/** + * json_node_copy: + * @node: a #JsonNode + * + * Copies @node. If the node contains complex data types, their reference + * counts are increased, regardless of whether the node is mutable or + * immutable. + * + * The copy will be immutable if, and only if, @node is immutable. However, + * there should be no need to copy an immutable node. + * + * Return value: (transfer full): the copied #JsonNode + */ +JsonNode * +json_node_copy (JsonNode *node) +{ + JsonNode *copy; + + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + + copy = json_node_alloc (); + copy->type = node->type; + copy->immutable = node->immutable; + +#ifdef JSON_ENABLE_DEBUG + if (node->immutable) + { + JSON_NOTE (NODE, "Copying immutable JsonNode %p of type %s", + node, + json_node_type_name (node)); + } +#endif + + switch (copy->type) + { + case JSON_NODE_OBJECT: + copy->data.object = json_node_dup_object (node); + break; + + case JSON_NODE_ARRAY: + copy->data.array = json_node_dup_array (node); + break; + + case JSON_NODE_VALUE: + if (node->data.value) + copy->data.value = json_value_ref (node->data.value); + break; + + case JSON_NODE_NULL: + break; + + default: + g_assert_not_reached (); + } + + return copy; +} + +/** + * json_node_ref: + * @node: a #JsonNode + * + * Increment the reference count of @node. + * + * Since: 1.2 + * Returns: (transfer full): a pointer to @node + */ +JsonNode * +json_node_ref (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + + g_atomic_int_inc (&node->ref_count); + + return node; +} + +/** + * json_node_unref: + * @node: (transfer full): a #JsonNode + * + * Decrement the reference count of @node. If it reaches zero, the node is + * freed. + * + * Since: 1.2 + */ +void +json_node_unref (JsonNode *node) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + + if (g_atomic_int_dec_and_test (&node->ref_count)) + { + json_node_unset (node); + if (node->allocated) + g_slice_free (JsonNode, node); + } +} + +/** + * json_node_set_object: + * @node: a #JsonNode initialized to %JSON_NODE_OBJECT + * @object: (nullable): a #JsonObject + * + * Sets @objects inside @node. The reference count of @object is increased. + * + * If @object is %NULL, the node’s existing object is cleared. + * + * It is an error to call this on an immutable node, or on a node which is not + * an object node. + */ +void +json_node_set_object (JsonNode *node, + JsonObject *object) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT); + g_return_if_fail (!node->immutable); + + if (node->data.object != NULL) + json_object_unref (node->data.object); + + if (object) + node->data.object = json_object_ref (object); + else + node->data.object = NULL; +} + +/** + * json_node_take_object: + * @node: a #JsonNode initialized to %JSON_NODE_OBJECT + * @object: (transfer full): a #JsonObject + * + * Sets @object inside @node. The reference count of @object is not increased. + * + * It is an error to call this on an immutable node, or on a node which is not + * an object node. + */ +void +json_node_take_object (JsonNode *node, + JsonObject *object) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT); + g_return_if_fail (!node->immutable); + + if (node->data.object) + { + json_object_unref (node->data.object); + node->data.object = NULL; + } + + if (object) + node->data.object = object; +} + +/** + * json_node_get_object: + * @node: a #JsonNode + * + * Retrieves the #JsonObject stored inside a #JsonNode. It is a programmer error + * to call this on a node which doesn’t hold an object value. Use + * %JSON_NODE_HOLDS_OBJECT first. + * + * Return value: (transfer none) (nullable): the #JsonObject + */ +JsonObject * +json_node_get_object (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL); + + return node->data.object; +} + +/** + * json_node_dup_object: + * @node: a #JsonNode + * + * Retrieves the #JsonObject inside @node. The reference count of + * the returned object is increased. It is a programmer error + * to call this on a node which doesn’t hold an object value. Use + * %JSON_NODE_HOLDS_OBJECT first. + * + * Return value: (transfer full) (nullable): the #JsonObject + */ +JsonObject * +json_node_dup_object (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_OBJECT, NULL); + + if (node->data.object) + return json_object_ref (node->data.object); + + return NULL; +} + +/** + * json_node_set_array: + * @node: a #JsonNode initialized to %JSON_NODE_ARRAY + * @array: a #JsonArray + * + * Sets @array inside @node and increases the #JsonArray reference count. + * + * It is an error to call this on an immutable node, or on a node which is not + * an array node. + */ +void +json_node_set_array (JsonNode *node, + JsonArray *array) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY); + g_return_if_fail (!node->immutable); + + if (node->data.array) + json_array_unref (node->data.array); + + if (array) + node->data.array = json_array_ref (array); + else + node->data.array = NULL; +} + +/** + * json_node_take_array: + * @node: a #JsonNode initialized to %JSON_NODE_ARRAY + * @array: (transfer full): a #JsonArray + * + * Sets @array into @node without increasing the #JsonArray reference count. + * + * It is an error to call this on an immutable node, or a node which is not + * an array node. + */ +void +json_node_take_array (JsonNode *node, + JsonArray *array) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY); + g_return_if_fail (!node->immutable); + + if (node->data.array) + { + json_array_unref (node->data.array); + node->data.array = NULL; + } + + if (array) + node->data.array = array; +} + +/** + * json_node_get_array: + * @node: a #JsonNode + * + * Retrieves the #JsonArray stored inside a #JsonNode. It is a programmer error + * to call this on a node which doesn’t hold an array value. Use + * %JSON_NODE_HOLDS_ARRAY first. + * + * Return value: (transfer none) (nullable): the #JsonArray + */ +JsonArray * +json_node_get_array (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL); + + return node->data.array; +} + +/** + * json_node_dup_array: + * @node: a #JsonNode + * + * Retrieves the #JsonArray stored inside a #JsonNode and returns it + * with its reference count increased by one. It is a programmer error + * to call this on a node which doesn’t hold an array value. Use + * %JSON_NODE_HOLDS_ARRAY first. + * + * Return value: (transfer full) (nullable): the #JsonArray with its reference + * count increased. + */ +JsonArray * +json_node_dup_array (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_ARRAY, NULL); + + if (node->data.array) + return json_array_ref (node->data.array); + + return NULL; +} + +/** + * json_node_get_value: + * @node: a #JsonNode + * @value: (out caller-allocates): return location for an uninitialized value + * + * Retrieves a value from a #JsonNode and copies into @value. When done + * using it, call g_value_unset() on the #GValue. It is a programmer error + * to call this on a node which doesn’t hold a scalar value. Use + * %JSON_NODE_HOLDS_VALUE first. + */ +void +json_node_get_value (JsonNode *node, + GValue *value) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE); + + if (node->data.value) + { + g_value_init (value, JSON_VALUE_TYPE (node->data.value)); + switch (JSON_VALUE_TYPE (node->data.value)) + { + case G_TYPE_INT64: + g_value_set_int64 (value, json_value_get_int (node->data.value)); + break; + + case G_TYPE_DOUBLE: + g_value_set_double (value, json_value_get_double (node->data.value)); + break; + + case G_TYPE_BOOLEAN: + g_value_set_boolean (value, json_value_get_boolean (node->data.value)); + break; + + case G_TYPE_STRING: + g_value_set_string (value, json_value_get_string (node->data.value)); + break; + + default: + break; + } + } +} + +/** + * json_node_set_value: + * @node: a #JsonNode initialized to %JSON_NODE_VALUE + * @value: the #GValue to set + * + * Sets @value inside @node. The passed #GValue is copied into the #JsonNode. + * + * It is an error to call this on an immutable node, or on a node which is not + * a value node. + */ +void +json_node_set_value (JsonNode *node, + const GValue *value) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE); + g_return_if_fail (G_VALUE_TYPE (value) != G_TYPE_INVALID); + g_return_if_fail (!node->immutable); + + if (node->data.value == NULL) + node->data.value = json_value_alloc (); + + switch (G_VALUE_TYPE (value)) + { + /* auto-promote machine integers to 64 bit integers */ + case G_TYPE_INT64: + case G_TYPE_INT: + json_value_init (node->data.value, JSON_VALUE_INT); + if (G_VALUE_TYPE (value) == G_TYPE_INT64) + json_value_set_int (node->data.value, g_value_get_int64 (value)); + else + json_value_set_int (node->data.value, g_value_get_int (value)); + break; + + case G_TYPE_BOOLEAN: + json_value_init (node->data.value, JSON_VALUE_BOOLEAN); + json_value_set_boolean (node->data.value, g_value_get_boolean (value)); + break; + + /* auto-promote single-precision floats to double precision floats */ + case G_TYPE_DOUBLE: + case G_TYPE_FLOAT: + json_value_init (node->data.value, JSON_VALUE_DOUBLE); + if (G_VALUE_TYPE (value) == G_TYPE_DOUBLE) + json_value_set_double (node->data.value, g_value_get_double (value)); + else + json_value_set_double (node->data.value, g_value_get_float (value)); + break; + + case G_TYPE_STRING: + json_value_init (node->data.value, JSON_VALUE_STRING); + json_value_set_string (node->data.value, g_value_get_string (value)); + break; + + default: + g_message ("Invalid value of type '%s'", + g_type_name (G_VALUE_TYPE (value))); + return; + } + +} + +/** + * json_node_free: + * @node: a #JsonNode + * + * Frees the resources allocated by @node. + */ +void +json_node_free (JsonNode *node) +{ + g_return_if_fail (node == NULL || JSON_NODE_IS_VALID (node)); + g_return_if_fail (node == NULL || node->allocated); + + if (G_LIKELY (node)) + { + if (node->ref_count > 1) + g_warning ("Freeing a JsonNode %p owned by other code.", node); + + json_node_unset (node); + g_slice_free (JsonNode, node); + } +} + +/** + * json_node_seal: + * @node: a #JsonNode + * + * Seals the #JsonNode, making it immutable to further changes. In order to be + * sealed, the @node must have a type and value set. The value will be + * recursively sealed — if the node holds an object, that #JsonObject will be + * sealed, etc. + * + * If the @node is already immutable, this is a no-op. + * + * Since: 1.2 + */ +void +json_node_seal (JsonNode *node) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + + if (node->immutable) + return; + + switch (node->type) + { + case JSON_NODE_OBJECT: + g_return_if_fail (node->data.object != NULL); + json_object_seal (node->data.object); + break; + case JSON_NODE_ARRAY: + g_return_if_fail (node->data.array != NULL); + json_array_seal (node->data.array); + break; + case JSON_NODE_NULL: + break; + case JSON_NODE_VALUE: + g_return_if_fail (node->data.value != NULL); + json_value_seal (node->data.value); + break; + default: + g_assert_not_reached (); + } + + node->immutable = TRUE; +} + +/** + * json_node_is_immutable: + * @node: a #JsonNode + * + * Check whether the given @node has been marked as immutable by calling + * json_node_seal() on it. + * + * Since: 1.2 + * Returns: %TRUE if the @node is immutable + */ +gboolean +json_node_is_immutable (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), FALSE); + + return node->immutable; +} + +/** + * json_node_type_name: + * @node: a #JsonNode + * + * Retrieves the user readable name of the data type contained by @node. + * + * Return value: a string containing the name of the type. The returned string + * is owned by the node and should never be modified or freed + */ +const gchar * +json_node_type_name (JsonNode *node) +{ + g_return_val_if_fail (node != NULL, "(null)"); + + switch (node->type) + { + case JSON_NODE_OBJECT: + case JSON_NODE_ARRAY: + case JSON_NODE_NULL: + return json_node_type_get_name (node->type); + + case JSON_NODE_VALUE: + if (node->data.value) + return json_value_type_get_name (node->data.value->type); + } + + return "unknown"; +} + +const gchar * +json_node_type_get_name (JsonNodeType node_type) +{ + switch (node_type) + { + case JSON_NODE_OBJECT: + return "JsonObject"; + + case JSON_NODE_ARRAY: + return "JsonArray"; + + case JSON_NODE_NULL: + return "NULL"; + + case JSON_NODE_VALUE: + return "Value"; + + default: + g_assert_not_reached (); + break; + } + + return "unknown"; +} + +/** + * json_node_set_parent: + * @node: a #JsonNode + * @parent: (transfer none): the parent #JsonNode of @node + * + * Sets the parent #JsonNode of @node. + * + * It is an error to call this with an immutable @parent. @node may be + * immutable. + * + * Since: 0.8 + */ +void +json_node_set_parent (JsonNode *node, + JsonNode *parent) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (parent == NULL || + !json_node_is_immutable (parent)); + + node->parent = parent; +} + +/** + * json_node_get_parent: + * @node: a #JsonNode + * + * Retrieves the parent #JsonNode of @node. + * + * Return value: (transfer none) (nullable): the parent node, or %NULL if @node + * is the root node + */ +JsonNode * +json_node_get_parent (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + + return node->parent; +} + +/** + * json_node_set_string: + * @node: a #JsonNode initialized to %JSON_NODE_VALUE + * @value: a string value + * + * Sets @value as the string content of the @node, replacing any existing + * content. + * + * It is an error to call this on an immutable node, or on a node which is not + * a value node. + */ +void +json_node_set_string (JsonNode *node, + const gchar *value) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE); + g_return_if_fail (!node->immutable); + + if (node->data.value == NULL) + node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_STRING); + else + json_value_init (node->data.value, JSON_VALUE_STRING); + + json_value_set_string (node->data.value, value); +} + +/** + * json_node_get_string: + * @node: a #JsonNode of type %JSON_NODE_VALUE + * + * Gets the string value stored inside a #JsonNode. If the node does not hold a + * string value, %NULL is returned. + * + * Return value: (nullable): a string value. + */ +const gchar * +json_node_get_string (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + + if (JSON_NODE_TYPE (node) == JSON_NODE_NULL) + return NULL; + + if (JSON_VALUE_HOLDS_STRING (node->data.value)) + return json_value_get_string (node->data.value); + + return NULL; +} + +/** + * json_node_dup_string: + * @node: a #JsonNode of type %JSON_NODE_VALUE + * + * Gets a copy of the string value stored inside a #JsonNode. If the node does + * not hold a string value, %NULL is returned. + * + * Return value: (transfer full) (nullable): a newly allocated string + * containing a copy of the #JsonNode contents. Use g_free() to free the + * allocated resources + */ +gchar * +json_node_dup_string (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), NULL); + + return g_strdup (json_node_get_string (node)); +} + +/** + * json_node_set_int: + * @node: a #JsonNode of type %JSON_NODE_VALUE + * @value: an integer value + * + * Sets @value as the integer content of the @node, replacing any existing + * content. + * + * It is an error to call this on an immutable node, or on a node which is not + * a value node. + */ +void +json_node_set_int (JsonNode *node, + gint64 value) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE); + g_return_if_fail (!node->immutable); + + if (node->data.value == NULL) + node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_INT); + else + json_value_init (node->data.value, JSON_VALUE_INT); + + json_value_set_int (node->data.value, value); +} + +/** + * json_node_get_int: + * @node: a #JsonNode of type %JSON_NODE_VALUE + * + * Gets the integer value stored inside a #JsonNode. If the node holds a double + * value, its integer component is returned. If the node holds a %FALSE boolean + * value, `0` is returned; otherwise a non-zero integer is returned. If the + * node holds a %JSON_NODE_NULL value or a value of another non-integer type, + * `0` is returned. + * + * Return value: an integer value. + */ +gint64 +json_node_get_int (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), 0); + + if (JSON_NODE_TYPE (node) == JSON_NODE_NULL) + return 0; + + if (JSON_VALUE_HOLDS_INT (node->data.value)) + return json_value_get_int (node->data.value); + + if (JSON_VALUE_HOLDS_DOUBLE (node->data.value)) + return json_value_get_double (node->data.value); + + if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value)) + return json_value_get_boolean (node->data.value); + + return 0; +} + +/** + * json_node_set_double: + * @node: a #JsonNode of type %JSON_NODE_VALUE + * @value: a double value + * + * Sets @value as the double content of the @node, replacing any existing + * content. + * + * It is an error to call this on an immutable node, or on a node which is not + * a value node. + */ +void +json_node_set_double (JsonNode *node, + gdouble value) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE); + g_return_if_fail (!node->immutable); + + if (node->data.value == NULL) + node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_DOUBLE); + else + json_value_init (node->data.value, JSON_VALUE_DOUBLE); + + json_value_set_double (node->data.value, value); +} + +/** + * json_node_get_double: + * @node: a #JsonNode of type %JSON_NODE_VALUE + * + * Gets the double value stored inside a #JsonNode. If the node holds an integer + * value, it is returned as a double. If the node holds a %FALSE boolean value, + * `0.0` is returned; otherwise a non-zero double is returned. If the node holds + * a %JSON_NODE_NULL value or a value of another non-double type, `0.0` is + * returned. + * + * Return value: a double value. + */ +gdouble +json_node_get_double (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), 0.0); + + if (JSON_NODE_TYPE (node) == JSON_NODE_NULL) + return 0; + + if (JSON_VALUE_HOLDS_DOUBLE (node->data.value)) + return json_value_get_double (node->data.value); + + if (JSON_VALUE_HOLDS_INT (node->data.value)) + return (gdouble) json_value_get_int (node->data.value); + + if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value)) + return (gdouble) json_value_get_boolean (node->data.value); + + return 0.0; +} + +/** + * json_node_set_boolean: + * @node: a #JsonNode of type %JSON_NODE_VALUE + * @value: a boolean value + * + * Sets @value as the boolean content of the @node, replacing any existing + * content. + * + * It is an error to call this on an immutable node, or on a node which is not + * a value node. + */ +void +json_node_set_boolean (JsonNode *node, + gboolean value) +{ + g_return_if_fail (JSON_NODE_IS_VALID (node)); + g_return_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE); + g_return_if_fail (!node->immutable); + + if (node->data.value == NULL) + node->data.value = json_value_init (json_value_alloc (), JSON_VALUE_BOOLEAN); + else + json_value_init (node->data.value, JSON_VALUE_BOOLEAN); + + json_value_set_boolean (node->data.value, value); +} + +/** + * json_node_get_boolean: + * @node: a #JsonNode of type %JSON_NODE_VALUE + * + * Gets the boolean value stored inside a #JsonNode. If the node holds an + * integer or double value which is zero, %FALSE is returned; otherwise %TRUE + * is returned. If the node holds a %JSON_NODE_NULL value or a value of another + * non-boolean type, %FALSE is returned. + * + * Return value: a boolean value. + */ +gboolean +json_node_get_boolean (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), FALSE); + + if (JSON_NODE_TYPE (node) == JSON_NODE_NULL) + return FALSE; + + if (JSON_VALUE_HOLDS_BOOLEAN (node->data.value)) + return json_value_get_boolean (node->data.value); + + if (JSON_VALUE_HOLDS_INT (node->data.value)) + return json_value_get_int (node->data.value) != 0; + + if (JSON_VALUE_HOLDS_DOUBLE (node->data.value)) + return json_value_get_double (node->data.value) != 0.0; + + return FALSE; +} + +/** + * json_node_get_node_type: + * @node: a #JsonNode + * + * Retrieves the #JsonNodeType of @node + * + * Return value: the type of the node + * + * Since: 0.8 + */ +JsonNodeType +json_node_get_node_type (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), JSON_NODE_NULL); + + return node->type; +} + +/** + * json_node_is_null: + * @node: a #JsonNode + * + * Checks whether @node is a %JSON_NODE_NULL. + * + * A %JSON_NODE_NULL node is not the same as a %NULL #JsonNode; a + * %JSON_NODE_NULL represents a 'null' value in the JSON tree. + * + * Return value: %TRUE if the node is null + * + * Since: 0.8 + */ +gboolean +json_node_is_null (JsonNode *node) +{ + g_return_val_if_fail (JSON_NODE_IS_VALID (node), TRUE); + + return node->type == JSON_NODE_NULL; +} + +/** + * json_type_is_a: + * @sub: sub-type + * @super: super-type + * + * Check whether @sub is a sub-type of, or equal to, @super. The only sub-type + * relationship in the JSON Schema type system is that + * %WBL_PRIMITIVE_TYPE_INTEGER is a sub-type of %WBL_PRIMITIVE_TYPE_NUMBER. + * + * Formally, this function calculates: `@sub <: @super`. + * + * Reference: http://json-schema.org/latest/json-schema-core.html#rfc.section.3.5 + * + * Returns: %TRUE if @sub is a sub-type of, or equal to, @super; %FALSE + * otherwise + * Since: 1.2 + */ +static gboolean +json_type_is_a (JsonNode *sub, + JsonNode *super) +{ + if (super->type == JSON_NODE_VALUE && sub->type == JSON_NODE_VALUE) + { + JsonValueType super_value_type, sub_value_type; + + if (super->data.value == NULL || sub->data.value == NULL) + return FALSE; + + super_value_type = super->data.value->type; + sub_value_type = sub->data.value->type; + + return (super_value_type == sub_value_type || + (super_value_type == JSON_VALUE_DOUBLE && + sub_value_type == JSON_VALUE_INT)); + } + + return (super->type == sub->type); +} + +/** + * json_string_hash: + * @key: (type utf8): a JSON string to hash + * + * Calculate a hash value for the given @key (a UTF-8 JSON string). + * + * Note: Member names are compared byte-wise, without applying any Unicode + * decomposition or normalisation. This is not explicitly mentioned in the JSON + * standard (ECMA-404), but is assumed. + * + * Returns: hash value for @key + * Since: 1.2 + */ +guint +json_string_hash (gconstpointer key) +{ + return g_str_hash (key); +} + +/** + * json_string_equal: + * @a: (type utf8): a JSON string + * @b: (type utf8): another JSON string + * + * Check whether @a and @b are equal UTF-8 JSON strings. + * + * Returns: %TRUE if @a and @b are equal; %FALSE otherwise + * Since: 1.2 + */ +gboolean +json_string_equal (gconstpointer a, + gconstpointer b) +{ + return g_str_equal (a, b); +} + +/** + * json_string_compare: + * @a: (type utf8): a JSON string + * @b: (type utf8): another JSON string + * + * Check whether @a and @b are equal UTF-8 JSON strings and return an ordering + * over them in strcmp() style. + * + * Returns: an integer less than zero if @a < @b, equal to zero if @a == @b, and + * greater than zero if @a > @b + * Since: 1.2 + */ +gint +json_string_compare (gconstpointer a, + gconstpointer b) +{ + return g_strcmp0 (a, b); +} + +/** + * json_node_hash: + * @key: (type JsonNode): a JSON node to hash + * + * Calculate a hash value for the given @key (a #JsonNode). + * + * The hash is calculated over the node and its value, recursively. If the node + * is immutable, this is a fast operation; otherwise, it scales proportionally + * with the size of the node’s value (for example, with the number of members + * in the #JsonObject if this node contains an object). + * + * Returns: hash value for @key + * Since: 1.2 + */ +guint +json_node_hash (gconstpointer key) +{ + JsonNode *node; /* unowned */ + + /* These are all randomly generated and arbitrary. */ + const guint value_hash = 0xc19e75ad; + const guint array_hash = 0x865acfc2; + const guint object_hash = 0x3c8f3135; + + node = (JsonNode *) key; + + /* XOR the hash values with a (constant) random number depending on the node’s + * type so that empty values, arrays and objects do not all collide at the + * hash value 0. */ + switch (node->type) + { + case JSON_NODE_NULL: + return 0; + case JSON_NODE_VALUE: + return value_hash ^ json_value_hash (node->data.value); + case JSON_NODE_ARRAY: + return array_hash ^ json_array_hash (json_node_get_array (node)); + case JSON_NODE_OBJECT: + return object_hash ^ json_object_hash (json_node_get_object (node)); + default: + g_assert_not_reached (); + } +} + +/** + * json_node_equal: + * @a: (type JsonNode): a JSON node + * @b: (type JsonNode): another JSON node + * + * Check whether @a and @b are equal #JsonNodes, meaning they have the same + * type and same values (checked recursively). Note that integer values are + * compared numerically, ignoring type, so a double value 4.0 is equal to the + * integer value 4. + * + * Returns: %TRUE if @a and @b are equal; %FALSE otherwise + * Since: 1.2 + */ +gboolean +json_node_equal (gconstpointer a, + gconstpointer b) +{ + JsonNode *node_a, *node_b; /* unowned */ + + node_a = (JsonNode *) a; + node_b = (JsonNode *) b; + + /* Identity comparison. */ + if (node_a == node_b) + return TRUE; + + /* Eliminate mismatched types rapidly. */ + if (!json_type_is_a (node_a, node_b) && + !json_type_is_a (node_b, node_a)) + { + return FALSE; + } + + switch (node_a->type) + { + case JSON_NODE_NULL: + /* Types match already. */ + return TRUE; + case JSON_NODE_ARRAY: + return json_array_equal (json_node_get_array (node_a), + json_node_get_array (node_b)); + case JSON_NODE_OBJECT: + return json_object_equal (json_node_get_object (node_a), + json_node_get_object (node_b)); + case JSON_NODE_VALUE: + /* Handled below. */ + break; + default: + g_assert_not_reached (); + } + + /* Handle values. */ + switch (node_a->data.value->type) + { + case JSON_VALUE_NULL: + /* Types already match. */ + return TRUE; + case JSON_VALUE_BOOLEAN: + return (json_node_get_boolean (node_a) == json_node_get_boolean (node_b)); + case JSON_VALUE_STRING: + return json_string_equal (json_node_get_string (node_a), + json_node_get_string (node_b)); + case JSON_VALUE_DOUBLE: + case JSON_VALUE_INT: { + gdouble val_a, val_b; + JsonValueType value_type_a, value_type_b; + + value_type_a = node_a->data.value->type; + value_type_b = node_b->data.value->type; + + /* Integer comparison doesn’t need to involve doubles… */ + if (value_type_a == JSON_VALUE_INT && + value_type_b == JSON_VALUE_INT) + { + return (json_node_get_int (node_a) == + json_node_get_int (node_b)); + } + + /* …but everything else does. We can use bitwise double equality here, + * since we’re not doing any calculations which could introduce floating + * point error. We expect that the doubles in the JSON nodes come directly + * from strtod() or similar, so should be bitwise equal for equal string + * representations. + * + * Interesting background reading: + * http://randomascii.wordpress.com/2012/06/26/\ + * doubles-are-not-floats-so-dont-compare-them/ + */ + if (value_type_a == JSON_VALUE_INT) + val_a = json_node_get_int (node_a); + else + val_a = json_node_get_double (node_a); + + if (value_type_b == JSON_VALUE_INT) + val_b = json_node_get_int (node_b); + else + val_b = json_node_get_double (node_b); + + return (val_a == val_b); + } + case JSON_VALUE_INVALID: + default: + g_assert_not_reached (); + } +} diff --git a/json-glib/json-object.c b/json-glib/json-object.c new file mode 100644 index 0000000..29b9401 --- /dev/null +++ b/json-glib/json-object.c @@ -0,0 +1,1075 @@ +/* json-object.c - JSON object implementation + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#include "config.h" + +#include +#include + +#include "json-types-private.h" + +/** + * SECTION:json-object + * @short_description: a JSON object representation + * + * #JsonObject is the representation of the object type inside JSON. It + * contains #JsonNodes, which may contain fundamental types, arrays or other + * objects; each node inside an object, or "member", is accessed using a + * unique string, or "name". + * + * Since objects can be expensive, they are reference counted. You can control + * the lifetime of a #JsonObject using json_object_ref() and json_object_unref(). + * + * To add or overwrite a member with a given name, use json_object_set_member(). + * To extract a member with a given name, use json_object_get_member(). + * To retrieve the list of members, use json_object_get_members(). + * To retrieve the size of the object (that is, the number of members it has), + * use json_object_get_size(). + */ + +G_DEFINE_BOXED_TYPE (JsonObject, json_object, json_object_ref, json_object_unref); + +/** + * json_object_new: (constructor) + * + * Creates a new #JsonObject, an JSON object type representation. + * + * Return value: (transfer full): the newly created #JsonObject + */ +JsonObject * +json_object_new (void) +{ + JsonObject *object; + + object = g_slice_new0 (JsonObject); + + object->ref_count = 1; + object->members = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, + (GDestroyNotify) json_node_unref); + g_queue_init (&object->members_ordered); + + return object; +} + +/** + * json_object_ref: + * @object: a #JsonObject + * + * Increase by one the reference count of a #JsonObject. + * + * Return value: (transfer none): the passed #JsonObject, with the reference count + * increased by one. + */ +JsonObject * +json_object_ref (JsonObject *object) +{ + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (object->ref_count > 0, NULL); + + object->ref_count++; + + return object; +} + +/** + * json_object_unref: + * @object: a #JsonObject + * + * Decreases by one the reference count of a #JsonObject. If the + * reference count reaches zero, the object is destroyed and all + * its allocated resources are freed. + */ +void +json_object_unref (JsonObject *object) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (object->ref_count > 0); + + if (--object->ref_count == 0) + { + g_queue_clear (&object->members_ordered); + g_hash_table_destroy (object->members); + object->members = NULL; + + g_slice_free (JsonObject, object); + } +} + +/** + * json_object_seal: + * @object: a #JsonObject + * + * Seals the #JsonObject, making it immutable to further changes. This will + * recursively seal all members of the object too. + * + * If the @object is already immutable, this is a no-op. + * + * Since: 1.2 + */ +void +json_object_seal (JsonObject *object) +{ + JsonObjectIter iter; + JsonNode *node; + + g_return_if_fail (object != NULL); + g_return_if_fail (object->ref_count > 0); + + if (object->immutable) + return; + + /* Propagate to all members. */ + json_object_iter_init (&iter, object); + + while (json_object_iter_next (&iter, NULL, &node)) + json_node_seal (node); + + object->immutable_hash = json_object_hash (object); + object->immutable = TRUE; +} + +/** + * json_object_is_immutable: + * @object: a #JsonObject + * + * Check whether the given @object has been marked as immutable by calling + * json_object_seal() on it. + * + * Since: 1.2 + * Returns: %TRUE if the @object is immutable + */ +gboolean +json_object_is_immutable (JsonObject *object) +{ + g_return_val_if_fail (object != NULL, FALSE); + g_return_val_if_fail (object->ref_count > 0, FALSE); + + return object->immutable; +} + +static inline void +object_set_member_internal (JsonObject *object, + const gchar *member_name, + JsonNode *node) +{ + gchar *name = g_strdup (member_name); + + if (g_hash_table_lookup (object->members, name) == NULL) + g_queue_push_tail (&object->members_ordered, name); + else + { + GList *l; + + /* if the member already exists then we need to replace the + * pointer to its name, to avoid keeping invalid pointers + * once we replace the key in the hash table + */ + l = g_queue_find_custom (&object->members_ordered, name, (GCompareFunc) strcmp); + if (l != NULL) + l->data = name; + } + + g_hash_table_replace (object->members, name, node); +} + +/** + * json_object_add_member: + * @object: a #JsonObject + * @member_name: the name of the member + * @node: (transfer full): the value of the member + * + * Adds a member named @member_name and containing @node into a #JsonObject. + * The object will take ownership of the #JsonNode. + * + * This function will return if the @object already contains a member + * @member_name. + * + * Deprecated: 0.8: Use json_object_set_member() instead + */ +void +json_object_add_member (JsonObject *object, + const gchar *member_name, + JsonNode *node) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + g_return_if_fail (node != NULL); + + if (json_object_has_member (object, member_name)) + { + g_warning ("JsonObject already has a `%s' member of type `%s'", + member_name, + json_node_type_name (node)); + return; + } + + object_set_member_internal (object, member_name, node); +} + +/** + * json_object_set_member: + * @object: a #JsonObject + * @member_name: the name of the member + * @node: (transfer full): the value of the member + * + * Sets @node as the value of @member_name inside @object. + * + * If @object already contains a member called @member_name then + * the member's current value is overwritten. Otherwise, a new + * member is added to @object. + * + * Since: 0.8 + */ +void +json_object_set_member (JsonObject *object, + const gchar *member_name, + JsonNode *node) +{ + JsonNode *old_node; + + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + g_return_if_fail (node != NULL); + + old_node = g_hash_table_lookup (object->members, member_name); + if (old_node == NULL) + goto set_member; + + if (old_node == node) + return; + +set_member: + object_set_member_internal (object, member_name, node); +} + +/** + * json_object_set_int_member: + * @object: a #JsonObject + * @member_name: the name of the member + * @value: the value of the member + * + * Convenience function for setting an integer @value of + * @member_name inside @object. + * + * See also: json_object_set_member() + * + * Since: 0.8 + */ +void +json_object_set_int_member (JsonObject *object, + const gchar *member_name, + gint64 value) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + object_set_member_internal (object, member_name, json_node_init_int (json_node_alloc (), value)); +} + +/** + * json_object_set_double_member: + * @object: a #JsonObject + * @member_name: the name of the member + * @value: the value of the member + * + * Convenience function for setting a floating point @value + * of @member_name inside @object. + * + * See also: json_object_set_member() + * + * Since: 0.8 + */ +void +json_object_set_double_member (JsonObject *object, + const gchar *member_name, + gdouble value) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + object_set_member_internal (object, member_name, json_node_init_double (json_node_alloc (), value)); +} + +/** + * json_object_set_boolean_member: + * @object: a #JsonObject + * @member_name: the name of the member + * @value: the value of the member + * + * Convenience function for setting a boolean @value of + * @member_name inside @object. + * + * See also: json_object_set_member() + * + * Since: 0.8 + */ +void +json_object_set_boolean_member (JsonObject *object, + const gchar *member_name, + gboolean value) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + object_set_member_internal (object, member_name, json_node_init_boolean (json_node_alloc (), value)); +} + +/** + * json_object_set_string_member: + * @object: a #JsonObject + * @member_name: the name of the member + * @value: the value of the member + * + * Convenience function for setting a string @value of + * @member_name inside @object. + * + * See also: json_object_set_member() + * + * Since: 0.8 + */ +void +json_object_set_string_member (JsonObject *object, + const gchar *member_name, + const gchar *value) +{ + JsonNode *node; + + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + node = json_node_alloc (); + + if (value != NULL) + json_node_init_string (node, value); + else + json_node_init_null (node); + + object_set_member_internal (object, member_name, node); +} + +/** + * json_object_set_null_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function for setting a null @value of + * @member_name inside @object. + * + * See also: json_object_set_member() + * + * Since: 0.8 + */ +void +json_object_set_null_member (JsonObject *object, + const gchar *member_name) +{ + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + object_set_member_internal (object, member_name, json_node_init_null (json_node_alloc ())); +} + +/** + * json_object_set_array_member: + * @object: a #JsonObject + * @member_name: the name of the member + * @value: (transfer full): the value of the member + * + * Convenience function for setting an array @value of + * @member_name inside @object. + * + * The @object will take ownership of the passed #JsonArray + * + * See also: json_object_set_member() + * + * Since: 0.8 + */ +void +json_object_set_array_member (JsonObject *object, + const gchar *member_name, + JsonArray *value) +{ + JsonNode *node; + + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + node = json_node_alloc (); + + if (value != NULL) + { + json_node_init_array (node, value); + json_array_unref (value); + } + else + json_node_init_null (node); + + object_set_member_internal (object, member_name, node); +} + +/** + * json_object_set_object_member: + * @object: a #JsonObject + * @member_name: the name of the member + * @value: (transfer full): the value of the member + * + * Convenience function for setting an object @value of + * @member_name inside @object. + * + * The @object will take ownership of the passed #JsonObject + * + * See also: json_object_set_member() + * + * Since: 0.8 + */ +void +json_object_set_object_member (JsonObject *object, + const gchar *member_name, + JsonObject *value) +{ + JsonNode *node; + + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + node = json_node_alloc (); + + if (value != NULL) + { + json_node_init_object (node, value); + json_object_unref (value); + } + else + json_node_init_null (node); + + object_set_member_internal (object, member_name, node); +} + +/** + * json_object_get_members: + * @object: a #JsonObject + * + * Retrieves all the names of the members of a #JsonObject. You can + * obtain the value for each member using json_object_get_member(). + * + * Return value: (element-type utf8) (transfer container) (nullable): a + * #GList of member names, or %NULL. The content of the list is owned + * by the #JsonObject and should never be modified or freed. When you + * have finished using the returned list, use g_list_free() to free + * the resources it has allocated. + */ +GList * +json_object_get_members (JsonObject *object) +{ + g_return_val_if_fail (object != NULL, NULL); + + return g_list_copy (object->members_ordered.head); +} + + +GQueue * +json_object_get_members_internal (JsonObject *object) +{ + g_return_val_if_fail (object != NULL, NULL); + + return &object->members_ordered; +} + +/** + * json_object_get_values: + * @object: a #JsonObject + * + * Retrieves all the values of the members of a #JsonObject. + * + * Return value: (element-type JsonNode) (transfer container) (nullable): a + * #GList of #JsonNodes, or %NULL. The content of the list is owned by the + * #JsonObject and should never be modified or freed. When you have finished + * using the returned list, use g_list_free() to free the resources it has + * allocated. + */ +GList * +json_object_get_values (JsonObject *object) +{ + GList *values, *l; + + g_return_val_if_fail (object != NULL, NULL); + + values = NULL; + for (l = object->members_ordered.tail; l != NULL; l = l->prev) + values = g_list_prepend (values, g_hash_table_lookup (object->members, l->data)); + + return values; +} + +/** + * json_object_dup_member: + * @object: a #JsonObject + * @member_name: the name of the JSON object member to access + * + * Retrieves a copy of the #JsonNode containing the value of @member_name + * inside a #JsonObject + * + * Return value: (transfer full) (nullable): a copy of the node for the + * requested object member or %NULL. Use json_node_unref() when done. + * + * Since: 0.6 + */ +JsonNode * +json_object_dup_member (JsonObject *object, + const gchar *member_name) +{ + JsonNode *retval; + + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (member_name != NULL, NULL); + + retval = json_object_get_member (object, member_name); + if (!retval) + return NULL; + + return json_node_copy (retval); +} + +static inline JsonNode * +object_get_member_internal (JsonObject *object, + const gchar *member_name) +{ + return g_hash_table_lookup (object->members, member_name); +} + +/** + * json_object_get_member: + * @object: a #JsonObject + * @member_name: the name of the JSON object member to access + * + * Retrieves the #JsonNode containing the value of @member_name inside + * a #JsonObject. + * + * Return value: (transfer none) (nullable): a pointer to the node for the + * requested object member, or %NULL + */ +JsonNode * +json_object_get_member (JsonObject *object, + const gchar *member_name) +{ + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (member_name != NULL, NULL); + + return object_get_member_internal (object, member_name); +} + +/** + * json_object_get_int_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function that retrieves the integer value + * stored in @member_name of @object + * + * See also: json_object_get_member() + * + * Return value: the integer value of the object's member + * + * Since: 0.8 + */ +gint64 +json_object_get_int_member (JsonObject *object, + const gchar *member_name) +{ + JsonNode *node; + + g_return_val_if_fail (object != NULL, 0); + g_return_val_if_fail (member_name != NULL, 0); + + node = object_get_member_internal (object, member_name); + g_return_val_if_fail (node != NULL, 0); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0); + + return json_node_get_int (node); +} + +/** + * json_object_get_double_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function that retrieves the floating point value + * stored in @member_name of @object + * + * See also: json_object_get_member() + * + * Return value: the floating point value of the object's member + * + * Since: 0.8 + */ +gdouble +json_object_get_double_member (JsonObject *object, + const gchar *member_name) +{ + JsonNode *node; + + g_return_val_if_fail (object != NULL, 0.0); + g_return_val_if_fail (member_name != NULL, 0.0); + + node = object_get_member_internal (object, member_name); + g_return_val_if_fail (node != NULL, 0.0); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0); + + return json_node_get_double (node); +} + +/** + * json_object_get_boolean_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function that retrieves the boolean value + * stored in @member_name of @object + * + * See also: json_object_get_member() + * + * Return value: the boolean value of the object's member + * + * Since: 0.8 + */ +gboolean +json_object_get_boolean_member (JsonObject *object, + const gchar *member_name) +{ + JsonNode *node; + + g_return_val_if_fail (object != NULL, FALSE); + g_return_val_if_fail (member_name != NULL, FALSE); + + node = object_get_member_internal (object, member_name); + g_return_val_if_fail (node != NULL, FALSE); + g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE); + + return json_node_get_boolean (node); +} + +/** + * json_object_get_null_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function that checks whether the value + * stored in @member_name of @object is null + * + * See also: json_object_get_member() + * + * Return value: %TRUE if the value is null + * + * Since: 0.8 + */ +gboolean +json_object_get_null_member (JsonObject *object, + const gchar *member_name) +{ + JsonNode *node; + + g_return_val_if_fail (object != NULL, FALSE); + g_return_val_if_fail (member_name != NULL, FALSE); + + node = object_get_member_internal (object, member_name); + g_return_val_if_fail (node != NULL, FALSE); + + if (JSON_NODE_HOLDS_NULL (node)) + return TRUE; + + if (JSON_NODE_HOLDS_OBJECT (node)) + return json_node_get_object (node) == NULL; + + if (JSON_NODE_HOLDS_ARRAY (node)) + return json_node_get_array (node) == NULL; + + return FALSE; +} + +/** + * json_object_get_string_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function that retrieves the string value + * stored in @member_name of @object + * + * See also: json_object_get_member() + * + * Return value: the string value of the object's member + * + * Since: 0.8 + */ +const gchar * +json_object_get_string_member (JsonObject *object, + const gchar *member_name) +{ + JsonNode *node; + + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (member_name != NULL, NULL); + + node = object_get_member_internal (object, member_name); + g_return_val_if_fail (node != NULL, NULL); + g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL); + + if (JSON_NODE_HOLDS_NULL (node)) + return NULL; + + return json_node_get_string (node); +} + +/** + * json_object_get_array_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function that retrieves the array + * stored in @member_name of @object + * + * See also: json_object_get_member() + * + * Return value: (transfer none): the array inside the object's member + * + * Since: 0.8 + */ +JsonArray * +json_object_get_array_member (JsonObject *object, + const gchar *member_name) +{ + JsonNode *node; + + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (member_name != NULL, NULL); + + node = object_get_member_internal (object, member_name); + g_return_val_if_fail (node != NULL, NULL); + g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL); + + if (JSON_NODE_HOLDS_NULL (node)) + return NULL; + + return json_node_get_array (node); +} + +/** + * json_object_get_object_member: + * @object: a #JsonObject + * @member_name: the name of the member + * + * Convenience function that retrieves the object + * stored in @member_name of @object. It is an error to specify a @member_name + * which does not exist. + * + * See also: json_object_get_member() + * + * Return value: (transfer none) (nullable): the object inside the object’s + * member, or %NULL if the value for the member is `null` + * + * Since: 0.8 + */ +JsonObject * +json_object_get_object_member (JsonObject *object, + const gchar *member_name) +{ + JsonNode *node; + + g_return_val_if_fail (object != NULL, NULL); + g_return_val_if_fail (member_name != NULL, NULL); + + node = object_get_member_internal (object, member_name); + g_return_val_if_fail (node != NULL, NULL); + g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL); + + if (JSON_NODE_HOLDS_NULL (node)) + return NULL; + + return json_node_get_object (node); +} + +/** + * json_object_has_member: + * @object: a #JsonObject + * @member_name: the name of a JSON object member + * + * Checks whether @object has a member named @member_name. + * + * Return value: %TRUE if the JSON object has the requested member + */ +gboolean +json_object_has_member (JsonObject *object, + const gchar *member_name) +{ + g_return_val_if_fail (object != NULL, FALSE); + g_return_val_if_fail (member_name != NULL, FALSE); + + return (g_hash_table_lookup (object->members, member_name) != NULL); +} + +/** + * json_object_get_size: + * @object: a #JsonObject + * + * Retrieves the number of members of a #JsonObject. + * + * Return value: the number of members + */ +guint +json_object_get_size (JsonObject *object) +{ + g_return_val_if_fail (object != NULL, 0); + + return g_hash_table_size (object->members); +} + +/** + * json_object_remove_member: + * @object: a #JsonObject + * @member_name: the name of the member to remove + * + * Removes @member_name from @object, freeing its allocated resources. + */ +void +json_object_remove_member (JsonObject *object, + const gchar *member_name) +{ + GList *l; + + g_return_if_fail (object != NULL); + g_return_if_fail (member_name != NULL); + + for (l = object->members_ordered.head; l != NULL; l = l->next) + { + const gchar *name = l->data; + + if (g_strcmp0 (name, member_name) == 0) + { + g_queue_delete_link (&object->members_ordered, l); + break; + } + } + + g_hash_table_remove (object->members, member_name); +} + +/** + * json_object_foreach_member: + * @object: a #JsonObject + * @func: (scope call): the function to be called on each member + * @data: (closure): data to be passed to the function + * + * Iterates over all members of @object and calls @func on + * each one of them. + * + * It is safe to change the value of a #JsonNode of the @object + * from within the iterator @func, but it is not safe to add or + * remove members from the @object. + * + * Since: 0.8 + */ +void +json_object_foreach_member (JsonObject *object, + JsonObjectForeach func, + gpointer data) +{ + GList *l; + + g_return_if_fail (object != NULL); + g_return_if_fail (func != NULL); + + for (l = object->members_ordered.head; l != NULL; l = l->next) + { + const gchar *member_name = l->data; + JsonNode *member_node = g_hash_table_lookup (object->members, member_name); + + func (object, member_name, member_node, data); + } +} + +/** + * json_object_hash: + * @key: (type JsonObject): a JSON object to hash + * + * Calculate a hash value for the given @key (a #JsonObject). + * + * The hash is calculated over the object and all its members, recursively. If + * the object is immutable, this is a fast operation; otherwise, it scales + * proportionally with the number of members in the object. + * + * Returns: hash value for @key + * Since: 1.2 + */ +guint +json_object_hash (gconstpointer key) +{ + JsonObject *object = (JsonObject *) key; + guint hash = 0; + JsonObjectIter iter; + const gchar *member_name; + JsonNode *node; + + g_return_val_if_fail (object != NULL, 0); + + /* If the object is immutable, use the cached hash. */ + if (object->immutable) + return object->immutable_hash; + + /* Otherwise, calculate from scratch. */ + json_object_iter_init (&iter, object); + + while (json_object_iter_next (&iter, &member_name, &node)) + hash ^= (json_string_hash (member_name) ^ json_node_hash (node)); + + return hash; +} + +/** + * json_object_equal: + * @a: (type JsonObject): a JSON object + * @b: (type JsonObject): another JSON object + * + * Check whether @a and @b are equal #JsonObjects, meaning they have the same + * set of members, and the values of corresponding members are equal. + * + * Returns: %TRUE if @a and @b are equal; %FALSE otherwise + * Since: 1.2 + */ +gboolean +json_object_equal (gconstpointer a, + gconstpointer b) +{ + JsonObject *object_a, *object_b; + guint size_a, size_b; + JsonObjectIter iter_a; + JsonNode *child_a, *child_b; /* unowned */ + const gchar *member_name; + + object_a = (JsonObject *) a; + object_b = (JsonObject *) b; + + /* Identity comparison. */ + if (object_a == object_b) + return TRUE; + + /* Check sizes. */ + size_a = json_object_get_size (object_a); + size_b = json_object_get_size (object_b); + + if (size_a != size_b) + return FALSE; + + /* Check member names and values. Check the member names first + * to avoid expensive recursive value comparisons which might + * be unnecessary. */ + json_object_iter_init (&iter_a, object_a); + + while (json_object_iter_next (&iter_a, &member_name, NULL)) + { + if (!json_object_has_member (object_b, member_name)) + return FALSE; + } + + json_object_iter_init (&iter_a, object_a); + + while (json_object_iter_next (&iter_a, &member_name, &child_a)) + { + child_b = json_object_get_member (object_b, member_name); + + if (!json_node_equal (child_a, child_b)) + return FALSE; + } + + return TRUE; +} + +/** + * json_object_iter_init: + * @iter: an uninitialised #JsonObjectIter + * @object: the #JsonObject to iterate over + * + * Initialise the @iter and associate it with @object. + * + * |[ + * JsonObjectIter iter; + * const gchar *member_name; + * JsonNode *member_node; + * + * json_object_iter_init (&iter, some_object); + * while (json_object_iter_next (&iter, &member_name, &member_node)) + * { + * // Do something with @member_name and @member_node. + * } + * ]| + * + * Since: 1.2 + */ +void +json_object_iter_init (JsonObjectIter *iter, + JsonObject *object) +{ + JsonObjectIterReal *iter_real = (JsonObjectIterReal *) iter;; + + g_return_if_fail (iter != NULL); + g_return_if_fail (object != NULL); + g_return_if_fail (object->ref_count > 0); + + iter_real->object = object; + g_hash_table_iter_init (&iter_real->members_iter, object->members); +} + +/** + * json_object_iter_next: + * @iter: a #JsonObjectIter + * @member_name: (out callee-allocates) (transfer none) (optional): return + * location for the member name, or %NULL to ignore + * @member_node: (out callee-allocates) (transfer none) (optional): return + * location for the member value, or %NULL to ignore + * + * Advance @iter and retrieve the next member in the object. If the end of the + * object is reached, %FALSE is returned and @member_name and @member_node are + * set to invalid values. After that point, the @iter is invalid. + * + * The order in which members are returned by the iterator is undefined. The + * iterator is invalidated if its #JsonObject is modified during iteration. + * + * Returns: %TRUE if @member_name and @member_node are valid; %FALSE if the end + * of the object has been reached + * + * Since: 1.2 + */ +gboolean +json_object_iter_next (JsonObjectIter *iter, + const gchar **member_name, + JsonNode **member_node) +{ + JsonObjectIterReal *iter_real = (JsonObjectIterReal *) iter; + + g_return_val_if_fail (iter != NULL, FALSE); + g_return_val_if_fail (iter_real->object != NULL, FALSE); + g_return_val_if_fail (iter_real->object->ref_count > 0, FALSE); + + return g_hash_table_iter_next (&iter_real->members_iter, + (gpointer *) member_name, + (gpointer *) member_node); +} diff --git a/json-glib/json-parser.c b/json-glib/json-parser.c new file mode 100644 index 0000000..1155783 --- /dev/null +++ b/json-glib/json-parser.c @@ -0,0 +1,1533 @@ +/* json-parser.c - JSON streams parser + * + * This file is part of JSON-GLib + * + * Copyright © 2007, 2008, 2009 OpenedHand Ltd + * Copyright © 2009, 2010 Intel Corp. + * Copyright © 2015 Collabora Ltd. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + * Philip Withnall + */ + +/** + * SECTION:json-parser + * @short_description: Parse JSON data streams + * + * #JsonParser provides an object for parsing a JSON data stream, either + * inside a file or inside a static buffer. + */ + +#include "config.h" + +#include + +#include + +#include "json-types-private.h" + +#include "json-debug.h" +#include "json-parser.h" +#include "json-scanner.h" + +struct _JsonParserPrivate +{ + JsonNode *root; + JsonNode *current_node; + + JsonScanner *scanner; + + JsonParserError error_code; + GError *last_error; + + gchar *variable_name; + gchar *filename; + + guint has_assignment : 1; + guint is_filename : 1; + guint is_immutable : 1; +}; + +static const gchar symbol_names[] = + "true\0" + "false\0" + "null\0" + "var\0"; + +static const struct +{ + guint name_offset; + guint token; +} symbols[] = { + { 0, JSON_TOKEN_TRUE }, + { 5, JSON_TOKEN_FALSE }, + { 11, JSON_TOKEN_NULL }, + { 16, JSON_TOKEN_VAR } +}; + +static const guint n_symbols = G_N_ELEMENTS (symbols); + +enum +{ + PARSE_START, + OBJECT_START, + OBJECT_MEMBER, + OBJECT_END, + ARRAY_START, + ARRAY_ELEMENT, + ARRAY_END, + PARSE_END, + ERROR, + + LAST_SIGNAL +}; + +static guint parser_signals[LAST_SIGNAL] = { 0, }; + +enum +{ + PROP_IMMUTABLE = 1, + PROP_LAST +}; + +static GParamSpec *parser_props[PROP_LAST] = { NULL, }; + +G_DEFINE_QUARK (json-parser-error-quark, json_parser_error) + +G_DEFINE_TYPE_WITH_PRIVATE (JsonParser, json_parser, G_TYPE_OBJECT) + +static guint json_parse_array (JsonParser *parser, + JsonScanner *scanner, + JsonNode **node); +static guint json_parse_object (JsonParser *parser, + JsonScanner *scanner, + JsonNode **node); + +static inline void +json_parser_clear (JsonParser *parser) +{ + JsonParserPrivate *priv = parser->priv; + + g_free (priv->variable_name); + priv->variable_name = NULL; + + if (priv->last_error) + { + g_error_free (priv->last_error); + priv->last_error = NULL; + } + + if (priv->root) + { + json_node_unref (priv->root); + priv->root = NULL; + } +} + +static void +json_parser_dispose (GObject *gobject) +{ + json_parser_clear (JSON_PARSER (gobject)); + + G_OBJECT_CLASS (json_parser_parent_class)->dispose (gobject); +} + +static void +json_parser_finalize (GObject *gobject) +{ + JsonParserPrivate *priv = JSON_PARSER (gobject)->priv; + + g_free (priv->variable_name); + g_free (priv->filename); + + G_OBJECT_CLASS (json_parser_parent_class)->finalize (gobject); +} + +static void +json_parser_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + JsonParserPrivate *priv = JSON_PARSER (gobject)->priv; + + switch (prop_id) + { + case PROP_IMMUTABLE: + /* Construct-only. */ + priv->is_immutable = g_value_get_boolean (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +json_parser_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + JsonParserPrivate *priv = JSON_PARSER (gobject)->priv; + + switch (prop_id) + { + case PROP_IMMUTABLE: + g_value_set_boolean (value, priv->is_immutable); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +json_parser_class_init (JsonParserClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = json_parser_set_property; + gobject_class->get_property = json_parser_get_property; + gobject_class->dispose = json_parser_dispose; + gobject_class->finalize = json_parser_finalize; + + /** + * JsonParser:immutable: + * + * Whether the #JsonNode tree built by the #JsonParser should be immutable + * when created. Making the output immutable on creation avoids the expense + * of traversing it to make it immutable later. + * + * Since: 1.2 + */ + parser_props[PROP_IMMUTABLE] = + g_param_spec_boolean ("immutable", + "Immutable Output", + "Whether the parser output is immutable.", + FALSE, + G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE); + + g_object_class_install_properties (gobject_class, PROP_LAST, parser_props); + + /** + * JsonParser::parse-start: + * @parser: the #JsonParser that received the signal + * + * The ::parse-start signal is emitted when the parser began parsing + * a JSON data stream. + */ + parser_signals[PARSE_START] = + g_signal_new ("parse-start", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, parse_start), + NULL, NULL, + NULL, + G_TYPE_NONE, 0); + /** + * JsonParser::parse-end: + * @parser: the #JsonParser that received the signal + * + * The ::parse-end signal is emitted when the parser successfully + * finished parsing a JSON data stream + */ + parser_signals[PARSE_END] = + g_signal_new ("parse-end", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, parse_end), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + /** + * JsonParser::object-start: + * @parser: the #JsonParser that received the signal + * + * The ::object-start signal is emitted each time the #JsonParser + * starts parsing a #JsonObject. + */ + parser_signals[OBJECT_START] = + g_signal_new ("object-start", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, object_start), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + /** + * JsonParser::object-member: + * @parser: the #JsonParser that received the signal + * @object: a #JsonObject + * @member_name: the name of the newly parsed member + * + * The ::object-member signal is emitted each time the #JsonParser + * has successfully parsed a single member of a #JsonObject. The + * object and member are passed to the signal handlers. + */ + parser_signals[OBJECT_MEMBER] = + g_signal_new ("object-member", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, object_member), + NULL, NULL, NULL, + G_TYPE_NONE, 2, + JSON_TYPE_OBJECT, + G_TYPE_STRING); + /** + * JsonParser::object-end: + * @parser: the #JsonParser that received the signal + * @object: the parsed #JsonObject + * + * The ::object-end signal is emitted each time the #JsonParser + * has successfully parsed an entire #JsonObject. + */ + parser_signals[OBJECT_END] = + g_signal_new ("object-end", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, object_end), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + JSON_TYPE_OBJECT); + /** + * JsonParser::array-start: + * @parser: the #JsonParser that received the signal + * + * The ::array-start signal is emitted each time the #JsonParser + * starts parsing a #JsonArray + */ + parser_signals[ARRAY_START] = + g_signal_new ("array-start", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, array_start), + NULL, NULL, NULL, + G_TYPE_NONE, 0); + /** + * JsonParser::array-element: + * @parser: the #JsonParser that received the signal + * @array: a #JsonArray + * @index_: the index of the newly parsed element + * + * The ::array-element signal is emitted each time the #JsonParser + * has successfully parsed a single element of a #JsonArray. The + * array and element index are passed to the signal handlers. + */ + parser_signals[ARRAY_ELEMENT] = + g_signal_new ("array-element", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, array_element), + NULL, NULL, NULL, + G_TYPE_NONE, 2, + JSON_TYPE_ARRAY, + G_TYPE_INT); + /** + * JsonParser::array-end: + * @parser: the #JsonParser that received the signal + * @array: the parsed #JsonArray + * + * The ::array-end signal is emitted each time the #JsonParser + * has successfully parsed an entire #JsonArray + */ + parser_signals[ARRAY_END] = + g_signal_new ("array-end", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, array_end), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + JSON_TYPE_ARRAY); + /** + * JsonParser::error: + * @parser: the parser instance that received the signal + * @error: a pointer to the #GError + * + * The ::error signal is emitted each time a #JsonParser encounters + * an error in a JSON stream. + */ + parser_signals[ERROR] = + g_signal_new ("error", + G_OBJECT_CLASS_TYPE (gobject_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (JsonParserClass, error), + NULL, NULL, NULL, + G_TYPE_NONE, 1, + G_TYPE_POINTER); +} + +static void +json_parser_init (JsonParser *parser) +{ + JsonParserPrivate *priv = json_parser_get_instance_private (parser); + + parser->priv = priv; + + priv->root = NULL; + priv->current_node = NULL; + + priv->error_code = JSON_PARSER_ERROR_PARSE; + priv->last_error = NULL; + + priv->has_assignment = FALSE; + priv->variable_name = NULL; + + priv->is_filename = FALSE; + priv->filename = FALSE; +} + +static guint +json_parse_value (JsonParser *parser, + JsonScanner *scanner, + guint token, + JsonNode **node) +{ + JsonParserPrivate *priv = parser->priv; + JsonNode *current_node = priv->current_node; + gboolean is_negative = FALSE; + + if (token == '-') + { + guint next_token = json_scanner_peek_next_token (scanner); + + if (next_token == G_TOKEN_INT || + next_token == G_TOKEN_FLOAT) + { + is_negative = TRUE; + token = json_scanner_get_next_token (scanner); + } + else + return G_TOKEN_INT; + } + + switch (token) + { + case G_TOKEN_INT: + JSON_NOTE (PARSER, "abs(node): %" G_GINT64_FORMAT " (sign: %s)", + scanner->value.v_int64, + is_negative ? "negative" : "positive"); + *node = json_node_init_int (json_node_alloc (), + is_negative ? scanner->value.v_int64 * -1 + : scanner->value.v_int64); + break; + + case G_TOKEN_FLOAT: + JSON_NOTE (PARSER, "abs(node): %.6f (sign: %s)", + scanner->value.v_float, + is_negative ? "negative" : "positive"); + *node = json_node_init_double (json_node_alloc (), + is_negative ? scanner->value.v_float * -1.0 + : scanner->value.v_float); + break; + + case G_TOKEN_STRING: + JSON_NOTE (PARSER, "node: '%s'", + scanner->value.v_string); + *node = json_node_init_string (json_node_alloc (), scanner->value.v_string); + break; + + case JSON_TOKEN_TRUE: + case JSON_TOKEN_FALSE: + JSON_NOTE (PARSER, "node: '%s'", + JSON_TOKEN_TRUE ? "" : ""); + *node = json_node_init_boolean (json_node_alloc (), token == JSON_TOKEN_TRUE ? TRUE : FALSE); + break; + + case JSON_TOKEN_NULL: + JSON_NOTE (PARSER, "node: "); + *node = json_node_init_null (json_node_alloc ()); + break; + + case G_TOKEN_IDENTIFIER: + JSON_NOTE (PARSER, "node: identifier '%s'", scanner->value.v_identifier); + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; + *node = NULL; + return G_TOKEN_SYMBOL; + + default: + { + JsonNodeType cur_type; + + *node = NULL; + + JSON_NOTE (PARSER, "node: invalid token"); + + cur_type = json_node_get_node_type (current_node); + if (cur_type == JSON_NODE_ARRAY) + { + priv->error_code = JSON_PARSER_ERROR_PARSE; + return G_TOKEN_RIGHT_BRACE; + } + else if (cur_type == JSON_NODE_OBJECT) + { + priv->error_code = JSON_PARSER_ERROR_PARSE; + return G_TOKEN_RIGHT_CURLY; + } + else + { + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; + return G_TOKEN_SYMBOL; + } + } + break; + } + + if (priv->is_immutable && *node != NULL) + json_node_seal (*node); + + return G_TOKEN_NONE; +} + +static guint +json_parse_array (JsonParser *parser, + JsonScanner *scanner, + JsonNode **node) +{ + JsonParserPrivate *priv = parser->priv; + JsonNode *old_current; + JsonArray *array; + guint token; + gint idx; + + old_current = priv->current_node; + priv->current_node = json_node_init_array (json_node_alloc (), NULL); + + array = json_array_new (); + + token = json_scanner_get_next_token (scanner); + g_assert (token == G_TOKEN_LEFT_BRACE); + + g_signal_emit (parser, parser_signals[ARRAY_START], 0); + + idx = 0; + while (token != G_TOKEN_RIGHT_BRACE) + { + guint next_token = json_scanner_peek_next_token (scanner); + JsonNode *element = NULL; + + /* parse the element */ + switch (next_token) + { + case G_TOKEN_LEFT_BRACE: + JSON_NOTE (PARSER, "Nested array at index %d", idx); + token = json_parse_array (parser, scanner, &element); + break; + + case G_TOKEN_LEFT_CURLY: + JSON_NOTE (PARSER, "Nested object at index %d", idx); + token = json_parse_object (parser, scanner, &element); + break; + + case G_TOKEN_RIGHT_BRACE: + goto array_done; + + default: + token = json_scanner_get_next_token (scanner); + token = json_parse_value (parser, scanner, token, &element); + break; + } + + if (token != G_TOKEN_NONE || element == NULL) + { + /* the json_parse_* functions will have set the error code */ + json_array_unref (array); + json_node_unref (priv->current_node); + priv->current_node = old_current; + + return token; + } + + next_token = json_scanner_peek_next_token (scanner); + + /* look for missing commas */ + if (next_token != G_TOKEN_COMMA && next_token != G_TOKEN_RIGHT_BRACE) + { + priv->error_code = JSON_PARSER_ERROR_MISSING_COMMA; + + json_array_unref (array); + json_node_free (priv->current_node); + json_node_free (element); + priv->current_node = old_current; + + return G_TOKEN_COMMA; + } + + /* look for trailing commas */ + if (next_token == G_TOKEN_COMMA) + { + token = json_scanner_get_next_token (scanner); + next_token = json_scanner_peek_next_token (scanner); + + if (next_token == G_TOKEN_RIGHT_BRACE) + { + priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; + + json_array_unref (array); + json_node_unref (priv->current_node); + json_node_unref (element); + priv->current_node = old_current; + + return G_TOKEN_RIGHT_BRACE; + } + } + + JSON_NOTE (PARSER, "Array element %d completed", idx); + json_node_set_parent (element, priv->current_node); + if (priv->is_immutable) + json_node_seal (element); + json_array_add_element (array, element); + + g_signal_emit (parser, parser_signals[ARRAY_ELEMENT], 0, + array, + idx); + + idx += 1; + token = next_token; + } + +array_done: + json_scanner_get_next_token (scanner); + + if (priv->is_immutable) + json_array_seal (array); + + json_node_take_array (priv->current_node, array); + if (priv->is_immutable) + json_node_seal (priv->current_node); + json_node_set_parent (priv->current_node, old_current); + + g_signal_emit (parser, parser_signals[ARRAY_END], 0, array); + + if (node != NULL && *node == NULL) + *node = priv->current_node; + + priv->current_node = old_current; + + return G_TOKEN_NONE; +} + +static guint +json_parse_object (JsonParser *parser, + JsonScanner *scanner, + JsonNode **node) +{ + JsonParserPrivate *priv = parser->priv; + JsonObject *object; + JsonNode *old_current; + guint token; + + old_current = priv->current_node; + priv->current_node = json_node_init_object (json_node_alloc (), NULL); + + object = json_object_new (); + + token = json_scanner_get_next_token (scanner); + g_assert (token == G_TOKEN_LEFT_CURLY); + + g_signal_emit (parser, parser_signals[OBJECT_START], 0); + + while (token != G_TOKEN_RIGHT_CURLY) + { + guint next_token = json_scanner_peek_next_token (scanner); + JsonNode *member = NULL; + gchar *name; + + /* we need to abort here because empty objects do not + * have member names + */ + if (next_token == G_TOKEN_RIGHT_CURLY) + break; + + /* parse the member's name */ + if (next_token != G_TOKEN_STRING) + { + JSON_NOTE (PARSER, "Missing object member name"); + + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; + + json_object_unref (object); + json_node_unref (priv->current_node); + priv->current_node = old_current; + + return G_TOKEN_STRING; + } + + /* member name */ + token = json_scanner_get_next_token (scanner); + name = g_strdup (scanner->value.v_string); + if (name == NULL) + { + JSON_NOTE (PARSER, "Empty object member name"); + + priv->error_code = JSON_PARSER_ERROR_EMPTY_MEMBER_NAME; + + json_object_unref (object); + json_node_unref (priv->current_node); + priv->current_node = old_current; + + return G_TOKEN_STRING; + } + + JSON_NOTE (PARSER, "Object member '%s'", name); + + /* a colon separates names from values */ + next_token = json_scanner_peek_next_token (scanner); + if (next_token != ':') + { + JSON_NOTE (PARSER, "Missing object member name separator"); + + priv->error_code = JSON_PARSER_ERROR_MISSING_COLON; + + g_free (name); + json_object_unref (object); + json_node_unref (priv->current_node); + priv->current_node = old_current; + + return ':'; + } + + /* we swallow the ':' */ + token = json_scanner_get_next_token (scanner); + g_assert (token == ':'); + next_token = json_scanner_peek_next_token (scanner); + + /* parse the member's value */ + switch (next_token) + { + case G_TOKEN_LEFT_BRACE: + JSON_NOTE (PARSER, "Nested array at member %s", name); + token = json_parse_array (parser, scanner, &member); + break; + + case G_TOKEN_LEFT_CURLY: + JSON_NOTE (PARSER, "Nested object at member %s", name); + token = json_parse_object (parser, scanner, &member); + break; + + default: + /* once a member name is defined we need a value */ + token = json_scanner_get_next_token (scanner); + token = json_parse_value (parser, scanner, token, &member); + break; + } + + if (token != G_TOKEN_NONE || member == NULL) + { + /* the json_parse_* functions will have set the error code */ + g_free (name); + json_object_unref (object); + json_node_unref (priv->current_node); + priv->current_node = old_current; + + return token; + } + + next_token = json_scanner_peek_next_token (scanner); + if (next_token == G_TOKEN_COMMA) + { + token = json_scanner_get_next_token (scanner); + next_token = json_scanner_peek_next_token (scanner); + + /* look for trailing commas */ + if (next_token == G_TOKEN_RIGHT_CURLY) + { + priv->error_code = JSON_PARSER_ERROR_TRAILING_COMMA; + + g_free (name); + json_object_unref (object); + json_node_unref (member); + json_node_unref (priv->current_node); + priv->current_node = old_current; + + return G_TOKEN_RIGHT_BRACE; + } + } + else if (next_token == G_TOKEN_STRING) + { + priv->error_code = JSON_PARSER_ERROR_MISSING_COMMA; + + g_free (name); + json_object_unref (object); + json_node_unref (member); + json_node_unref (priv->current_node); + priv->current_node = old_current; + + return G_TOKEN_COMMA; + } + + JSON_NOTE (PARSER, "Object member '%s' completed", name); + json_node_set_parent (member, priv->current_node); + if (priv->is_immutable) + json_node_seal (member); + json_object_set_member (object, name, member); + + g_signal_emit (parser, parser_signals[OBJECT_MEMBER], 0, + object, + name); + + g_free (name); + + token = next_token; + } + + json_scanner_get_next_token (scanner); + + if (priv->is_immutable) + json_object_seal (object); + + json_node_take_object (priv->current_node, object); + if (priv->is_immutable) + json_node_seal (priv->current_node); + json_node_set_parent (priv->current_node, old_current); + + g_signal_emit (parser, parser_signals[OBJECT_END], 0, object); + + if (node != NULL && *node == NULL) + *node = priv->current_node; + + priv->current_node = old_current; + + return G_TOKEN_NONE; +} + +static guint +json_parse_statement (JsonParser *parser, + JsonScanner *scanner) +{ + JsonParserPrivate *priv = parser->priv; + guint token; + + token = json_scanner_peek_next_token (scanner); + switch (token) + { + case G_TOKEN_LEFT_CURLY: + JSON_NOTE (PARSER, "Statement is object declaration"); + return json_parse_object (parser, scanner, &priv->root); + + case G_TOKEN_LEFT_BRACE: + JSON_NOTE (PARSER, "Statement is array declaration"); + return json_parse_array (parser, scanner, &priv->root); + + /* some web APIs are not only passing the data structures: they are + * also passing an assigment, which makes parsing horribly complicated + * only because web developers are lazy, and writing "var foo = " is + * evidently too much to request from them. + */ + case JSON_TOKEN_VAR: + { + guint next_token; + gchar *name; + + JSON_NOTE (PARSER, "Statement is an assignment"); + + /* swallow the 'var' token... */ + token = json_scanner_get_next_token (scanner); + + /* ... swallow the variable name... */ + next_token = json_scanner_get_next_token (scanner); + if (next_token != G_TOKEN_IDENTIFIER) + { + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; + return G_TOKEN_IDENTIFIER; + } + + name = g_strdup (scanner->value.v_identifier); + + /* ... and finally swallow the '=' */ + next_token = json_scanner_get_next_token (scanner); + if (next_token != '=') + { + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; + g_free (name); + return '='; + } + + priv->has_assignment = TRUE; + priv->variable_name = name; + + token = json_parse_statement (parser, scanner); + + /* remove the trailing semi-colon */ + next_token = json_scanner_peek_next_token (scanner); + if (next_token == ';') + { + token = json_scanner_get_next_token (scanner); + return G_TOKEN_NONE; + } + + return token; + } + break; + + case JSON_TOKEN_NULL: + case JSON_TOKEN_TRUE: + case JSON_TOKEN_FALSE: + case '-': + case G_TOKEN_INT: + case G_TOKEN_FLOAT: + case G_TOKEN_STRING: + case G_TOKEN_IDENTIFIER: + JSON_NOTE (PARSER, "Statement is a value"); + token = json_scanner_get_next_token (scanner); + return json_parse_value (parser, scanner, token, &priv->root); + + default: + JSON_NOTE (PARSER, "Unknown statement"); + json_scanner_get_next_token (scanner); + priv->error_code = JSON_PARSER_ERROR_INVALID_BAREWORD; + return G_TOKEN_SYMBOL; + } +} + +static void +json_scanner_msg_handler (JsonScanner *scanner, + gchar *message) +{ + JsonParser *parser = scanner->user_data; + JsonParserPrivate *priv = parser->priv; + GError *error = NULL; + + g_set_error (&error, JSON_PARSER_ERROR, + priv->error_code, + /* translators: %s: is the file name, the first %d is the line + * number, the second %d is the position on the line, and %s is + * the error message + */ + _("%s:%d:%d: Parse error: %s"), + priv->is_filename ? priv->filename : "", + scanner->line, + scanner->position, + message); + + parser->priv->last_error = error; + g_signal_emit (parser, parser_signals[ERROR], 0, error); +} + +static JsonScanner * +json_scanner_create (JsonParser *parser) +{ + JsonScanner *scanner; + gint i; + + scanner = json_scanner_new (); + scanner->msg_handler = json_scanner_msg_handler; + scanner->user_data = parser; + + /* XXX: this is eminently stupid, but we use the symbols later on, so + * we cannot move them into JsonScanner without moving a bunch of code + * as well + */ + for (i = 0; i < n_symbols; i++) + { + json_scanner_scope_add_symbol (scanner, 0, + symbol_names + symbols[i].name_offset, + GINT_TO_POINTER (symbols[i].token)); + } + + return scanner; +} + +/** + * json_parser_new: + * + * Creates a new #JsonParser instance. You can use the #JsonParser to + * load a JSON stream from either a file or a buffer and then walk the + * hierarchy using the data types API. + * + * Return value: the newly created #JsonParser. Use g_object_unref() + * to release all the memory it allocates. + */ +JsonParser * +json_parser_new (void) +{ + return g_object_new (JSON_TYPE_PARSER, NULL); +} + +/** + * json_parser_new_immutable: + * + * Creates a new #JsonParser instance with its #JsonParser:immutable property + * set to %TRUE to create immutable output trees. + * + * Since: 1.2 + * Returns: (transfer full): a new #JsonParser + */ +JsonParser * +json_parser_new_immutable (void) +{ + return g_object_new (JSON_TYPE_PARSER, "immutable", TRUE, NULL); +} + +static gboolean +json_parser_load (JsonParser *parser, + const gchar *data, + gsize length, + GError **error) +{ + JsonParserPrivate *priv = parser->priv; + JsonScanner *scanner; + gboolean done; + gboolean retval = TRUE; + gint i; + + json_parser_clear (parser); + + if (!g_utf8_validate (data, length, NULL)) + { + g_set_error_literal (error, JSON_PARSER_ERROR, + JSON_PARSER_ERROR_INVALID_DATA, + _("JSON data must be UTF-8 encoded")); + g_signal_emit (parser, parser_signals[ERROR], 0, *error); + return FALSE; + } + + scanner = json_scanner_create (parser); + json_scanner_input_text (scanner, data, length); + + priv->scanner = scanner; + + g_signal_emit (parser, parser_signals[PARSE_START], 0); + + done = FALSE; + while (!done) + { + if (json_scanner_peek_next_token (scanner) == G_TOKEN_EOF) + done = TRUE; + else + { + guint expected_token; + gint cur_token; + + /* we try to show the expected token, if possible */ + expected_token = json_parse_statement (parser, scanner); + if (expected_token != G_TOKEN_NONE) + { + const gchar *symbol_name; + gchar *msg; + + cur_token = scanner->token; + msg = NULL; + symbol_name = NULL; + + if (scanner->scope_id == 0) + { + if (expected_token > JSON_TOKEN_INVALID && + expected_token < JSON_TOKEN_LAST) + { + for (i = 0; i < n_symbols; i++) + if (symbols[i].token == expected_token) + symbol_name = symbol_names + symbols[i].name_offset; + + if (!msg) + msg = g_strconcat ("e.g. '", symbol_name, "'", NULL); + } + + if (cur_token > JSON_TOKEN_INVALID && + cur_token < JSON_TOKEN_LAST) + { + symbol_name = "???"; + + for (i = 0; i < n_symbols; i++) + if (symbols[i].token == cur_token) + symbol_name = symbol_names + symbols[i].name_offset; + } + } + + /* this will emit the ::error signal via the custom + * message handler we install + */ + json_scanner_unexp_token (scanner, expected_token, + NULL, "value", + symbol_name, msg); + + /* and this will propagate the error we create in the + * same message handler + */ + if (priv->last_error) + { + g_propagate_error (error, priv->last_error); + priv->last_error = NULL; + } + + retval = FALSE; + + g_free (msg); + done = TRUE; + } + } + } + + g_signal_emit (parser, parser_signals[PARSE_END], 0); + + /* remove the scanner */ + json_scanner_destroy (scanner); + priv->scanner = NULL; + priv->current_node = NULL; + + return retval; +} + +/** + * json_parser_load_from_file: + * @parser: a #JsonParser + * @filename: the path for the file to parse + * @error: return location for a #GError, or %NULL + * + * Loads a JSON stream from the content of @filename and parses it. See + * json_parser_load_from_data(). + * + * Return value: %TRUE if the file was successfully loaded and parsed. + * In case of error, @error is set accordingly and %FALSE is returned + */ +gboolean +json_parser_load_from_file (JsonParser *parser, + const gchar *filename, + GError **error) +{ + JsonParserPrivate *priv; + GError *internal_error; + gchar *data; + gsize length; + gboolean retval = TRUE; + + g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + + priv = parser->priv; + + internal_error = NULL; + if (!g_file_get_contents (filename, &data, &length, &internal_error)) + { + g_propagate_error (error, internal_error); + return FALSE; + } + + g_free (priv->filename); + + priv->is_filename = TRUE; + priv->filename = g_strdup (filename); + + if (!json_parser_load (parser, data, length, &internal_error)) + { + g_propagate_error (error, internal_error); + retval = FALSE; + } + + g_free (data); + + return retval; +} + +/** + * json_parser_load_from_data: + * @parser: a #JsonParser + * @data: the buffer to parse + * @length: the length of the buffer, or -1 + * @error: return location for a #GError, or %NULL + * + * Loads a JSON stream from a buffer and parses it. You can call this function + * multiple times with the same #JsonParser object, but the contents of the + * parser will be destroyed each time. + * + * Return value: %TRUE if the buffer was succesfully parser. In case + * of error, @error is set accordingly and %FALSE is returned + */ +gboolean +json_parser_load_from_data (JsonParser *parser, + const gchar *data, + gssize length, + GError **error) +{ + JsonParserPrivate *priv; + GError *internal_error; + gboolean retval = TRUE; + + g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE); + g_return_val_if_fail (data != NULL, FALSE); + + priv = parser->priv; + + if (length < 0) + length = strlen (data); + + priv->is_filename = FALSE; + g_free (priv->filename); + priv->filename = NULL; + + internal_error = NULL; + if (!json_parser_load (parser, data, length, &internal_error)) + { + g_propagate_error (error, internal_error); + retval = FALSE; + } + + return retval; +} + +/** + * json_parser_get_root: + * @parser: a #JsonParser + * + * Retrieves the top level node from the parsed JSON stream. If the parser input + * was an empty string, or if parsing failed, this will be %NULL. It will also + * be %NULL if it has been stolen using json_parser_steal_root(). + * + * Return value: (transfer none) (nullable): the root #JsonNode . The returned + * node is owned by the #JsonParser and should never be modified + * or freed. + */ +JsonNode * +json_parser_get_root (JsonParser *parser) +{ + g_return_val_if_fail (JSON_IS_PARSER (parser), NULL); + + /* Sanity check. */ + g_return_val_if_fail (parser->priv->root == NULL || + !parser->priv->is_immutable || + json_node_is_immutable (parser->priv->root), NULL); + + return parser->priv->root; +} + +/** + * json_parser_steal_root: + * @parser: a #JsonParser + * + * Steals the top level node from the parsed JSON stream. This will be %NULL + * in the same situations as json_parser_get_root() returns %NULL. + * + * Returns: (transfer full) (nullable): the top level #JsonNode + * + * Since: 1.4 + */ +JsonNode * +json_parser_steal_root (JsonParser *parser) +{ + JsonParserPrivate *priv = json_parser_get_instance_private (parser); + + g_return_val_if_fail (JSON_IS_PARSER (parser), NULL); + + /* Sanity check. */ + g_return_val_if_fail (parser->priv->root == NULL || + !parser->priv->is_immutable || + json_node_is_immutable (parser->priv->root), NULL); + + return g_steal_pointer (&priv->root); +} + +/** + * json_parser_get_current_line: + * @parser: a #JsonParser + * + * Retrieves the line currently parsed, starting from 1. + * + * This function has defined behaviour only while parsing; calling this + * function from outside the signal handlers emitted by #JsonParser will + * yield 0. + * + * Return value: the currently parsed line, or 0. + */ +guint +json_parser_get_current_line (JsonParser *parser) +{ + g_return_val_if_fail (JSON_IS_PARSER (parser), 0); + + if (parser->priv->scanner != NULL) + return parser->priv->scanner->line; + + return 0; +} + +/** + * json_parser_get_current_pos: + * @parser: a #JsonParser + * + * Retrieves the current position inside the current line, starting + * from 0. + * + * This function has defined behaviour only while parsing; calling this + * function from outside the signal handlers emitted by #JsonParser will + * yield 0. + * + * Return value: the position in the current line, or 0. + */ +guint +json_parser_get_current_pos (JsonParser *parser) +{ + g_return_val_if_fail (JSON_IS_PARSER (parser), 0); + + if (parser->priv->scanner != NULL) + return parser->priv->scanner->position; + + return 0; +} + +/** + * json_parser_has_assignment: + * @parser: a #JsonParser + * @variable_name: (out) (allow-none) (transfer none): Return location for the variable + * name, or %NULL + * + * A JSON data stream might sometimes contain an assignment, like: + * + * |[ + * var _json_data = { "member_name" : [ ... + * ]| + * + * even though it would technically constitute a violation of the RFC. + * + * #JsonParser will ignore the left hand identifier and parse the right + * hand value of the assignment. #JsonParser will record, though, the + * existence of the assignment in the data stream and the variable name + * used. + * + * Return value: %TRUE if there was an assignment, %FALSE otherwise. If + * @variable_name is not %NULL it will be set to the name of the variable + * used in the assignment. The string is owned by #JsonParser and should + * never be modified or freed. + * + * Since: 0.4 + */ +gboolean +json_parser_has_assignment (JsonParser *parser, + gchar **variable_name) +{ + JsonParserPrivate *priv; + + g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE); + + priv = parser->priv; + + if (priv->has_assignment && variable_name) + *variable_name = priv->variable_name; + + return priv->has_assignment; +} + +#define GET_DATA_BLOCK_SIZE 8192 + +/** + * json_parser_load_from_stream: + * @parser: a #JsonParser + * @stream: an open #GInputStream + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @error: the return location for a #GError, or %NULL + * + * Loads the contents of an input stream and parses them. + * + * If @cancellable is not %NULL, then the operation can be cancelled by + * triggering the @cancellable object from another thread. If the + * operation was cancelled, the error %G_IO_ERROR_CANCELLED will be set + * on the passed @error. + * + * Return value: %TRUE if the data stream was successfully read and + * parsed, and %FALSE otherwise + * + * Since: 0.12 + */ +gboolean +json_parser_load_from_stream (JsonParser *parser, + GInputStream *stream, + GCancellable *cancellable, + GError **error) +{ + GByteArray *content; + gsize pos; + gssize res; + gboolean retval = FALSE; + GError *internal_error; + + g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE); + g_return_val_if_fail (G_IS_INPUT_STREAM (stream), FALSE); + g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), FALSE); + + if (g_cancellable_set_error_if_cancelled (cancellable, error)) + return FALSE; + + content = g_byte_array_new (); + pos = 0; + + g_byte_array_set_size (content, pos + GET_DATA_BLOCK_SIZE + 1); + while ((res = g_input_stream_read (stream, content->data + pos, + GET_DATA_BLOCK_SIZE, + cancellable, error)) > 0) + { + pos += res; + g_byte_array_set_size (content, pos + GET_DATA_BLOCK_SIZE + 1); + } + + if (res < 0) + { + /* error has already been set */ + retval = FALSE; + goto out; + } + + /* zero-terminate the content; we allocated an extra byte for this */ + content->data[pos] = 0; + + internal_error = NULL; + retval = json_parser_load (parser, (const gchar *) content->data, pos, &internal_error); + + if (internal_error != NULL) + g_propagate_error (error, internal_error); + +out: + g_byte_array_free (content, TRUE); + + return retval; +} + +typedef struct { + GInputStream *stream; + GByteArray *content; + gsize pos; +} LoadData; + +static void +load_data_free (gpointer data_) +{ + if (data_ != NULL) + { + LoadData *data = data_; + + g_object_unref (data->stream); + g_byte_array_unref (data->content); + g_free (data); + } +} + +/** + * json_parser_load_from_stream_finish: + * @parser: a #JsonParser + * @result: a #GAsyncResult + * @error: the return location for a #GError or %NULL + * + * Finishes an asynchronous stream loading started with + * json_parser_load_from_stream_async(). + * + * Return value: %TRUE if the content of the stream was successfully retrieves + * and parsed, and %FALSE otherwise. In case of error, the #GError will be + * filled accordingly. + * + * Since: 0.12 + */ +gboolean +json_parser_load_from_stream_finish (JsonParser *parser, + GAsyncResult *result, + GError **error) +{ + gboolean res; + + g_return_val_if_fail (JSON_IS_PARSER (parser), FALSE); + g_return_val_if_fail (g_task_is_valid (result, parser), FALSE); + + res = g_task_propagate_boolean (G_TASK (result), error); + if (res) + { + LoadData *data = g_task_get_task_data (G_TASK (result)); + GError *internal_error = NULL; + + /* We need to do this inside the finis() function because JsonParser will emit + * signals, and we need to ensure that the signals are emitted in the right + * context; it's easier to do that if we just rely on the async callback being + * called in the right context, even if it means making the finish() function + * necessary to complete the async operation. + */ + res = json_parser_load (parser, (const gchar *) data->content->data, data->pos, &internal_error); + if (internal_error != NULL) + g_propagate_error (error, internal_error); + } + + return res; +} + +static void +read_from_stream (GTask *task, + gpointer source_obj, + gpointer task_data, + GCancellable *cancellable) +{ + LoadData *data = task_data; + GError *error = NULL; + gssize res; + + data->pos = 0; + g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1); + while ((res = g_input_stream_read (data->stream, + data->content->data + data->pos, + GET_DATA_BLOCK_SIZE, + cancellable, &error)) > 0) + { + data->pos += res; + g_byte_array_set_size (data->content, data->pos + GET_DATA_BLOCK_SIZE + 1); + } + + if (res < 0) + { + g_task_return_error (task, error); + return; + } + + /* zero-terminate the content; we allocated an extra byte for this */ + data->content->data[data->pos] = 0; + g_task_return_boolean (task, TRUE); +} + +/** + * json_parser_load_from_stream_async: + * @parser: a #JsonParser + * @stream: a #GInputStream + * @cancellable: (allow-none): a #GCancellable, or %NULL + * @callback: a #GAsyncReadyCallback to call when the request is satisfied + * @user_data: the data to pass to @callback + * + * Asynchronously reads the contents of @stream. + * + * For more details, see json_parser_load_from_stream() which is the + * synchronous version of this call. + * + * When the operation is finished, @callback will be called. You should + * then call json_parser_load_from_stream_finish() to get the result + * of the operation. + * + * Since: 0.12 + */ +void +json_parser_load_from_stream_async (JsonParser *parser, + GInputStream *stream, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data) +{ + LoadData *data; + GTask *task; + + g_return_if_fail (JSON_IS_PARSER (parser)); + g_return_if_fail (G_IS_INPUT_STREAM (stream)); + g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable)); + + data = g_new (LoadData, 1); + data->stream = g_object_ref (stream); + data->content = g_byte_array_new (); + data->pos = 0; + + task = g_task_new (parser, cancellable, callback, user_data); + g_task_set_task_data (task, data, load_data_free); + + g_task_run_in_thread (task, read_from_stream); + g_object_unref (task); +} diff --git a/json-glib/json-parser.h b/json-glib/json-parser.h new file mode 100644 index 0000000..1470fbf --- /dev/null +++ b/json-glib/json-parser.h @@ -0,0 +1,196 @@ +/* json-parser.h - JSON streams parser + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_PARSER_H__ +#define __JSON_PARSER_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +#define JSON_TYPE_PARSER (json_parser_get_type ()) +#define JSON_PARSER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_PARSER, JsonParser)) +#define JSON_IS_PARSER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_PARSER)) +#define JSON_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), JSON_TYPE_PARSER, JsonParserClass)) +#define JSON_IS_PARSER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), JSON_TYPE_PARSER)) +#define JSON_PARSER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), JSON_TYPE_PARSER, JsonParserClass)) + +#define JSON_PARSER_ERROR (json_parser_error_quark ()) + +typedef struct _JsonParser JsonParser; +typedef struct _JsonParserPrivate JsonParserPrivate; +typedef struct _JsonParserClass JsonParserClass; + +/** + * JsonParserError: + * @JSON_PARSER_ERROR_PARSE: parse error + * @JSON_PARSER_ERROR_TRAILING_COMMA: unexpected trailing comma + * @JSON_PARSER_ERROR_MISSING_COMMA: expected comma + * @JSON_PARSER_ERROR_MISSING_COLON: expected colon + * @JSON_PARSER_ERROR_INVALID_BAREWORD: invalid bareword + * @JSON_PARSER_ERROR_EMPTY_MEMBER_NAME: empty member name (Since: 0.16) + * @JSON_PARSER_ERROR_INVALID_DATA: invalid data (Since: 0.18) + * @JSON_PARSER_ERROR_UNKNOWN: unknown error + * + * Error enumeration for #JsonParser + * + * This enumeration can be extended at later date + */ +typedef enum { + JSON_PARSER_ERROR_PARSE, + JSON_PARSER_ERROR_TRAILING_COMMA, + JSON_PARSER_ERROR_MISSING_COMMA, + JSON_PARSER_ERROR_MISSING_COLON, + JSON_PARSER_ERROR_INVALID_BAREWORD, + JSON_PARSER_ERROR_EMPTY_MEMBER_NAME, + JSON_PARSER_ERROR_INVALID_DATA, + + JSON_PARSER_ERROR_UNKNOWN +} JsonParserError; + +/** + * JsonParser: + * + * JSON data streams parser. The contents of the #JsonParser structure are + * private and should only be accessed via the provided API. + */ +struct _JsonParser +{ + /*< private >*/ + GObject parent_instance; + + JsonParserPrivate *priv; +}; + +/** + * JsonParserClass: + * @parse_start: class handler for the JsonParser::parse-start signal + * @object_start: class handler for the JsonParser::object-start signal + * @object_member: class handler for the JsonParser::object-member signal + * @object_end: class handler for the JsonParser::object-end signal + * @array_start: class handler for the JsonParser::array-start signal + * @array_element: class handler for the JsonParser::array-element signal + * @array_end: class handler for the JsonParser::array-end signal + * @parse_end: class handler for the JsonParser::parse-end signal + * @error: class handler for the JsonParser::error signal + * + * #JsonParser class. + */ +struct _JsonParserClass +{ + /*< private >*/ + GObjectClass parent_class; + + /*< public >*/ + void (* parse_start) (JsonParser *parser); + + void (* object_start) (JsonParser *parser); + void (* object_member) (JsonParser *parser, + JsonObject *object, + const gchar *member_name); + void (* object_end) (JsonParser *parser, + JsonObject *object); + + void (* array_start) (JsonParser *parser); + void (* array_element) (JsonParser *parser, + JsonArray *array, + gint index_); + void (* array_end) (JsonParser *parser, + JsonArray *array); + + void (* parse_end) (JsonParser *parser); + + void (* error) (JsonParser *parser, + const GError *error); + + /*< private >*/ + /* padding for future expansion */ + void (* _json_reserved1) (void); + void (* _json_reserved2) (void); + void (* _json_reserved3) (void); + void (* _json_reserved4) (void); + void (* _json_reserved5) (void); + void (* _json_reserved6) (void); + void (* _json_reserved7) (void); + void (* _json_reserved8) (void); +}; + +JSON_AVAILABLE_IN_1_0 +GQuark json_parser_error_quark (void); +JSON_AVAILABLE_IN_1_0 +GType json_parser_get_type (void) G_GNUC_CONST; + +JSON_AVAILABLE_IN_1_0 +JsonParser *json_parser_new (void); +JSON_AVAILABLE_IN_1_2 +JsonParser *json_parser_new_immutable (void); +JSON_AVAILABLE_IN_1_0 +gboolean json_parser_load_from_file (JsonParser *parser, + const gchar *filename, + GError **error); +JSON_AVAILABLE_IN_1_0 +gboolean json_parser_load_from_data (JsonParser *parser, + const gchar *data, + gssize length, + GError **error); +JSON_AVAILABLE_IN_1_0 +gboolean json_parser_load_from_stream (JsonParser *parser, + GInputStream *stream, + GCancellable *cancellable, + GError **error); +JSON_AVAILABLE_IN_1_0 +void json_parser_load_from_stream_async (JsonParser *parser, + GInputStream *stream, + GCancellable *cancellable, + GAsyncReadyCallback callback, + gpointer user_data); +JSON_AVAILABLE_IN_1_0 +gboolean json_parser_load_from_stream_finish (JsonParser *parser, + GAsyncResult *result, + GError **error); + +JSON_AVAILABLE_IN_1_0 +JsonNode * json_parser_get_root (JsonParser *parser); +JSON_AVAILABLE_IN_1_4 +JsonNode * json_parser_steal_root (JsonParser *parser); + +JSON_AVAILABLE_IN_1_0 +guint json_parser_get_current_line (JsonParser *parser); +JSON_AVAILABLE_IN_1_0 +guint json_parser_get_current_pos (JsonParser *parser); +JSON_AVAILABLE_IN_1_0 +gboolean json_parser_has_assignment (JsonParser *parser, + gchar **variable_name); + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonParser, g_object_unref) +#endif + +G_END_DECLS + +#endif /* __JSON_PARSER_H__ */ diff --git a/json-glib/json-path.c b/json-glib/json-path.c new file mode 100644 index 0000000..fe6e7b1 --- /dev/null +++ b/json-glib/json-path.c @@ -0,0 +1,1001 @@ +/* json-path.h - JSONPath implementation + * + * This file is part of JSON-GLib + * Copyright © 2011 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +/** + * SECTION:json-path + * @Title: JsonPath + * @short_description: JSONPath implementation + * + * #JsonPath is a simple class implementing the JSONPath syntax for extracting + * data out of a JSON tree. While the semantics of the JSONPath expressions are + * heavily borrowed by the XPath specification for XML, the syntax follows the + * ECMAScript origins of JSON. + * + * Once a #JsonPath instance has been created, it has to compile a JSONPath + * expression using json_path_compile() before being able to match it to a + * JSON tree; the same #JsonPath instance can be used to match multiple JSON + * trees. It it also possible to compile a new JSONPath expression using the + * same #JsonPath instance; the previous expression will be discarded only if + * the compilation of the new expression is successful. + * + * The simple convenience function json_path_query() can be used for one-off + * matching. + * + * ## Syntax of the JSONPath expressions ## + * + * A JSONPath expression is composed by path indices and operators. + * Each path index can either be a member name or an element index inside + * a JSON tree. A JSONPath expression must start with the '$' operator; each + * path index is separated using either the dot notation or the bracket + * notation, e.g.: + * + * |[ + * // dot notation + * $.store.book[0].title + * + * // bracket notation + * $['store']['book'][0]['title'] + * ]| + * + * The available operators are: + * + * * Root node + * The `$` character represents the root node of the JSON tree, and + * matches the entire document. + * + * * Child nodes can either be matched using `.` or `[]`. For instance, + * both `$.store.book` and `$['store']['book']` match the contents of + * the book member of the store object. + * + * * Child nodes can be reached without specifying the whole tree structure + * through the recursive descent operator, or `..`. For instance, + * `$..author` matches all author member in every object. + * + * * Child nodes can grouped through the wildcard operator, or `*`. For + * instance, `$.store.book[*].author` matches all author members of any + * object element contained in the book array of the store object. + * + * * Element nodes can be accessed using their index (starting from zero) + * in the subscript operator `[]`. For instance, `$.store.book[0]` matches + * the first element of the book array of the store object. + * + * * Subsets of element nodes can be accessed using the set notation + * operator `[i,j,...]`. For instance, `$.store.book[0,2]` matches the + * elements 0 and 2 (the first and third) of the book array of the store + * object. + * + * * Slices of element nodes can be accessed using the slice notation + * operation `[start:end:step]`. If start is omitted, the starting index + * of the slice is implied to be zero; if end is omitted, the ending index + * of the slice is implied to be the length of the array; if step is + * omitted, the step of the slice is implied to be 1. For instance, + * `$.store.book[:2]` matches the first two elements of the book array + * of the store object. + * + * More information about JSONPath is available on Stefan Gössner's + * [JSONPath website](http://goessner.net/articles/JsonPath/). + * + * ## Example of JSONPath matches + * The following example shows some of the results of using #JsonPath + * on a JSON tree. We use the following JSON description of a bookstore: + * + * |[ + * { "store": { + * "book": [ + * { "category": "reference", "author": "Nigel Rees", + * "title": "Sayings of the Century", "price": "8.95" }, + * { "category": "fiction", "author": "Evelyn Waugh", + * "title": "Sword of Honour", "price": "12.99" }, + * { "category": "fiction", "author": "Herman Melville", + * "title": "Moby Dick", "isbn": "0-553-21311-3", + * "price": "8.99" }, + * { "category": "fiction", "author": "J. R. R. Tolkien", + * "title": "The Lord of the Rings", "isbn": "0-395-19395-8", + * "price": "22.99" } + * ], + * "bicycle": { "color": "red", "price": "19.95" } + * } + * } + * ]| + * + * We can parse the JSON using #JsonParser: + * + * |[ + * JsonParser *parser = json_parser_new (); + * json_parser_load_from_data (parser, json_data, -1, NULL); + * ]| + * + * If we run the following code: + * + * |[ + * JsonNode *result; + * JsonPath *path = json_path_new (); + * json_path_compile (path, "$.store..author", NULL); + * result = json_path_match (path, json_parser_get_root (parser)); + * ]| + * + * The result #JsonNode will contain an array with all values of the + * author member of the objects in the JSON tree. If we use a + * #JsonGenerator to convert the #JsonNode to a string and print it: + * + * |[ + * JsonGenerator *generator = json_generator_new (); + * json_generator_set_root (generator, result); + * char *str = json_generator_to_data (generator, NULL); + * g_print ("Results: %s\n", str); + * ]| + * + * The output will be: + * + * |[ + * ["Nigel Rees","Evelyn Waugh","Herman Melville","J. R. R. Tolkien"] + * ]| + * + * #JsonPath is available since JSON-GLib 0.14 + */ + +#include "config.h" + +#include + +#include + +#include "json-path.h" + +#include "json-debug.h" +#include "json-types-private.h" + +typedef enum { + JSON_PATH_NODE_ROOT, + JSON_PATH_NODE_CHILD_MEMBER, + JSON_PATH_NODE_CHILD_ELEMENT, + JSON_PATH_NODE_RECURSIVE_DESCENT, + JSON_PATH_NODE_WILDCARD_MEMBER, + JSON_PATH_NODE_WILDCARD_ELEMENT, + JSON_PATH_NODE_ELEMENT_SET, + JSON_PATH_NODE_ELEMENT_SLICE +} PathNodeType; + +typedef struct _PathNode PathNode; + +struct _JsonPath +{ + GObject parent_instance; + + /* the compiled path */ + GList *nodes; + + guint is_compiled : 1; +}; + +struct _JsonPathClass +{ + GObjectClass parent_class; +}; + +struct _PathNode +{ + PathNodeType node_type; + + union { + /* JSON_PATH_NODE_CHILD_ELEMENT */ + int element_index; + + /* JSON_PATH_NODE_CHILD_MEMBER */ + char *member_name; + + /* JSON_PATH_NODE_ELEMENT_SET */ + struct { int n_indices; int *indices; } set; + + /* JSON_PATH_NODE_ELEMENT_SLICE */ + struct { int start, end, step; } slice; + } data; +}; + +G_DEFINE_QUARK (json-path-error-quark, json_path_error) + +G_DEFINE_TYPE (JsonPath, json_path, G_TYPE_OBJECT) + +static void +path_node_free (gpointer data) +{ + if (data != NULL) + { + PathNode *node = data; + + switch (node->node_type) + { + case JSON_PATH_NODE_CHILD_MEMBER: + g_free (node->data.member_name); + break; + + case JSON_PATH_NODE_ELEMENT_SET: + g_free (node->data.set.indices); + break; + + default: + break; + } + + g_free (node); + } +} + +static void +json_path_finalize (GObject *gobject) +{ + JsonPath *self = JSON_PATH (gobject); + + g_list_free_full (self->nodes, path_node_free); + + G_OBJECT_CLASS (json_path_parent_class)->finalize (gobject); +} + +static void +json_path_class_init (JsonPathClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = json_path_finalize; +} + +static void +json_path_init (JsonPath *self) +{ +} + +/** + * json_path_new: + * + * Creates a new #JsonPath instance. + * + * Once created, the #JsonPath object should be used with json_path_compile() + * and json_path_match(). + * + * Return value: (transfer full): the newly created #JsonPath instance. Use + * g_object_unref() to free the allocated resources when done + * + * Since: 0.14 + */ +JsonPath * +json_path_new (void) +{ + return g_object_new (JSON_TYPE_PATH, NULL); +} + +#ifdef JSON_ENABLE_DEBUG +/* used as the function for a g_list_foreach() on a list of PathNode; needs + * a GString as the payload to build the output string + */ +static void +json_path_foreach_print (gpointer data, + gpointer user_data) +{ + PathNode *cur_node = data; + GString *buf = user_data; + + switch (cur_node->node_type) + { + case JSON_PATH_NODE_ROOT: + g_string_append (buf, "data.member_name); + break; + + case JSON_PATH_NODE_CHILD_ELEMENT: + g_string_append_printf (buf, "data.element_index); + break; + + case JSON_PATH_NODE_RECURSIVE_DESCENT: + g_string_append (buf, "data.set.n_indices - 1; i++) + g_string_append_printf (buf, "'%d', ", cur_node->data.set.indices[i]); + + g_string_append_printf (buf, "'%d'", cur_node->data.set.indices[i]); + } + break; + + case JSON_PATH_NODE_ELEMENT_SLICE: + g_string_append_printf (buf, "data.slice.start, + cur_node->data.slice.end, + cur_node->data.slice.step); + break; + + default: + g_string_append (buf, ""); +} +#endif /* JSON_ENABLE_DEBUG */ + +/** + * json_path_compile: + * @path: a #JsonPath + * @expression: a JSONPath expression + * @error: return location for a #GError, or %NULL + * + * Validates and decomposes @expression. + * + * A JSONPath expression must be compiled before calling json_path_match(). + * + * Return value: %TRUE on success; on error, @error will be set with + * the %JSON_PATH_ERROR domain and a code from the #JsonPathError + * enumeration, and %FALSE will be returned + * + * Since: 0.14 + */ +gboolean +json_path_compile (JsonPath *path, + const char *expression, + GError **error) +{ + const char *p, *end_p; + PathNode *root = NULL; + GList *nodes = NULL; + + g_return_val_if_fail (expression != NULL, FALSE); + + p = expression; + + while (*p != '\0') + { + switch (*p) + { + case '$': + { + PathNode *node; + + if (root != NULL) + { + g_set_error_literal (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + _("Only one root node is allowed in a JSONPath expression")); + return FALSE; + } + + if (!(*(p + 1) == '.' || *(p + 1) == '[' || *(p + 1) == '\0')) + { + g_set_error (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + /* translators: the %c is the invalid character */ + _("Root node followed by invalid character “%c”"), + *(p + 1)); + return FALSE; + } + + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_ROOT; + + root = node; + nodes = g_list_prepend (NULL, root); + } + break; + + case '.': + case '[': + { + PathNode *node = NULL; + + if (*p == '.' && *(p + 1) == '.') + { + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_RECURSIVE_DESCENT; + } + else if (*p == '.' && *(p + 1) == '*') + { + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_WILDCARD_MEMBER; + + p += 1; + } + else if (*p == '.') + { + end_p = p + 1; + while (!(*end_p == '.' || *end_p == '[' || *end_p == '\0')) + end_p += 1; + + if (end_p == p + 1) + { + g_set_error_literal (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + _("Missing member name or wildcard after . character")); + goto fail; + } + + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_CHILD_MEMBER; + node->data.member_name = g_strndup (p + 1, end_p - p - 1); + + p = end_p - 1; + } + else if (*p == '[' && *(p + 1) == '\'') + { + if (*(p + 2) == '*' && *(p + 3) == '\'' && *(p + 4) == ']') + { + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_WILDCARD_MEMBER; + + p += 4; + } + else + { + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_CHILD_MEMBER; + + end_p = strchr (p + 2, '\''); + node->data.member_name = g_strndup (p + 2, end_p - p - 2); + + p = end_p + 1; + } + } + else if (*p == '[' && *(p + 1) == '*' && *(p + 2) == ']') + { + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_WILDCARD_ELEMENT; + + p += 1; + } + else if (*p == '[') + { + int sign = 1; + int idx; + + end_p = p + 1; + + if (*end_p == '-') + { + sign = -1; + end_p += 1; + } + + /* slice with missing start */ + if (*end_p == ':') + { + int slice_end = g_ascii_strtoll (end_p + 1, (char **) &end_p, 10) * sign; + int slice_step = 1; + + if (*end_p == ':') + { + end_p += 1; + + if (*end_p == '-') + { + sign = -1; + end_p += 1; + } + else + sign = 1; + + slice_step = g_ascii_strtoll (end_p, (char **) &end_p, 10) * sign; + + if (*end_p != ']') + { + g_set_error (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + _("Malformed slice expression “%*s”"), + (int)(end_p - p), + p + 1); + goto fail; + } + } + + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_ELEMENT_SLICE; + node->data.slice.start = 0; + node->data.slice.end = slice_end; + node->data.slice.step = slice_step; + + nodes = g_list_prepend (nodes, node); + p = end_p; + break; + } + + idx = g_ascii_strtoll (end_p, (char **) &end_p, 10) * sign; + + if (*end_p == ',') + { + GArray *indices = g_array_new (FALSE, TRUE, sizeof (int)); + + g_array_append_val (indices, idx); + + while (*end_p != ']') + { + end_p += 1; + + if (*end_p == '-') + { + sign = -1; + end_p += 1; + } + else + sign = 1; + + idx = g_ascii_strtoll (end_p, (char **) &end_p, 10) * sign; + if (!(*end_p == ',' || *end_p == ']')) + { + g_array_unref (indices); + g_set_error (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + _("Invalid set definition “%*s”"), + (int)(end_p - p), + p + 1); + goto fail; + } + + g_array_append_val (indices, idx); + } + + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_ELEMENT_SET; + node->data.set.n_indices = indices->len; + node->data.set.indices = (int *) g_array_free (indices, FALSE); + nodes = g_list_prepend (nodes, node); + p = end_p; + break; + } + else if (*end_p == ':') + { + int slice_start = idx; + int slice_end = 0; + int slice_step = 1; + + end_p += 1; + + if (*end_p == '-') + { + sign = -1; + end_p += 1; + } + else + sign = 1; + + slice_end = g_ascii_strtoll (end_p, (char **) &end_p, 10) * sign; + if (*end_p == ':') + { + end_p += 1; + + if (*end_p == '-') + { + sign = -1; + end_p += 1; + } + else + sign = 1; + + slice_step = g_ascii_strtoll (end_p + 1, (char **) &end_p, 10) * sign; + } + + if (*end_p != ']') + { + g_set_error (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + _("Invalid slice definition “%*s”"), + (int)(end_p - p), + p + 1); + goto fail; + } + + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_ELEMENT_SLICE; + node->data.slice.start = slice_start; + node->data.slice.end = slice_end; + node->data.slice.step = slice_step; + nodes = g_list_prepend (nodes, node); + p = end_p; + break; + } + else if (*end_p == ']') + { + node = g_new0 (PathNode, 1); + node->node_type = JSON_PATH_NODE_CHILD_ELEMENT; + node->data.element_index = idx; + nodes = g_list_prepend (nodes, node); + p = end_p; + break; + } + else + { + g_set_error (error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + _("Invalid array index definition “%*s”"), + (int)(end_p - p), + p + 1); + goto fail; + } + } + else + break; + + if (node != NULL) + nodes = g_list_prepend (nodes, node); + } + break; + + default: + if (nodes == NULL) + { + g_set_error(error, JSON_PATH_ERROR, + JSON_PATH_ERROR_INVALID_QUERY, + _("Invalid first character “%c”"), + *p); + return FALSE; + } + break; + } + + p += 1; + } + + nodes = g_list_reverse (nodes); + +#ifdef JSON_ENABLE_DEBUG + if (JSON_HAS_DEBUG (PATH)) + { + GString *buf = g_string_new (NULL); + + g_list_foreach (nodes, json_path_foreach_print, buf); + + g_message ("[PATH] " G_STRLOC ": expression '%s' => '%s'", expression, buf->str); + g_string_free (buf, TRUE); + } +#endif /* JSON_ENABLE_DEBUG */ + + g_list_free_full (path->nodes, path_node_free); + + path->nodes = nodes; + path->is_compiled = (path->nodes != NULL); + + return path->nodes != NULL; + +fail: + g_list_free_full (nodes, path_node_free); + + return FALSE; +} + +static void +walk_path_node (GList *path, + JsonNode *root, + JsonArray *results) +{ + PathNode *node = path->data; + + switch (node->node_type) + { + case JSON_PATH_NODE_ROOT: + if (path->next != NULL) + walk_path_node (path->next, root, results); + else + json_array_add_element (results, json_node_copy (root)); + break; + + case JSON_PATH_NODE_CHILD_MEMBER: + if (JSON_NODE_HOLDS_OBJECT (root)) + { + JsonObject *object = json_node_get_object (root); + + if (json_object_has_member (object, node->data.member_name)) + { + JsonNode *member = json_object_get_member (object, node->data.member_name); + + if (path->next == NULL) + { + JSON_NOTE (PATH, "end of path at member '%s'", node->data.member_name); + json_array_add_element (results, json_node_copy (member)); + } + else + walk_path_node (path->next, member, results); + } + } + break; + + case JSON_PATH_NODE_CHILD_ELEMENT: + if (JSON_NODE_HOLDS_ARRAY (root)) + { + JsonArray *array = json_node_get_array (root); + + if (json_array_get_length (array) >= node->data.element_index) + { + JsonNode *element = json_array_get_element (array, node->data.element_index); + + if (path->next == NULL) + { + JSON_NOTE (PATH, "end of path at element '%d'", node->data.element_index); + json_array_add_element (results, json_node_copy (element)); + } + else + walk_path_node (path->next, element, results); + } + } + break; + + case JSON_PATH_NODE_RECURSIVE_DESCENT: + { + PathNode *tmp = path->next->data; + + switch (json_node_get_node_type (root)) + { + case JSON_NODE_OBJECT: + { + JsonObject *object = json_node_get_object (root); + GQueue *members = json_object_get_members_internal (object); + GList *l; + + for (l = members->head; l != NULL; l = l->next) + { + JsonNode *m = json_object_get_member (object, l->data); + + if (tmp->node_type == JSON_PATH_NODE_CHILD_MEMBER && + strcmp (tmp->data.member_name, l->data) == 0) + { + JSON_NOTE (PATH, "entering '%s'", tmp->data.member_name); + walk_path_node (path->next, root, results); + } + else + { + JSON_NOTE (PATH, "recursing into '%s'", (char *) l->data); + walk_path_node (path, m, results); + } + } + } + break; + + case JSON_NODE_ARRAY: + { + JsonArray *array = json_node_get_array (root); + GList *members, *l; + int i; + + members = json_array_get_elements (array); + for (l = members, i = 0; l != NULL; l = l->next, i += 1) + { + JsonNode *m = l->data; + + if (tmp->node_type == JSON_PATH_NODE_CHILD_ELEMENT && + tmp->data.element_index == i) + { + JSON_NOTE (PATH, "entering '%d'", tmp->data.element_index); + walk_path_node (path->next, root, results); + } + else + { + JSON_NOTE (PATH, "recursing into '%d'", i); + walk_path_node (path, m, results); + } + } + g_list_free (members); + } + break; + + default: + break; + } + } + break; + + case JSON_PATH_NODE_WILDCARD_MEMBER: + if (JSON_NODE_HOLDS_OBJECT (root)) + { + JsonObject *object = json_node_get_object (root); + GQueue *members = json_object_get_members_internal (object); + GList *l; + + for (l = members->head; l != NULL; l = l->next) + { + JsonNode *member = json_object_get_member (object, l->data); + + if (path->next != NULL) + walk_path_node (path->next, member, results); + else + { + JSON_NOTE (PATH, "glob match member '%s'", (char *) l->data); + json_array_add_element (results, json_node_copy (member)); + } + } + } + else + json_array_add_element (results, json_node_copy (root)); + break; + + case JSON_PATH_NODE_WILDCARD_ELEMENT: + if (JSON_NODE_HOLDS_ARRAY (root)) + { + JsonArray *array = json_node_get_array (root); + GList *elements, *l; + int i; + + elements = json_array_get_elements (array); + for (l = elements, i = 0; l != NULL; l = l->next, i += 1) + { + JsonNode *element = l->data; + + if (path->next != NULL) + walk_path_node (path->next, element, results); + else + { + JSON_NOTE (PATH, "glob match element '%d'", i); + json_array_add_element (results, json_node_copy (element)); + } + } + g_list_free (elements); + } + else + json_array_add_element (results, json_node_copy (root)); + break; + + case JSON_PATH_NODE_ELEMENT_SET: + if (JSON_NODE_HOLDS_ARRAY (root)) + { + JsonArray *array = json_node_get_array (root); + int i; + + for (i = 0; i < node->data.set.n_indices; i += 1) + { + int idx = node->data.set.indices[i]; + JsonNode *element = json_array_get_element (array, idx); + + if (path->next != NULL) + walk_path_node (path->next, element, results); + else + { + JSON_NOTE (PATH, "set element '%d'", idx); + json_array_add_element (results, json_node_copy (element)); + } + } + } + break; + + case JSON_PATH_NODE_ELEMENT_SLICE: + if (JSON_NODE_HOLDS_ARRAY (root)) + { + JsonArray *array = json_node_get_array (root); + int i, start, end; + + if (node->data.slice.start < 0) + { + start = json_array_get_length (array) + + node->data.slice.start; + + end = json_array_get_length (array) + + node->data.slice.end; + } + else + { + start = node->data.slice.start; + end = node->data.slice.end; + } + + for (i = start; i < end; i += node->data.slice.step) + { + JsonNode *element = json_array_get_element (array, i); + + if (path->next != NULL) + walk_path_node (path->next, element, results); + else + { + JSON_NOTE (PATH, "slice element '%d'", i); + json_array_add_element (results, json_node_copy (element)); + } + } + } + break; + + default: + break; + } +} + +/** + * json_path_match: + * @path: a compiled #JsonPath + * @root: a #JsonNode + * + * Matches the JSON tree pointed by @root using the expression compiled + * into the #JsonPath. + * + * The matching #JsonNodes will be copied into a #JsonArray and + * returned wrapped in a #JsonNode. + * + * Return value: (transfer full): a newly-created #JsonNode of type + * %JSON_NODE_ARRAY containing an array of matching #JsonNodes. + * Use json_node_unref() when done + * + * Since: 0.14 + */ +JsonNode * +json_path_match (JsonPath *path, + JsonNode *root) +{ + JsonArray *results; + JsonNode *retval; + + g_return_val_if_fail (JSON_IS_PATH (path), NULL); + g_return_val_if_fail (path->is_compiled, NULL); + g_return_val_if_fail (root != NULL, NULL); + + results = json_array_new (); + + walk_path_node (path->nodes, root, results); + + retval = json_node_new (JSON_NODE_ARRAY); + json_node_take_array (retval, results); + + return retval; +} + +/** + * json_path_query: + * @expression: a JSONPath expression + * @root: the root of a JSON tree + * @error: return location for a #GError, or %NULL + * + * Queries a JSON tree using a JSONPath expression. + * + * This function is a simple wrapper around json_path_new(), + * json_path_compile() and json_path_match(). It implicitly + * creates a #JsonPath instance, compiles @expression and + * matches it against the JSON tree pointed by @root. + * + * Return value: (transfer full): a newly-created #JsonNode of type + * %JSON_NODE_ARRAY containing an array of matching #JsonNodes. + * Use json_node_unref() when done + * + * Since: 0.14 + */ +JsonNode * +json_path_query (const char *expression, + JsonNode *root, + GError **error) +{ + JsonPath *path = json_path_new (); + JsonNode *retval; + + if (!json_path_compile (path, expression, error)) + { + g_object_unref (path); + return NULL; + } + + retval = json_path_match (path, root); + + g_object_unref (path); + + return retval; +} diff --git a/json-glib/json-path.h b/json-glib/json-path.h new file mode 100644 index 0000000..3c3ddf0 --- /dev/null +++ b/json-glib/json-path.h @@ -0,0 +1,106 @@ +/* json-path.h - JSONPath implementation + * + * This file is part of JSON-GLib + * Copyright © 2011 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_PATH_H__ +#define __JSON_PATH_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define JSON_TYPE_PATH (json_path_get_type ()) +#define JSON_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_PATH, JsonPath)) +#define JSON_IS_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_PATH)) + +/** + * JSON_PATH_ERROR: + * + * Error domain for #JsonPath errors + * + * Since: 0.14 + */ +#define JSON_PATH_ERROR (json_path_error_quark ()) + +/** + * JsonPathError: + * @JSON_PATH_ERROR_INVALID_QUERY: Invalid query + * + * Error code enumeration for the %JSON_PATH_ERROR domain. + * + * Since: 0.14 + */ +typedef enum { + JSON_PATH_ERROR_INVALID_QUERY +} JsonPathError; + +/** + * JsonPath: + * + * The `JsonPath` structure is an opaque object whose members cannot be + * directly accessed except through the provided API. + * + * Since: 0.14 + */ +typedef struct _JsonPath JsonPath; + +/** + * JsonPathClass: + * + * The `JsonPathClass` structure is an opaque object class whose members + * cannot be directly accessed. + * + * Since: 0.14 + */ +typedef struct _JsonPathClass JsonPathClass; + +JSON_AVAILABLE_IN_1_0 +GType json_path_get_type (void) G_GNUC_CONST; +JSON_AVAILABLE_IN_1_0 +GQuark json_path_error_quark (void); + +JSON_AVAILABLE_IN_1_0 +JsonPath * json_path_new (void); + +JSON_AVAILABLE_IN_1_0 +gboolean json_path_compile (JsonPath *path, + const char *expression, + GError **error); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_path_match (JsonPath *path, + JsonNode *root); + +JSON_AVAILABLE_IN_1_0 +JsonNode * json_path_query (const char *expression, + JsonNode *root, + GError **error); + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonPath, g_object_unref) +#endif + +G_END_DECLS + +#endif /* __JSON_PATH_H__ */ diff --git a/json-glib/json-reader.c b/json-glib/json-reader.c new file mode 100644 index 0000000..f371dd9 --- /dev/null +++ b/json-glib/json-reader.c @@ -0,0 +1,1067 @@ +/* json-reader.h - JSON cursor parser + * + * This file is part of JSON-GLib + * Copyright (C) 2010 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +/** + * SECTION:json-reader + * @Title: JsonReader + * @short_description: A cursor-based parser + * + * #JsonReader provides a simple, cursor-based API for parsing a JSON DOM. It + * is similar, in spirit, to the XML Reader API. + * + * In case of error, #JsonReader will be set in an error state; all subsequent + * calls will simply be ignored until a function that resets the error state is + * called, e.g.: + * + * |[ + * // ask for the 7th element; if the element does not exist, the + * // reader will be put in an error state + * json_reader_read_element (reader, 6); + * + * // in case of error, this will return NULL, otherwise it will + * // return the value of the element + * str = json_reader_get_string_value (value); + * + * // this function resets the error state if any was set + * json_reader_end_element (reader); + * ]| + * + * If you want to detect the error state as soon as possible, you can use + * json_reader_get_error(): + * + * |[ + * // like the example above, but in this case we print out the + * // error immediately + * if (!json_reader_read_element (reader, 6)) + * { + * const GError *error = json_reader_get_error (reader); + * g_print ("Unable to read the element: %s", error->message); + * } + * ]| + * + * #JsonReader is available since JSON-GLib 0.12. + */ + +#include "config.h" + +#include + +#include + +#include "json-reader.h" +#include "json-types-private.h" +#include "json-debug.h" + +#define json_reader_return_if_error_set(r) G_STMT_START { \ + if (((JsonReader *) (r))->priv->error != NULL) \ + return; } G_STMT_END + +#define json_reader_return_val_if_error_set(r,v) G_STMT_START { \ + if (((JsonReader *) (r))->priv->error != NULL) \ + return (v); } G_STMT_END + +struct _JsonReaderPrivate +{ + JsonNode *root; + + JsonNode *current_node; + JsonNode *previous_node; + + /* Stack of member names. */ + GPtrArray *members; + + GError *error; +}; + +enum +{ + PROP_0, + + PROP_ROOT, + + PROP_LAST +}; + +static GParamSpec *reader_properties[PROP_LAST] = { NULL, }; + +G_DEFINE_TYPE_WITH_PRIVATE (JsonReader, json_reader, G_TYPE_OBJECT) + +G_DEFINE_QUARK (json-reader-error-quark, json_reader_error) + +static void +json_reader_finalize (GObject *gobject) +{ + JsonReaderPrivate *priv = JSON_READER (gobject)->priv; + + if (priv->root != NULL) + json_node_unref (priv->root); + + if (priv->error != NULL) + g_clear_error (&priv->error); + + if (priv->members != NULL) + g_ptr_array_unref (priv->members); + + G_OBJECT_CLASS (json_reader_parent_class)->finalize (gobject); +} + +static void +json_reader_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_ROOT: + json_reader_set_root (JSON_READER (gobject), g_value_get_boxed (value)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +json_reader_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_ROOT: + g_value_set_boxed (value, JSON_READER (gobject)->priv->root); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + +static void +json_reader_class_init (JsonReaderClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + /** + * JsonReader:root: + * + * The root of the JSON tree that the #JsonReader should read. + * + * Since: 0.12 + */ + reader_properties[PROP_ROOT] = + g_param_spec_boxed ("root", + "Root Node", + "The root of the tree to read", + JSON_TYPE_NODE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + gobject_class->finalize = json_reader_finalize; + gobject_class->set_property = json_reader_set_property; + gobject_class->get_property = json_reader_get_property; + g_object_class_install_properties (gobject_class, PROP_LAST, reader_properties); +} + +static void +json_reader_init (JsonReader *self) +{ + self->priv = json_reader_get_instance_private (self); + self->priv->members = g_ptr_array_new_with_free_func (g_free); +} + +/** + * json_reader_new: + * @node: (allow-none): a #JsonNode, or %NULL + * + * Creates a new #JsonReader. You can use this object to read the contents of + * the JSON tree starting from @node + * + * Return value: the newly created #JsonReader. Use g_object_unref() to + * release the allocated resources when done + * + * Since: 0.12 + */ +JsonReader * +json_reader_new (JsonNode *node) +{ + return g_object_new (JSON_TYPE_READER, "root", node, NULL); +} + +/* + * json_reader_unset_error: + * @reader: a #JsonReader + * + * Unsets the error state of @reader, if set + * + * Return value: TRUE if an error was set. + */ +static inline gboolean +json_reader_unset_error (JsonReader *reader) +{ + if (reader->priv->error != NULL) + { + g_clear_error (&(reader->priv->error)); + return TRUE; + } + return FALSE; +} + +/** + * json_reader_set_root: + * @reader: a #JsonReader + * @root: (allow-none): a #JsonNode + * + * Sets the root #JsonNode to be read by @reader. The @reader will take + * a copy of @root + * + * If another #JsonNode is currently set as root, it will be replaced. + * + * Since: 0.12 + */ +void +json_reader_set_root (JsonReader *reader, + JsonNode *root) +{ + JsonReaderPrivate *priv; + + g_return_if_fail (JSON_IS_READER (reader)); + + priv = reader->priv; + + if (priv->root == root) + return; + + if (priv->root != NULL) + { + json_node_unref (priv->root); + priv->root = NULL; + priv->current_node = NULL; + priv->previous_node = NULL; + } + + if (root != NULL) + { + priv->root = json_node_copy (root); + priv->current_node = priv->root; + priv->previous_node = NULL; + } + + g_object_notify_by_pspec (G_OBJECT (reader), reader_properties[PROP_ROOT]); +} + +/* + * json_reader_ser_error: + * @reader: a #JsonReader + * @error_code: the #JsonReaderError code for the error + * @error_fmt: format string + * @Varargs: list of arguments for the @error_fmt string + * + * Sets the error state of @reader using the given error code + * and string + * + * Return value: %FALSE, to be used to return immediately from + * the caller function + */ +G_GNUC_PRINTF (3, 4) +static gboolean +json_reader_set_error (JsonReader *reader, + JsonReaderError error_code, + const gchar *error_fmt, + ...) +{ + JsonReaderPrivate *priv = reader->priv; + va_list args; + gchar *error_msg; + + if (priv->error != NULL) + g_clear_error (&priv->error); + + va_start (args, error_fmt); + error_msg = g_strdup_vprintf (error_fmt, args); + va_end (args); + + g_set_error_literal (&priv->error, JSON_READER_ERROR, + error_code, + error_msg); + + g_free (error_msg); + + return FALSE; +} + +/** + * json_reader_get_error: + * @reader: a #JsonReader + * + * Retrieves the #GError currently set on @reader, if the #JsonReader + * is in error state + * + * Return value: (nullable) (transfer none): the pointer to the error, or %NULL + * + * Since: 0.12 + */ +const GError * +json_reader_get_error (JsonReader *reader) +{ + g_return_val_if_fail (JSON_IS_READER (reader), NULL); + + return reader->priv->error; +} + +/** + * json_reader_is_array: + * @reader: a #JsonReader + * + * Checks whether the @reader is currently on an array + * + * Return value: %TRUE if the #JsonReader is on an array, and %FALSE + * otherwise + * + * Since: 0.12 + */ +gboolean +json_reader_is_array (JsonReader *reader) +{ + g_return_val_if_fail (JSON_IS_READER (reader), FALSE); + json_reader_return_val_if_error_set (reader, FALSE); + + if (reader->priv->current_node == NULL) + return FALSE; + + return JSON_NODE_HOLDS_ARRAY (reader->priv->current_node); +} + +/** + * json_reader_is_object: + * @reader: a #JsonReader + * + * Checks whether the @reader is currently on an object + * + * Return value: %TRUE if the #JsonReader is on an object, and %FALSE + * otherwise + * + * Since: 0.12 + */ +gboolean +json_reader_is_object (JsonReader *reader) +{ + g_return_val_if_fail (JSON_IS_READER (reader), FALSE); + json_reader_return_val_if_error_set (reader, FALSE); + + if (reader->priv->current_node == NULL) + return FALSE; + + return JSON_NODE_HOLDS_OBJECT (reader->priv->current_node); +} + +/** + * json_reader_is_value: + * @reader: a #JsonReader + * + * Checks whether the @reader is currently on a value + * + * Return value: %TRUE if the #JsonReader is on a value, and %FALSE + * otherwise + * + * Since: 0.12 + */ +gboolean +json_reader_is_value (JsonReader *reader) +{ + g_return_val_if_fail (JSON_IS_READER (reader), FALSE); + json_reader_return_val_if_error_set (reader, FALSE); + + if (reader->priv->current_node == NULL) + return FALSE; + + return JSON_NODE_HOLDS_VALUE (reader->priv->current_node) || + JSON_NODE_HOLDS_NULL (reader->priv->current_node); +} + +/** + * json_reader_read_element: + * @reader: a #JsonReader + * @index_: the index of the element + * + * Advances the cursor of @reader to the element @index_ of the array + * or the object at the current position. + * + * You can use the json_reader_get_value* family of functions to retrieve + * the value of the element; for instance: + * + * |[ + * json_reader_read_element (reader, 0); + * int_value = json_reader_get_int_value (reader); + * ]| + * + * After reading the value, json_reader_end_element() should be called to + * reposition the cursor inside the #JsonReader, e.g.: + * + * |[ + * json_reader_read_element (reader, 1); + * str_value = json_reader_get_string_value (reader); + * json_reader_end_element (reader); + * + * json_reader_read_element (reader, 2); + * str_value = json_reader_get_string_value (reader); + * json_reader_end_element (reader); + * ]| + * + * If @reader is not currently on an array or an object, or if the @index_ is + * bigger than the size of the array or the object, the #JsonReader will be + * put in an error state until json_reader_end_element() is called. This means + * that if used conditionally, json_reader_end_element() must be called on both + * code paths: + * + * |[ + * if (!json_reader_read_element (reader, 1)) + * { + * json_reader_end_element (reader); + * g_set_error (error, …); + * return FALSE; + * } + * + * str_value = json_reader_get_string_value (reader); + * json_reader_end_element (reader); + * ]| + * + * Return value: %TRUE on success, and %FALSE otherwise + * + * Since: 0.12 + */ +gboolean +json_reader_read_element (JsonReader *reader, + guint index_) +{ + JsonReaderPrivate *priv; + + g_return_val_if_fail (JSON_READER (reader), FALSE); + json_reader_return_val_if_error_set (reader, FALSE); + + priv = reader->priv; + + if (priv->current_node == NULL) + priv->current_node = priv->root; + + if (!(JSON_NODE_HOLDS_ARRAY (priv->current_node) || + JSON_NODE_HOLDS_OBJECT (priv->current_node))) + return json_reader_set_error (reader, JSON_READER_ERROR_NO_ARRAY, + _("The current node is of type “%s”, but " + "an array or an object was expected."), + json_node_type_name (priv->current_node)); + + switch (json_node_get_node_type (priv->current_node)) + { + case JSON_NODE_ARRAY: + { + JsonArray *array = json_node_get_array (priv->current_node); + + if (index_ >= json_array_get_length (array)) + return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX, + _("The index “%d” is greater than the size " + "of the array at the current position."), + index_); + + priv->previous_node = priv->current_node; + priv->current_node = json_array_get_element (array, index_); + } + break; + + case JSON_NODE_OBJECT: + { + JsonObject *object = json_node_get_object (priv->current_node); + GQueue *members; + const gchar *name; + + if (index_ >= json_object_get_size (object)) + return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_INDEX, + _("The index “%d” is greater than the size " + "of the object at the current position."), + index_); + + priv->previous_node = priv->current_node; + + members = json_object_get_members_internal (object); + name = g_queue_peek_nth (members, index_); + + priv->current_node = json_object_get_member (object, name); + g_ptr_array_add (priv->members, g_strdup (name)); + } + break; + + default: + g_assert_not_reached (); + return FALSE; + } + + return TRUE; +} + +/** + * json_reader_end_element: + * @reader: a #JsonReader + * + * Moves the cursor back to the previous node after being positioned + * inside an array + * + * This function resets the error state of @reader, if any was set + * + * Since: 0.12 + */ +void +json_reader_end_element (JsonReader *reader) +{ + JsonReaderPrivate *priv; + JsonNode *tmp; + + g_return_if_fail (JSON_IS_READER (reader)); + + if (json_reader_unset_error (reader)) + return; + + priv = reader->priv; + + if (priv->previous_node != NULL) + tmp = json_node_get_parent (priv->previous_node); + else + tmp = NULL; + + if (json_node_get_node_type (priv->previous_node) == JSON_NODE_OBJECT) + g_ptr_array_remove_index (priv->members, priv->members->len - 1); + + priv->current_node = priv->previous_node; + priv->previous_node = tmp; +} + +/** + * json_reader_count_elements: + * @reader: a #JsonReader + * + * Counts the elements of the current position, if @reader is + * positioned on an array + * + * Return value: the number of elements, or -1. In case of failure + * the #JsonReader is set in an error state + * + * Since: 0.12 + */ +gint +json_reader_count_elements (JsonReader *reader) +{ + JsonReaderPrivate *priv; + + g_return_val_if_fail (JSON_IS_READER (reader), -1); + + priv = reader->priv; + + if (priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return -1; + } + + if (!JSON_NODE_HOLDS_ARRAY (priv->current_node)) + { + json_reader_set_error (reader, JSON_READER_ERROR_NO_ARRAY, + _("The current position holds a “%s” and not an array"), + json_node_type_get_name (JSON_NODE_TYPE (priv->current_node))); + return -1; + } + + return json_array_get_length (json_node_get_array (priv->current_node)); +} + +/** + * json_reader_read_member: + * @reader: a #JsonReader + * @member_name: the name of the member to read + * + * Advances the cursor of @reader to the @member_name of the object at the + * current position. + * + * You can use the json_reader_get_value* family of functions to retrieve + * the value of the member; for instance: + * + * |[ + * json_reader_read_member (reader, "width"); + * width = json_reader_get_int_value (reader); + * ]| + * + * After reading the value, json_reader_end_member() should be called to + * reposition the cursor inside the #JsonReader, e.g.: + * + * |[ + * json_reader_read_member (reader, "author"); + * author = json_reader_get_string_value (reader); + * json_reader_end_member (reader); + * + * json_reader_read_member (reader, "title"); + * title = json_reader_get_string_value (reader); + * json_reader_end_member (reader); + * ]| + * + * If @reader is not currently on an object, or if the @member_name is not + * defined in the object, the #JsonReader will be put in an error state until + * json_reader_end_member() is called. This means that if used conditionally, + * json_reader_end_member() must be called on both code paths: + * + * |[ + * if (!json_reader_read_member (reader, "title")) + * { + * json_reader_end_member (reader); + * g_set_error (error, …); + * return FALSE; + * } + * + * str_value = json_reader_get_string_value (reader); + * json_reader_end_member (reader); + * ]| + * + * Return value: %TRUE on success, and %FALSE otherwise + * + * Since: 0.12 + */ +gboolean +json_reader_read_member (JsonReader *reader, + const gchar *member_name) +{ + JsonReaderPrivate *priv; + JsonObject *object; + + g_return_val_if_fail (JSON_READER (reader), FALSE); + g_return_val_if_fail (member_name != NULL, FALSE); + json_reader_return_val_if_error_set (reader, FALSE); + + priv = reader->priv; + + if (priv->current_node == NULL) + priv->current_node = priv->root; + + if (!JSON_NODE_HOLDS_OBJECT (priv->current_node)) + return json_reader_set_error (reader, JSON_READER_ERROR_NO_OBJECT, + _("The current node is of type “%s”, but " + "an object was expected."), + json_node_type_name (priv->current_node)); + + object = json_node_get_object (priv->current_node); + if (!json_object_has_member (object, member_name)) + return json_reader_set_error (reader, JSON_READER_ERROR_INVALID_MEMBER, + _("The member “%s” is not defined in the " + "object at the current position."), + member_name); + + priv->previous_node = priv->current_node; + priv->current_node = json_object_get_member (object, member_name); + g_ptr_array_add (priv->members, g_strdup (member_name)); + + return TRUE; +} + +/** + * json_reader_end_member: + * @reader: a #JsonReader + * + * Moves the cursor back to the previous node after being positioned + * inside an object + * + * This function resets the error state of @reader, if any was set + * + * Since: 0.12 + */ +void +json_reader_end_member (JsonReader *reader) +{ + JsonReaderPrivate *priv; + JsonNode *tmp; + + g_return_if_fail (JSON_IS_READER (reader)); + + if (json_reader_unset_error (reader)) + return; + + priv = reader->priv; + + if (priv->previous_node != NULL) + tmp = json_node_get_parent (priv->previous_node); + else + tmp = NULL; + + g_ptr_array_remove_index (priv->members, priv->members->len - 1); + + priv->current_node = priv->previous_node; + priv->previous_node = tmp; +} + +/** + * json_reader_list_members: + * @reader: a #JsonReader + * + * Retrieves a list of member names from the current position, if @reader + * is positioned on an object. + * + * Return value: (transfer full): a newly allocated, %NULL-terminated + * array of strings holding the members name. Use g_strfreev() when + * done. + * + * Since: 0.14 + */ +gchar ** +json_reader_list_members (JsonReader *reader) +{ + JsonReaderPrivate *priv; + JsonObject *object; + GQueue *members; + GList *l; + gchar **retval; + gint i; + + g_return_val_if_fail (JSON_IS_READER (reader), NULL); + + priv = reader->priv; + + if (priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return NULL; + } + + if (!JSON_NODE_HOLDS_OBJECT (priv->current_node)) + { + json_reader_set_error (reader, JSON_READER_ERROR_NO_OBJECT, + _("The current position holds a “%s” and not an object"), + json_node_type_get_name (JSON_NODE_TYPE (priv->current_node))); + return NULL; + } + + object = json_node_get_object (priv->current_node); + members = json_object_get_members_internal (object); + + retval = g_new (gchar*, g_queue_get_length (members) + 1); + for (l = members->head, i = 0; l != NULL; l = l->next, i += 1) + retval[i] = g_strdup (l->data); + + retval[i] = NULL; + + return retval; +} + +/** + * json_reader_count_members: + * @reader: a #JsonReader + * + * Counts the members of the current position, if @reader is + * positioned on an object + * + * Return value: the number of members, or -1. In case of failure + * the #JsonReader is set in an error state + * + * Since: 0.12 + */ +gint +json_reader_count_members (JsonReader *reader) +{ + JsonReaderPrivate *priv; + + g_return_val_if_fail (JSON_IS_READER (reader), -1); + + priv = reader->priv; + + if (priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return -1; + } + + if (!JSON_NODE_HOLDS_OBJECT (priv->current_node)) + { + json_reader_set_error (reader, JSON_READER_ERROR_NO_OBJECT, + _("The current position holds a “%s” and not an object"), + json_node_type_get_name (JSON_NODE_TYPE (priv->current_node))); + return -1; + } + + return json_object_get_size (json_node_get_object (priv->current_node)); +} + +/** + * json_reader_get_value: + * @reader: a #JsonReader + * + * Retrieves the #JsonNode of the current position of @reader + * + * Return value: (nullable) (transfer none): a #JsonNode, or %NULL. The + * returned node is owned by the #JsonReader and it should not be + * modified or freed directly + * + * Since: 0.12 + */ +JsonNode * +json_reader_get_value (JsonReader *reader) +{ + JsonNode *node; + + g_return_val_if_fail (JSON_IS_READER (reader), NULL); + json_reader_return_val_if_error_set (reader, NULL); + + if (reader->priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return NULL; + } + + node = reader->priv->current_node; + + if (!JSON_NODE_HOLDS_VALUE (node) && !JSON_NODE_HOLDS_NULL (node)) + { + json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE, + _("The current position holds a “%s” and not a value"), + json_node_type_get_name (JSON_NODE_TYPE (node))); + return NULL; + } + + return reader->priv->current_node; +} + +/** + * json_reader_get_int_value: + * @reader: a #JsonReader + * + * Retrieves the integer value of the current position of @reader + * + * Return value: the integer value + * + * Since: 0.12 + */ +gint64 +json_reader_get_int_value (JsonReader *reader) +{ + JsonNode *node; + + g_return_val_if_fail (JSON_IS_READER (reader), 0); + json_reader_return_val_if_error_set (reader, 0); + + if (reader->priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return 0; + } + + node = reader->priv->current_node; + + if (!JSON_NODE_HOLDS_VALUE (node)) + { + json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE, + _("The current position holds a “%s” and not a value"), + json_node_type_get_name (JSON_NODE_TYPE (node))); + return 0; + } + + return json_node_get_int (reader->priv->current_node); +} + +/** + * json_reader_get_double_value: + * @reader: a #JsonReader + * + * Retrieves the floating point value of the current position of @reader + * + * Return value: the floating point value + * + * Since: 0.12 + */ +gdouble +json_reader_get_double_value (JsonReader *reader) +{ + JsonNode *node; + + g_return_val_if_fail (JSON_IS_READER (reader), 0.0); + json_reader_return_val_if_error_set (reader, 0.0); + + if (reader->priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return 0.0; + } + + node = reader->priv->current_node; + + if (!JSON_NODE_HOLDS_VALUE (node)) + { + json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE, + _("The current position holds a “%s” and not a value"), + json_node_type_get_name (JSON_NODE_TYPE (node))); + return 0.0; + } + + return json_node_get_double (reader->priv->current_node); +} + +/** + * json_reader_get_string_value: + * @reader: a #JsonReader + * + * Retrieves the string value of the current position of @reader + * + * Return value: the string value + * + * Since: 0.12 + */ +const gchar * +json_reader_get_string_value (JsonReader *reader) +{ + JsonNode *node; + + g_return_val_if_fail (JSON_IS_READER (reader), NULL); + json_reader_return_val_if_error_set (reader, NULL); + + if (reader->priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return NULL; + } + + node = reader->priv->current_node; + + if (!JSON_NODE_HOLDS_VALUE (node)) + { + json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE, + _("The current position holds a “%s” and not a value"), + json_node_type_get_name (JSON_NODE_TYPE (node))); + return NULL; + } + + if (json_node_get_value_type (node) != G_TYPE_STRING) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_TYPE, + _("The current position does not hold a string type")); + return NULL; + } + + return json_node_get_string (reader->priv->current_node); +} + +/** + * json_reader_get_boolean_value: + * @reader: a #JsonReader + * + * Retrieves the boolean value of the current position of @reader + * + * Return value: the boolean value + * + * Since: 0.12 + */ +gboolean +json_reader_get_boolean_value (JsonReader *reader) +{ + JsonNode *node; + + g_return_val_if_fail (JSON_IS_READER (reader), FALSE); + json_reader_return_val_if_error_set (reader, FALSE); + + if (reader->priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return FALSE; + } + + node = reader->priv->current_node; + + if (!JSON_NODE_HOLDS_VALUE (node)) + { + json_reader_set_error (reader, JSON_READER_ERROR_NO_VALUE, + _("The current position holds a “%s” and not a value"), + json_node_type_get_name (JSON_NODE_TYPE (node))); + return FALSE; + } + + return json_node_get_boolean (node); +} + +/** + * json_reader_get_null_value: + * @reader: a #JsonReader + * + * Checks whether the value of the current position of @reader is 'null' + * + * Return value: %TRUE if 'null' is set, and %FALSE otherwise + * + * Since: 0.12 + */ +gboolean +json_reader_get_null_value (JsonReader *reader) +{ + g_return_val_if_fail (JSON_IS_READER (reader), FALSE); + json_reader_return_val_if_error_set (reader, FALSE); + + if (reader->priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return FALSE; + } + + return JSON_NODE_HOLDS_NULL (reader->priv->current_node); +} + +/** + * json_reader_get_member_name: + * @reader: a #JsonReader + * + * Retrieves the name of the current member. + * + * Return value: (nullable) (transfer none): the name of the member, or %NULL + * + * Since: 0.14 + */ +const gchar * +json_reader_get_member_name (JsonReader *reader) +{ + g_return_val_if_fail (JSON_IS_READER (reader), NULL); + json_reader_return_val_if_error_set (reader, NULL); + + if (reader->priv->current_node == NULL) + { + json_reader_set_error (reader, JSON_READER_ERROR_INVALID_NODE, + _("No node available at the current position")); + return NULL; + } + + if (reader->priv->members->len == 0) + return NULL; + + return g_ptr_array_index (reader->priv->members, + reader->priv->members->len - 1); +} diff --git a/json-glib/json-reader.h b/json-glib/json-reader.h new file mode 100644 index 0000000..786ed7b --- /dev/null +++ b/json-glib/json-reader.h @@ -0,0 +1,175 @@ +/* json-reader.h - JSON cursor parser + * + * This file is part of JSON-GLib + * Copyright (C) 2010 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_READER_H__ +#define __JSON_READER_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +#define JSON_TYPE_READER (json_reader_get_type ()) +#define JSON_READER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), JSON_TYPE_READER, JsonReader)) +#define JSON_IS_READER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), JSON_TYPE_READER)) +#define JSON_READER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), JSON_TYPE_READER, JsonReaderClass)) +#define JSON_IS_READER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), JSON_TYPE_READER)) +#define JSON_READER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), JSON_TYPE_READER, JsonReaderClass)) + +/** + * JSON_READER_ERROR: + * + * Error domain for #JsonReader errors + * + * Since: 0.12 + */ +#define JSON_READER_ERROR (json_reader_error_quark ()) + +typedef struct _JsonReader JsonReader; +typedef struct _JsonReaderPrivate JsonReaderPrivate; +typedef struct _JsonReaderClass JsonReaderClass; + +/** + * JsonReaderError: + * @JSON_READER_ERROR_NO_ARRAY: No array found at the current position + * @JSON_READER_ERROR_INVALID_INDEX: Index out of bounds + * @JSON_READER_ERROR_NO_OBJECT: No object found at the current position + * @JSON_READER_ERROR_INVALID_MEMBER: Member not found + * @JSON_READER_ERROR_INVALID_NODE: No valid node found at the current position + * @JSON_READER_ERROR_NO_VALUE: The node at the current position does not + * hold a value + * @JSON_READER_ERROR_INVALID_TYPE: The node at the current position does not + * hold a value of the desired type + * + * Error codes enumeration for #JsonReader errors + * + * Since: 0.12 + */ +typedef enum { + JSON_READER_ERROR_NO_ARRAY, + JSON_READER_ERROR_INVALID_INDEX, + JSON_READER_ERROR_NO_OBJECT, + JSON_READER_ERROR_INVALID_MEMBER, + JSON_READER_ERROR_INVALID_NODE, + JSON_READER_ERROR_NO_VALUE, + JSON_READER_ERROR_INVALID_TYPE +} JsonReaderError; + +/** + * JsonReader: + * + * The `JsonReader` structure contains only private data and should + * be accessed using the provided API + * + * Since: 0.12 + */ +struct _JsonReader +{ + /*< private >*/ + GObject parent_instance; + + JsonReaderPrivate *priv; +}; + +/** + * JsonReaderClass: + * + * The `JsonReaderClass` structure contains only private data + * + * Since: 0.12 + */ +struct _JsonReaderClass +{ + /*< private >*/ + GObjectClass parent_class; + + void (*_json_padding0) (void); + void (*_json_padding1) (void); + void (*_json_padding2) (void); + void (*_json_padding3) (void); + void (*_json_padding4) (void); +}; + +JSON_AVAILABLE_IN_1_0 +GQuark json_reader_error_quark (void); +JSON_AVAILABLE_IN_1_0 +GType json_reader_get_type (void) G_GNUC_CONST; + +JSON_AVAILABLE_IN_1_0 +JsonReader * json_reader_new (JsonNode *node); + +JSON_AVAILABLE_IN_1_0 +void json_reader_set_root (JsonReader *reader, + JsonNode *root); + +JSON_AVAILABLE_IN_1_0 +const GError * json_reader_get_error (JsonReader *reader); + +JSON_AVAILABLE_IN_1_0 +gboolean json_reader_is_array (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gboolean json_reader_read_element (JsonReader *reader, + guint index_); +JSON_AVAILABLE_IN_1_0 +void json_reader_end_element (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gint json_reader_count_elements (JsonReader *reader); + +JSON_AVAILABLE_IN_1_0 +gboolean json_reader_is_object (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gboolean json_reader_read_member (JsonReader *reader, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +void json_reader_end_member (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gint json_reader_count_members (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gchar ** json_reader_list_members (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +const gchar * json_reader_get_member_name (JsonReader *reader); + +JSON_AVAILABLE_IN_1_0 +gboolean json_reader_is_value (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_reader_get_value (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gint64 json_reader_get_int_value (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gdouble json_reader_get_double_value (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +const gchar * json_reader_get_string_value (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gboolean json_reader_get_boolean_value (JsonReader *reader); +JSON_AVAILABLE_IN_1_0 +gboolean json_reader_get_null_value (JsonReader *reader); + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonReader, g_object_unref) +#endif + +G_END_DECLS + +#endif /* __JSON_READER_H__ */ diff --git a/json-glib/json-scanner.c b/json-glib/json-scanner.c new file mode 100644 index 0000000..0c9919f --- /dev/null +++ b/json-glib/json-scanner.c @@ -0,0 +1,1543 @@ +/* json-scanner.c: Tokenizer for JSON + * Copyright (C) 2008 OpenedHand + * + * Based on JsonScanner: Flexible lexical scanner for general purpose. + * Copyright (C) 1997, 1998 Tim Janik + * + * Modified by Emmanuele Bassi + * + * 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 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, see . + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +#include "json-scanner.h" + +#ifdef G_OS_WIN32 +#include /* For _read() */ +#endif + +struct _JsonScannerConfig +{ + /* Character sets + */ + gchar *cset_skip_characters; /* default: " \t\n" */ + gchar *cset_identifier_first; + gchar *cset_identifier_nth; + gchar *cpair_comment_single; /* default: "#\n" */ + + /* Should symbol lookup work case sensitive? */ + guint case_sensitive : 1; + + /* Boolean values to be adjusted "on the fly" + * to configure scanning behaviour. + */ + guint skip_comment_multi : 1; /* C like comment */ + guint skip_comment_single : 1; /* single line comment */ + guint scan_comment_multi : 1; /* scan multi line comments? */ + guint scan_identifier : 1; + guint scan_identifier_1char : 1; + guint scan_identifier_NULL : 1; + guint scan_symbols : 1; + guint scan_binary : 1; + guint scan_octal : 1; + guint scan_float : 1; + guint scan_hex : 1; /* `0x0ff0' */ + guint scan_hex_dollar : 1; /* `$0ff0' */ + guint scan_string_sq : 1; /* string: 'anything' */ + guint scan_string_dq : 1; /* string: "\\-escapes!\n" */ + guint numbers_2_int : 1; /* bin, octal, hex => int */ + guint int_2_float : 1; /* int => G_TOKEN_FLOAT? */ + guint identifier_2_string : 1; + guint char_2_token : 1; /* return G_TOKEN_CHAR? */ + guint symbol_2_token : 1; + guint scope_0_fallback : 1; /* try scope 0 on lookups? */ + guint store_int64 : 1; /* use value.v_int64 rather than v_int */ + guint padding_dummy; +}; + +static JsonScannerConfig json_scanner_config_template = +{ + ( " \t\r\n" ) /* cset_skip_characters */, + ( + "_" + G_CSET_a_2_z + G_CSET_A_2_Z + ) /* cset_identifier_first */, + ( + G_CSET_DIGITS + "-_" + G_CSET_a_2_z + G_CSET_A_2_Z + ) /* cset_identifier_nth */, + ( "//\n" ) /* cpair_comment_single */, + TRUE /* case_sensitive */, + TRUE /* skip_comment_multi */, + TRUE /* skip_comment_single */, + FALSE /* scan_comment_multi */, + TRUE /* scan_identifier */, + TRUE /* scan_identifier_1char */, + FALSE /* scan_identifier_NULL */, + TRUE /* scan_symbols */, + TRUE /* scan_binary */, + TRUE /* scan_octal */, + TRUE /* scan_float */, + TRUE /* scan_hex */, + TRUE /* scan_hex_dollar */, + TRUE /* scan_string_sq */, + TRUE /* scan_string_dq */, + TRUE /* numbers_2_int */, + FALSE /* int_2_float */, + FALSE /* identifier_2_string */, + TRUE /* char_2_token */, + TRUE /* symbol_2_token */, + FALSE /* scope_0_fallback */, + TRUE /* store_int64 */ +}; + +/* --- defines --- */ +#define to_lower(c) ( \ + (guchar) ( \ + ( (((guchar)(c))>='A' && ((guchar)(c))<='Z') * ('a'-'A') ) | \ + ( (((guchar)(c))>=192 && ((guchar)(c))<=214) * (224-192) ) | \ + ( (((guchar)(c))>=216 && ((guchar)(c))<=222) * (248-216) ) | \ + ((guchar)(c)) \ + ) \ +) + +#define READ_BUFFER_SIZE (4000) + +/* --- typedefs --- */ +typedef struct _JsonScannerKey JsonScannerKey; + +struct _JsonScannerKey +{ + guint scope_id; + gchar *symbol; + gpointer value; +}; + +/* --- prototypes --- */ +static gboolean json_scanner_key_equal (gconstpointer v1, + gconstpointer v2); +static guint json_scanner_key_hash (gconstpointer v); + +static inline +JsonScannerKey *json_scanner_lookup_internal (JsonScanner *scanner, + guint scope_id, + const gchar *symbol); +static void json_scanner_get_token_ll (JsonScanner *scanner, + GTokenType *token_p, + GTokenValue *value_p, + guint *line_p, + guint *position_p); +static void json_scanner_get_token_i (JsonScanner *scanner, + GTokenType *token_p, + GTokenValue *value_p, + guint *line_p, + guint *position_p); + +static guchar json_scanner_peek_next_char (JsonScanner *scanner); +static guchar json_scanner_get_char (JsonScanner *scanner, + guint *line_p, + guint *position_p); +static gunichar json_scanner_get_unichar (JsonScanner *scanner, + guint *line_p, + guint *position_p); + +/* --- functions --- */ +static inline gint +json_scanner_char_2_num (guchar c, + guchar base) +{ + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + return -1; + + if (c < base) + return c; + + return -1; +} + +JsonScanner * +json_scanner_new (void) +{ + JsonScanner *scanner; + JsonScannerConfig *config_templ; + + config_templ = &json_scanner_config_template; + + scanner = g_new0 (JsonScanner, 1); + + scanner->user_data = NULL; + scanner->max_parse_errors = 1; + scanner->parse_errors = 0; + scanner->input_name = NULL; + g_datalist_init (&scanner->qdata); + + scanner->config = g_new0 (JsonScannerConfig, 1); + + scanner->config->case_sensitive = config_templ->case_sensitive; + scanner->config->cset_skip_characters = config_templ->cset_skip_characters; + if (!scanner->config->cset_skip_characters) + scanner->config->cset_skip_characters = ""; + scanner->config->cset_identifier_first = config_templ->cset_identifier_first; + scanner->config->cset_identifier_nth = config_templ->cset_identifier_nth; + scanner->config->cpair_comment_single = config_templ->cpair_comment_single; + scanner->config->skip_comment_multi = config_templ->skip_comment_multi; + scanner->config->skip_comment_single = config_templ->skip_comment_single; + scanner->config->scan_comment_multi = config_templ->scan_comment_multi; + scanner->config->scan_identifier = config_templ->scan_identifier; + scanner->config->scan_identifier_1char = config_templ->scan_identifier_1char; + scanner->config->scan_identifier_NULL = config_templ->scan_identifier_NULL; + scanner->config->scan_symbols = config_templ->scan_symbols; + scanner->config->scan_binary = config_templ->scan_binary; + scanner->config->scan_octal = config_templ->scan_octal; + scanner->config->scan_float = config_templ->scan_float; + scanner->config->scan_hex = config_templ->scan_hex; + scanner->config->scan_hex_dollar = config_templ->scan_hex_dollar; + scanner->config->scan_string_sq = config_templ->scan_string_sq; + scanner->config->scan_string_dq = config_templ->scan_string_dq; + scanner->config->numbers_2_int = config_templ->numbers_2_int; + scanner->config->int_2_float = config_templ->int_2_float; + scanner->config->identifier_2_string = config_templ->identifier_2_string; + scanner->config->char_2_token = config_templ->char_2_token; + scanner->config->symbol_2_token = config_templ->symbol_2_token; + scanner->config->scope_0_fallback = config_templ->scope_0_fallback; + scanner->config->store_int64 = config_templ->store_int64; + + scanner->token = G_TOKEN_NONE; + scanner->value.v_int64 = 0; + scanner->line = 1; + scanner->position = 0; + + scanner->next_token = G_TOKEN_NONE; + scanner->next_value.v_int64 = 0; + scanner->next_line = 1; + scanner->next_position = 0; + + scanner->symbol_table = g_hash_table_new (json_scanner_key_hash, + json_scanner_key_equal); + scanner->text = NULL; + scanner->text_end = NULL; + scanner->buffer = NULL; + scanner->scope_id = 0; + + return scanner; +} + +static inline void +json_scanner_free_value (GTokenType *token_p, + GTokenValue *value_p) +{ + switch (*token_p) + { + case G_TOKEN_STRING: + case G_TOKEN_IDENTIFIER: + case G_TOKEN_IDENTIFIER_NULL: + case G_TOKEN_COMMENT_SINGLE: + case G_TOKEN_COMMENT_MULTI: + g_free (value_p->v_string); + break; + + default: + break; + } + + *token_p = G_TOKEN_NONE; +} + +static void +json_scanner_destroy_symbol_table_entry (gpointer _key, + gpointer _value, + gpointer _data) +{ + JsonScannerKey *key = _key; + + g_free (key->symbol); + g_slice_free (JsonScannerKey, key); +} + +void +json_scanner_destroy (JsonScanner *scanner) +{ + g_return_if_fail (scanner != NULL); + + g_datalist_clear (&scanner->qdata); + g_hash_table_foreach (scanner->symbol_table, + json_scanner_destroy_symbol_table_entry, + NULL); + g_hash_table_destroy (scanner->symbol_table); + json_scanner_free_value (&scanner->token, &scanner->value); + json_scanner_free_value (&scanner->next_token, &scanner->next_value); + g_free (scanner->config); + g_free (scanner->buffer); + g_free (scanner); +} + +void +json_scanner_error (JsonScanner *scanner, + const gchar *format, + ...) +{ + g_return_if_fail (scanner != NULL); + g_return_if_fail (format != NULL); + + scanner->parse_errors++; + + if (scanner->msg_handler) + { + va_list args; + gchar *string; + + va_start (args, format); + string = g_strdup_vprintf (format, args); + va_end (args); + + scanner->msg_handler (scanner, string); + + g_free (string); + } +} + +static gboolean +json_scanner_key_equal (gconstpointer v1, + gconstpointer v2) +{ + const JsonScannerKey *key1 = v1; + const JsonScannerKey *key2 = v2; + + return (key1->scope_id == key2->scope_id) && + (strcmp (key1->symbol, key2->symbol) == 0); +} + +static guint +json_scanner_key_hash (gconstpointer v) +{ + const JsonScannerKey *key = v; + gchar *c; + guint h; + + h = key->scope_id; + for (c = key->symbol; *c; c++) + h = (h << 5) - h + *c; + + return h; +} + +static inline JsonScannerKey * +json_scanner_lookup_internal (JsonScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + JsonScannerKey *key_p; + JsonScannerKey key; + + key.scope_id = scope_id; + + if (!scanner->config->case_sensitive) + { + gchar *d; + const gchar *c; + + key.symbol = g_new (gchar, strlen (symbol) + 1); + for (d = key.symbol, c = symbol; *c; c++, d++) + *d = to_lower (*c); + *d = 0; + key_p = g_hash_table_lookup (scanner->symbol_table, &key); + g_free (key.symbol); + } + else + { + key.symbol = (gchar*) symbol; + key_p = g_hash_table_lookup (scanner->symbol_table, &key); + } + + return key_p; +} + +void +json_scanner_scope_add_symbol (JsonScanner *scanner, + guint scope_id, + const gchar *symbol, + gpointer value) +{ + JsonScannerKey *key; + + g_return_if_fail (scanner != NULL); + g_return_if_fail (symbol != NULL); + + key = json_scanner_lookup_internal (scanner, scope_id, symbol); + if (!key) + { + key = g_slice_new (JsonScannerKey); + key->scope_id = scope_id; + key->symbol = g_strdup (symbol); + key->value = value; + if (!scanner->config->case_sensitive) + { + gchar *c; + + c = key->symbol; + while (*c != 0) + { + *c = to_lower (*c); + c++; + } + } + + g_hash_table_insert (scanner->symbol_table, key, key); + } + else + key->value = value; +} + +GTokenType +json_scanner_peek_next_token (JsonScanner *scanner) +{ + g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF); + + if (scanner->next_token == G_TOKEN_NONE) + { + scanner->next_line = scanner->line; + scanner->next_position = scanner->position; + json_scanner_get_token_i (scanner, + &scanner->next_token, + &scanner->next_value, + &scanner->next_line, + &scanner->next_position); + } + + return scanner->next_token; +} + +GTokenType +json_scanner_get_next_token (JsonScanner *scanner) +{ + g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF); + + if (scanner->next_token != G_TOKEN_NONE) + { + json_scanner_free_value (&scanner->token, &scanner->value); + + scanner->token = scanner->next_token; + scanner->value = scanner->next_value; + scanner->line = scanner->next_line; + scanner->position = scanner->next_position; + scanner->next_token = G_TOKEN_NONE; + } + else + json_scanner_get_token_i (scanner, + &scanner->token, + &scanner->value, + &scanner->line, + &scanner->position); + + return scanner->token; +} + +void +json_scanner_input_text (JsonScanner *scanner, + const gchar *text, + guint text_len) +{ + g_return_if_fail (scanner != NULL); + if (text_len) + g_return_if_fail (text != NULL); + else + text = NULL; + + scanner->token = G_TOKEN_NONE; + scanner->value.v_int64 = 0; + scanner->line = 1; + scanner->position = 0; + scanner->next_token = G_TOKEN_NONE; + + scanner->text = text; + scanner->text_end = text + text_len; + + if (scanner->buffer) + { + g_free (scanner->buffer); + scanner->buffer = NULL; + } +} + +static guchar +json_scanner_peek_next_char (JsonScanner *scanner) +{ + if (scanner->text < scanner->text_end) + return *scanner->text; + else + return 0; +} + +static guchar +json_scanner_get_char (JsonScanner *scanner, + guint *line_p, + guint *position_p) +{ + guchar fchar; + + if (scanner->text < scanner->text_end) + fchar = *(scanner->text++); + else + fchar = 0; + + if (fchar == '\n') + { + (*position_p) = 0; + (*line_p)++; + } + else if (fchar) + { + (*position_p)++; + } + + return fchar; +} + +#define is_hex_digit(c) (((c) >= '0' && (c) <= '9') || \ + ((c) >= 'a' && (c) <= 'f') || \ + ((c) >= 'A' && (c) <= 'F')) +#define to_hex_digit(c) (((c) <= '9') ? (c) - '0' : ((c) & 7) + 9) + +static gunichar +json_scanner_get_unichar (JsonScanner *scanner, + guint *line_p, + guint *position_p) +{ + gunichar uchar; + gchar ch; + gint i; + + uchar = 0; + for (i = 0; i < 4; i++) + { + ch = json_scanner_get_char (scanner, line_p, position_p); + + if (is_hex_digit (ch)) + uchar += ((gunichar) to_hex_digit (ch) << ((3 - i) * 4)); + else + break; + } + + g_assert (g_unichar_validate (uchar) || g_unichar_type (uchar) == G_UNICODE_SURROGATE); + + return uchar; +} + +/* + * decode_utf16_surrogate_pair: + * @units: (array length=2): a pair of UTF-16 code points + * + * Decodes a surrogate pair of UTF-16 code points into the equivalent + * Unicode code point. + * + * Returns: the Unicode code point equivalent to the surrogate pair + */ +static inline gunichar +decode_utf16_surrogate_pair (const gunichar units[2]) +{ + gunichar ucs; + + g_assert (0xd800 <= units[0] && units[0] <= 0xdbff); + g_assert (0xdc00 <= units[1] && units[1] <= 0xdfff); + + ucs = 0x10000; + ucs += (units[0] & 0x3ff) << 10; + ucs += (units[1] & 0x3ff); + + return ucs; +} + +void +json_scanner_unexp_token (JsonScanner *scanner, + GTokenType expected_token, + const gchar *identifier_spec, + const gchar *symbol_spec, + const gchar *symbol_name, + const gchar *message) +{ + gchar *token_string; + guint token_string_len; + gchar *expected_string; + guint expected_string_len; + gchar *message_prefix; + gboolean print_unexp; + + g_return_if_fail (scanner != NULL); + + if (!identifier_spec) + identifier_spec = "identifier"; + if (!symbol_spec) + symbol_spec = "symbol"; + + token_string_len = 56; + token_string = g_new (gchar, token_string_len + 1); + expected_string_len = 64; + expected_string = g_new (gchar, expected_string_len + 1); + print_unexp = TRUE; + + switch (scanner->token) + { + case G_TOKEN_EOF: + g_snprintf (token_string, token_string_len, "end of file"); + break; + + default: + if (scanner->token >= 1 && scanner->token <= 255) + { + if ((scanner->token >= ' ' && scanner->token <= '~') || + strchr (scanner->config->cset_identifier_first, scanner->token) || + strchr (scanner->config->cset_identifier_nth, scanner->token)) + g_snprintf (token_string, token_string_len, "character `%c'", scanner->token); + else + g_snprintf (token_string, token_string_len, "character `\\%o'", scanner->token); + break; + } + else if (!scanner->config->symbol_2_token) + { + g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token); + break; + } + /* fall through */ + case G_TOKEN_SYMBOL: + if (expected_token == G_TOKEN_SYMBOL || + (scanner->config->symbol_2_token && + expected_token > G_TOKEN_LAST)) + print_unexp = FALSE; + if (symbol_name) + g_snprintf (token_string, token_string_len, + "%s%s `%s'", + print_unexp ? "" : "invalid ", + symbol_spec, + symbol_name); + else + g_snprintf (token_string, token_string_len, + "%s%s", + print_unexp ? "" : "invalid ", + symbol_spec); + break; + + case G_TOKEN_ERROR: + print_unexp = FALSE; + expected_token = G_TOKEN_NONE; + switch (scanner->value.v_error) + { + case G_ERR_UNEXP_EOF: + g_snprintf (token_string, token_string_len, "scanner: unexpected end of file"); + break; + + case G_ERR_UNEXP_EOF_IN_STRING: + g_snprintf (token_string, token_string_len, "scanner: unterminated string constant"); + break; + + case G_ERR_UNEXP_EOF_IN_COMMENT: + g_snprintf (token_string, token_string_len, "scanner: unterminated comment"); + break; + + case G_ERR_NON_DIGIT_IN_CONST: + g_snprintf (token_string, token_string_len, "scanner: non digit in constant"); + break; + + case G_ERR_FLOAT_RADIX: + g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant"); + break; + + case G_ERR_FLOAT_MALFORMED: + g_snprintf (token_string, token_string_len, "scanner: malformed floating constant"); + break; + + case G_ERR_DIGIT_RADIX: + g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix"); + break; + + case G_ERR_UNKNOWN: + default: + g_snprintf (token_string, token_string_len, "scanner: unknown error"); + break; + } + break; + + case G_TOKEN_CHAR: + g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char); + break; + + case G_TOKEN_IDENTIFIER: + case G_TOKEN_IDENTIFIER_NULL: + if (expected_token == G_TOKEN_IDENTIFIER || + expected_token == G_TOKEN_IDENTIFIER_NULL) + print_unexp = FALSE; + g_snprintf (token_string, token_string_len, + "%s%s `%s'", + print_unexp ? "" : "invalid ", + identifier_spec, + scanner->token == G_TOKEN_IDENTIFIER ? scanner->value.v_string : "null"); + break; + + case G_TOKEN_BINARY: + case G_TOKEN_OCTAL: + case G_TOKEN_INT: + case G_TOKEN_HEX: + if (scanner->config->store_int64) + g_snprintf (token_string, token_string_len, "number `%" G_GUINT64_FORMAT "'", scanner->value.v_int64); + else + g_snprintf (token_string, token_string_len, "number `%lu'", scanner->value.v_int); + break; + + case G_TOKEN_FLOAT: + g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float); + break; + + case G_TOKEN_STRING: + if (expected_token == G_TOKEN_STRING) + print_unexp = FALSE; + g_snprintf (token_string, token_string_len, + "%s%sstring constant \"%s\"", + print_unexp ? "" : "invalid ", + scanner->value.v_string[0] == 0 ? "empty " : "", + scanner->value.v_string); + token_string[token_string_len - 2] = '"'; + token_string[token_string_len - 1] = 0; + break; + + case G_TOKEN_COMMENT_SINGLE: + case G_TOKEN_COMMENT_MULTI: + g_snprintf (token_string, token_string_len, "comment"); + break; + + case G_TOKEN_NONE: + /* somehow the user's parsing code is screwed, there isn't much + * we can do about it. + * Note, a common case to trigger this is + * json_scanner_peek_next_token(); json_scanner_unexp_token(); + * without an intermediate json_scanner_get_next_token(). + */ + g_assert_not_reached (); + break; + } + + + switch (expected_token) + { + gboolean need_valid; + gchar *tstring; + case G_TOKEN_EOF: + g_snprintf (expected_string, expected_string_len, "end of file"); + break; + default: + if (expected_token >= 1 && expected_token <= 255) + { + if ((expected_token >= ' ' && expected_token <= '~') || + strchr (scanner->config->cset_identifier_first, expected_token) || + strchr (scanner->config->cset_identifier_nth, expected_token)) + g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token); + else + g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token); + break; + } + else if (!scanner->config->symbol_2_token) + { + g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token); + break; + } + /* fall through */ + case G_TOKEN_SYMBOL: + need_valid = (scanner->token == G_TOKEN_SYMBOL || + (scanner->config->symbol_2_token && + scanner->token > G_TOKEN_LAST)); + g_snprintf (expected_string, expected_string_len, + "%s%s", + need_valid ? "valid " : "", + symbol_spec); + /* FIXME: should we attempt to lookup the symbol_name for symbol_2_token? */ + break; + case G_TOKEN_CHAR: + g_snprintf (expected_string, expected_string_len, "%scharacter", + scanner->token == G_TOKEN_CHAR ? "valid " : ""); + break; + case G_TOKEN_BINARY: + tstring = "binary"; + g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_OCTAL: + tstring = "octal"; + g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_INT: + tstring = "integer"; + g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_HEX: + tstring = "hexadecimal"; + g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_FLOAT: + tstring = "float"; + g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_STRING: + g_snprintf (expected_string, + expected_string_len, + "%sstring constant", + scanner->token == G_TOKEN_STRING ? "valid " : ""); + break; + case G_TOKEN_IDENTIFIER: + case G_TOKEN_IDENTIFIER_NULL: + need_valid = (scanner->token == G_TOKEN_IDENTIFIER_NULL || + scanner->token == G_TOKEN_IDENTIFIER); + g_snprintf (expected_string, + expected_string_len, + "%s%s", + need_valid ? "valid " : "", + identifier_spec); + break; + case G_TOKEN_COMMENT_SINGLE: + tstring = "single-line"; + g_snprintf (expected_string, expected_string_len, "%scomment (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_COMMENT_MULTI: + tstring = "multi-line"; + g_snprintf (expected_string, expected_string_len, "%scomment (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_NONE: + case G_TOKEN_ERROR: + /* this is handled upon printout */ + break; + } + + if (message && message[0] != 0) + message_prefix = " - "; + else + { + message_prefix = ""; + message = ""; + } + if (expected_token == G_TOKEN_ERROR) + { + json_scanner_error (scanner, + "failure around %s%s%s", + token_string, + message_prefix, + message); + } + else if (expected_token == G_TOKEN_NONE) + { + if (print_unexp) + json_scanner_error (scanner, + "unexpected %s%s%s", + token_string, + message_prefix, + message); + else + json_scanner_error (scanner, + "%s%s%s", + token_string, + message_prefix, + message); + } + else + { + if (print_unexp) + json_scanner_error (scanner, + "unexpected %s, expected %s%s%s", + token_string, + expected_string, + message_prefix, + message); + else + json_scanner_error (scanner, + "%s, expected %s%s%s", + token_string, + expected_string, + message_prefix, + message); + } + + g_free (token_string); + g_free (expected_string); +} + +static void +json_scanner_get_token_i (JsonScanner *scanner, + GTokenType *token_p, + GTokenValue *value_p, + guint *line_p, + guint *position_p) +{ + do + { + json_scanner_free_value (token_p, value_p); + json_scanner_get_token_ll (scanner, token_p, value_p, line_p, position_p); + } + while (((*token_p > 0 && *token_p < 256) && + strchr (scanner->config->cset_skip_characters, *token_p)) || + (*token_p == G_TOKEN_CHAR && + strchr (scanner->config->cset_skip_characters, value_p->v_char)) || + (*token_p == G_TOKEN_COMMENT_MULTI && + scanner->config->skip_comment_multi) || + (*token_p == G_TOKEN_COMMENT_SINGLE && + scanner->config->skip_comment_single)); + + switch (*token_p) + { + case G_TOKEN_IDENTIFIER: + if (scanner->config->identifier_2_string) + *token_p = G_TOKEN_STRING; + break; + + case G_TOKEN_SYMBOL: + if (scanner->config->symbol_2_token) + *token_p = (GTokenType) value_p->v_symbol; + break; + + case G_TOKEN_BINARY: + case G_TOKEN_OCTAL: + case G_TOKEN_HEX: + if (scanner->config->numbers_2_int) + *token_p = G_TOKEN_INT; + break; + + default: + break; + } + + if (*token_p == G_TOKEN_INT && + scanner->config->int_2_float) + { + *token_p = G_TOKEN_FLOAT; + if (scanner->config->store_int64) + { +#ifdef _MSC_VER + /* work around error C2520, see gvaluetransform.c */ + value_p->v_float = (__int64)value_p->v_int64; +#else + value_p->v_float = value_p->v_int64; +#endif + } + else + value_p->v_float = value_p->v_int; + } + + errno = 0; +} + +static void +json_scanner_get_token_ll (JsonScanner *scanner, + GTokenType *token_p, + GTokenValue *value_p, + guint *line_p, + guint *position_p) +{ + JsonScannerConfig *config; + GTokenType token; + gboolean in_comment_multi; + gboolean in_comment_single; + gboolean in_string_sq; + gboolean in_string_dq; + GString *gstring; + GTokenValue value; + guchar ch; + + config = scanner->config; + (*value_p).v_int64 = 0; + + if (scanner->text >= scanner->text_end || + scanner->token == G_TOKEN_EOF) + { + *token_p = G_TOKEN_EOF; + return; + } + + in_comment_multi = FALSE; + in_comment_single = FALSE; + in_string_sq = FALSE; + in_string_dq = FALSE; + gstring = NULL; + + do /* while (ch != 0) */ + { + gboolean dotted_float = FALSE; + + ch = json_scanner_get_char (scanner, line_p, position_p); + + value.v_int64 = 0; + token = G_TOKEN_NONE; + + /* this is *evil*, but needed ;( + * we first check for identifier first character, because it + * might interfere with other key chars like slashes or numbers + */ + if (config->scan_identifier && + ch && strchr (config->cset_identifier_first, ch)) + goto identifier_precedence; + + switch (ch) + { + case 0: + token = G_TOKEN_EOF; + (*position_p)++; + /* ch = 0; */ + break; + + case '/': + if (!config->scan_comment_multi || + json_scanner_peek_next_char (scanner) != '*') + goto default_case; + json_scanner_get_char (scanner, line_p, position_p); + token = G_TOKEN_COMMENT_MULTI; + in_comment_multi = TRUE; + gstring = g_string_new (NULL); + while ((ch = json_scanner_get_char (scanner, line_p, position_p)) != 0) + { + if (ch == '*' && json_scanner_peek_next_char (scanner) == '/') + { + json_scanner_get_char (scanner, line_p, position_p); + in_comment_multi = FALSE; + break; + } + else + gstring = g_string_append_c (gstring, ch); + } + ch = 0; + break; + + case '\'': + if (!config->scan_string_sq) + goto default_case; + token = G_TOKEN_STRING; + in_string_sq = TRUE; + gstring = g_string_new (NULL); + while ((ch = json_scanner_get_char (scanner, line_p, position_p)) != 0) + { + if (ch == '\'') + { + in_string_sq = FALSE; + break; + } + else + gstring = g_string_append_c (gstring, ch); + } + ch = 0; + break; + + case '"': + if (!config->scan_string_dq) + goto default_case; + token = G_TOKEN_STRING; + in_string_dq = TRUE; + gstring = g_string_new (NULL); + while ((ch = json_scanner_get_char (scanner, line_p, position_p)) != 0) + { + if (ch == '"') + { + in_string_dq = FALSE; + break; + } + else + { + if (ch == '\\') + { + ch = json_scanner_get_char (scanner, line_p, position_p); + switch (ch) + { + guint i; + guint fchar; + + case 0: + break; + + case '\\': + gstring = g_string_append_c (gstring, '\\'); + break; + + case 'n': + gstring = g_string_append_c (gstring, '\n'); + break; + + case 't': + gstring = g_string_append_c (gstring, '\t'); + break; + + case 'r': + gstring = g_string_append_c (gstring, '\r'); + break; + + case 'b': + gstring = g_string_append_c (gstring, '\b'); + break; + + case 'f': + gstring = g_string_append_c (gstring, '\f'); + break; + + case 'u': + fchar = json_scanner_peek_next_char (scanner); + if (is_hex_digit (fchar)) + { + gunichar ucs; + + ucs = json_scanner_get_unichar (scanner, line_p, position_p); + + /* resolve UTF-16 surrogates for Unicode characters not in the BMP, + * as per ECMA 404, § 9, "String" + */ + if (g_unichar_type (ucs) == G_UNICODE_SURROGATE) + { + /* read next surrogate */ + if ('\\' == json_scanner_get_char (scanner, line_p, position_p) && + 'u' == json_scanner_get_char (scanner, line_p, position_p)) + { + gunichar units[2]; + + units[0] = ucs; + units[1] = json_scanner_get_unichar (scanner, line_p, position_p); + + ucs = decode_utf16_surrogate_pair (units); + g_assert (g_unichar_validate (ucs)); + } + } + + gstring = g_string_append_unichar (gstring, ucs); + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + i = ch - '0'; + fchar = json_scanner_peek_next_char (scanner); + if (fchar >= '0' && fchar <= '7') + { + ch = json_scanner_get_char (scanner, line_p, position_p); + i = i * 8 + ch - '0'; + fchar = json_scanner_peek_next_char (scanner); + if (fchar >= '0' && fchar <= '7') + { + ch = json_scanner_get_char (scanner, line_p, position_p); + i = i * 8 + ch - '0'; + } + } + gstring = g_string_append_c (gstring, i); + break; + + default: + gstring = g_string_append_c (gstring, ch); + break; + } + } + else + gstring = g_string_append_c (gstring, ch); + } + } + ch = 0; + break; + + case '.': + if (!config->scan_float) + goto default_case; + token = G_TOKEN_FLOAT; + dotted_float = TRUE; + ch = json_scanner_get_char (scanner, line_p, position_p); + goto number_parsing; + + case '$': + if (!config->scan_hex_dollar) + goto default_case; + token = G_TOKEN_HEX; + ch = json_scanner_get_char (scanner, line_p, position_p); + goto number_parsing; + + case '0': + if (config->scan_octal) + token = G_TOKEN_OCTAL; + else + token = G_TOKEN_INT; + ch = json_scanner_peek_next_char (scanner); + if (config->scan_hex && (ch == 'x' || ch == 'X')) + { + token = G_TOKEN_HEX; + json_scanner_get_char (scanner, line_p, position_p); + ch = json_scanner_get_char (scanner, line_p, position_p); + if (ch == 0) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_UNEXP_EOF; + (*position_p)++; + break; + } + if (json_scanner_char_2_num (ch, 16) < 0) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_DIGIT_RADIX; + ch = 0; + break; + } + } + else if (config->scan_binary && (ch == 'b' || ch == 'B')) + { + token = G_TOKEN_BINARY; + json_scanner_get_char (scanner, line_p, position_p); + ch = json_scanner_get_char (scanner, line_p, position_p); + if (ch == 0) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_UNEXP_EOF; + (*position_p)++; + break; + } + if (json_scanner_char_2_num (ch, 10) < 0) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + ch = 0; + break; + } + } + else + ch = '0'; + /* fall through */ + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + number_parsing: + { + gboolean in_number = TRUE; + gchar *endptr; + + if (token == G_TOKEN_NONE) + token = G_TOKEN_INT; + + gstring = g_string_new (dotted_float ? "0." : ""); + gstring = g_string_append_c (gstring, ch); + + do /* while (in_number) */ + { + gboolean is_E; + + is_E = token == G_TOKEN_FLOAT && (ch == 'e' || ch == 'E'); + + ch = json_scanner_peek_next_char (scanner); + + if (json_scanner_char_2_num (ch, 36) >= 0 || + (config->scan_float && ch == '.') || + (is_E && (ch == '+' || ch == '-'))) + { + ch = json_scanner_get_char (scanner, line_p, position_p); + + switch (ch) + { + case '.': + if (token != G_TOKEN_INT && token != G_TOKEN_OCTAL) + { + value.v_error = token == G_TOKEN_FLOAT ? G_ERR_FLOAT_MALFORMED : G_ERR_FLOAT_RADIX; + token = G_TOKEN_ERROR; + in_number = FALSE; + } + else + { + token = G_TOKEN_FLOAT; + gstring = g_string_append_c (gstring, ch); + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + gstring = g_string_append_c (gstring, ch); + break; + + case '-': + case '+': + if (token != G_TOKEN_FLOAT) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + in_number = FALSE; + } + else + gstring = g_string_append_c (gstring, ch); + break; + + case 'e': + case 'E': + if ((token != G_TOKEN_HEX && !config->scan_float) || + (token != G_TOKEN_HEX && + token != G_TOKEN_OCTAL && + token != G_TOKEN_FLOAT && + token != G_TOKEN_INT)) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + in_number = FALSE; + } + else + { + if (token != G_TOKEN_HEX) + token = G_TOKEN_FLOAT; + gstring = g_string_append_c (gstring, ch); + } + break; + + default: + if (token != G_TOKEN_HEX) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + in_number = FALSE; + } + else + gstring = g_string_append_c (gstring, ch); + break; + } + } + else + in_number = FALSE; + } + while (in_number); + + endptr = NULL; + if (token == G_TOKEN_FLOAT) + value.v_float = g_strtod (gstring->str, &endptr); + else + { + guint64 ui64 = 0; + switch (token) + { + case G_TOKEN_BINARY: + ui64 = g_ascii_strtoull (gstring->str, &endptr, 2); + break; + case G_TOKEN_OCTAL: + ui64 = g_ascii_strtoull (gstring->str, &endptr, 8); + break; + case G_TOKEN_INT: + ui64 = g_ascii_strtoull (gstring->str, &endptr, 10); + break; + case G_TOKEN_HEX: + ui64 = g_ascii_strtoull (gstring->str, &endptr, 16); + break; + default: ; + } + if (scanner->config->store_int64) + value.v_int64 = ui64; + else + value.v_int = ui64; + } + if (endptr && *endptr) + { + token = G_TOKEN_ERROR; + if (*endptr == 'e' || *endptr == 'E') + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + else + value.v_error = G_ERR_DIGIT_RADIX; + } + g_string_free (gstring, TRUE); + gstring = NULL; + ch = 0; + } /* number_parsing:... */ + break; + + default: + default_case: + { + if (config->cpair_comment_single && + ch == config->cpair_comment_single[0]) + { + token = G_TOKEN_COMMENT_SINGLE; + in_comment_single = TRUE; + gstring = g_string_new (NULL); + ch = json_scanner_get_char (scanner, line_p, position_p); + while (ch != 0) + { + if (ch == config->cpair_comment_single[1]) + { + in_comment_single = FALSE; + ch = 0; + break; + } + + gstring = g_string_append_c (gstring, ch); + ch = json_scanner_get_char (scanner, line_p, position_p); + } + /* ignore a missing newline at EOF for single line comments */ + if (in_comment_single && + config->cpair_comment_single[1] == '\n') + in_comment_single = FALSE; + } + else if (config->scan_identifier && ch && + strchr (config->cset_identifier_first, ch)) + { + identifier_precedence: + + if (config->cset_identifier_nth && ch && + strchr (config->cset_identifier_nth, + json_scanner_peek_next_char (scanner))) + { + token = G_TOKEN_IDENTIFIER; + gstring = g_string_new (NULL); + gstring = g_string_append_c (gstring, ch); + do + { + ch = json_scanner_get_char (scanner, line_p, position_p); + gstring = g_string_append_c (gstring, ch); + ch = json_scanner_peek_next_char (scanner); + } + while (ch && strchr (config->cset_identifier_nth, ch)); + ch = 0; + } + else if (config->scan_identifier_1char) + { + token = G_TOKEN_IDENTIFIER; + value.v_identifier = g_new0 (gchar, 2); + value.v_identifier[0] = ch; + ch = 0; + } + } + if (ch) + { + if (config->char_2_token) + token = ch; + else + { + token = G_TOKEN_CHAR; + value.v_char = ch; + } + ch = 0; + } + } /* default_case:... */ + break; + } + g_assert (ch == 0 && token != G_TOKEN_NONE); /* paranoid */ + } + while (ch != 0); + + if (in_comment_multi || in_comment_single || + in_string_sq || in_string_dq) + { + token = G_TOKEN_ERROR; + if (gstring) + { + g_string_free (gstring, TRUE); + gstring = NULL; + } + (*position_p)++; + if (in_comment_multi || in_comment_single) + value.v_error = G_ERR_UNEXP_EOF_IN_COMMENT; + else /* (in_string_sq || in_string_dq) */ + value.v_error = G_ERR_UNEXP_EOF_IN_STRING; + } + + if (gstring) + { + value.v_string = g_string_free (gstring, FALSE); + gstring = NULL; + } + + if (token == G_TOKEN_IDENTIFIER) + { + if (config->scan_symbols) + { + JsonScannerKey *key; + guint scope_id; + + scope_id = scanner->scope_id; + key = json_scanner_lookup_internal (scanner, scope_id, value.v_identifier); + if (!key && scope_id && scanner->config->scope_0_fallback) + key = json_scanner_lookup_internal (scanner, 0, value.v_identifier); + + if (key) + { + g_free (value.v_identifier); + token = G_TOKEN_SYMBOL; + value.v_symbol = key->value; + } + } + + if (token == G_TOKEN_IDENTIFIER && + config->scan_identifier_NULL && + strlen (value.v_identifier) == 4) + { + gchar *null_upper = "NULL"; + gchar *null_lower = "null"; + + if (scanner->config->case_sensitive) + { + if (value.v_identifier[0] == null_upper[0] && + value.v_identifier[1] == null_upper[1] && + value.v_identifier[2] == null_upper[2] && + value.v_identifier[3] == null_upper[3]) + token = G_TOKEN_IDENTIFIER_NULL; + } + else + { + if ((value.v_identifier[0] == null_upper[0] || + value.v_identifier[0] == null_lower[0]) && + (value.v_identifier[1] == null_upper[1] || + value.v_identifier[1] == null_lower[1]) && + (value.v_identifier[2] == null_upper[2] || + value.v_identifier[2] == null_lower[2]) && + (value.v_identifier[3] == null_upper[3] || + value.v_identifier[3] == null_lower[3])) + token = G_TOKEN_IDENTIFIER_NULL; + } + } + } + + *token_p = token; + *value_p = value; +} diff --git a/json-glib/json-scanner.h b/json-glib/json-scanner.h new file mode 100644 index 0000000..4d1f982 --- /dev/null +++ b/json-glib/json-scanner.h @@ -0,0 +1,147 @@ +/* json-scanner.h: Tokenizer for JSON + * + * This file is part of JSON-GLib + * Copyright (C) 2008 OpenedHand + * + * 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 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, see . + */ + +/* + * JsonScanner is a specialized tokenizer for JSON adapted from + * the GScanner tokenizer in GLib; GScanner came with this notice: + * + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + * + * JsonScanner: modified by Emmanuele Bassi + */ + +#ifndef __JSON_SCANNER_H__ +#define __JSON_SCANNER_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _JsonScanner JsonScanner; +typedef struct _JsonScannerConfig JsonScannerConfig; + +typedef void (* JsonScannerMsgFunc) (JsonScanner *scanner, + gchar *message); + +/** + * JsonTokenType: + * @JSON_TOKEN_INVALID: marker + * @JSON_TOKEN_TRUE: symbol for 'true' bareword + * @JSON_TOKEN_FALSE: symbol for 'false' bareword + * @JSON_TOKEN_NULL: symbol for 'null' bareword + * @JSON_TOKEN_VAR: symbol for 'var' bareword + * @JSON_TOKEN_LAST: marker + * + * Tokens for JsonScanner-based parser, extending #GTokenType. + */ +typedef enum { + JSON_TOKEN_INVALID = G_TOKEN_LAST, + + JSON_TOKEN_TRUE, + JSON_TOKEN_FALSE, + JSON_TOKEN_NULL, + JSON_TOKEN_VAR, + + JSON_TOKEN_LAST +} JsonTokenType; + +/** + * JsonScanner: + * + * Tokenizer scanner for JSON. See #GScanner + * + * Since: 0.6 + */ +struct _JsonScanner +{ + /*< private >*/ + /* unused fields */ + gpointer user_data; + guint max_parse_errors; + + /* json_scanner_error() increments this field */ + guint parse_errors; + + /* name of input stream, featured by the default message handler */ + const gchar *input_name; + + /* quarked data */ + GData *qdata; + + /* link into the scanner configuration */ + JsonScannerConfig *config; + + /* fields filled in after json_scanner_get_next_token() */ + GTokenType token; + GTokenValue value; + guint line; + guint position; + + /* fields filled in after json_scanner_peek_next_token() */ + GTokenType next_token; + GTokenValue next_value; + guint next_line; + guint next_position; + + /* to be considered private */ + GHashTable *symbol_table; + const gchar *text; + const gchar *text_end; + gchar *buffer; + guint scope_id; + + /* handler function for _warn and _error */ + JsonScannerMsgFunc msg_handler; +}; + +G_GNUC_INTERNAL +JsonScanner *json_scanner_new (void); +G_GNUC_INTERNAL +void json_scanner_destroy (JsonScanner *scanner); +G_GNUC_INTERNAL +void json_scanner_input_text (JsonScanner *scanner, + const gchar *text, + guint text_len); +G_GNUC_INTERNAL +GTokenType json_scanner_get_next_token (JsonScanner *scanner); +G_GNUC_INTERNAL +GTokenType json_scanner_peek_next_token (JsonScanner *scanner); +G_GNUC_INTERNAL +void json_scanner_scope_add_symbol (JsonScanner *scanner, + guint scope_id, + const gchar *symbol, + gpointer value); +G_GNUC_INTERNAL +void json_scanner_unexp_token (JsonScanner *scanner, + GTokenType expected_token, + const gchar *identifier_spec, + const gchar *symbol_spec, + const gchar *symbol_name, + const gchar *message); +G_GNUC_INTERNAL +void json_scanner_error (JsonScanner *scanner, + const gchar *format, + ...) G_GNUC_PRINTF (2,3); + +G_END_DECLS + +#endif /* __JSON_SCANNER_H__ */ diff --git a/json-glib/json-serializable.c b/json-glib/json-serializable.c new file mode 100644 index 0000000..d7a76d6 --- /dev/null +++ b/json-glib/json-serializable.c @@ -0,0 +1,365 @@ +/* json-gobject.c - JSON GObject integration + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * + * 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 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. + * + * Author: + * Emmanuele Bassi + */ + +/** + * SECTION:json-serializable + * @short_description: Interface for serialize and deserialize special GObjects + * + * #JsonSerializable is an interface for #GObject classes that + * allows controlling how the class is going to be serialized + * or deserialized by json_construct_gobject() and + * json_serialize_gobject() respectively. + */ + +#include "config.h" + +#include +#include + +#include "json-types-private.h" +#include "json-gobject-private.h" +#include "json-debug.h" + +/** + * json_serializable_serialize_property: + * @serializable: a #JsonSerializable object + * @property_name: the name of the property + * @value: the value of the property + * @pspec: a #GParamSpec + * + * Asks a #JsonSerializable implementation to serialize a #GObject + * property into a #JsonNode object. + * + * Return value: a #JsonNode containing the serialized property + */ +JsonNode * +json_serializable_serialize_property (JsonSerializable *serializable, + const gchar *property_name, + const GValue *value, + GParamSpec *pspec) +{ + JsonSerializableIface *iface; + + g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + g_return_val_if_fail (value != NULL, NULL); + g_return_val_if_fail (pspec != NULL, NULL); + + iface = JSON_SERIALIZABLE_GET_IFACE (serializable); + + return iface->serialize_property (serializable, property_name, value, pspec); +} + +/** + * json_serializable_deserialize_property: + * @serializable: a #JsonSerializable + * @property_name: the name of the property + * @value: (out): a pointer to an uninitialized #GValue + * @pspec: a #GParamSpec + * @property_node: a #JsonNode containing the serialized property + * + * Asks a #JsonSerializable implementation to deserialize the + * property contained inside @property_node into @value. + * + * Return value: %TRUE if the property was successfully deserialized. + */ +gboolean +json_serializable_deserialize_property (JsonSerializable *serializable, + const gchar *property_name, + GValue *value, + GParamSpec *pspec, + JsonNode *property_node) +{ + JsonSerializableIface *iface; + + g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), FALSE); + g_return_val_if_fail (property_name != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (pspec != NULL, FALSE); + g_return_val_if_fail (property_node != NULL, FALSE); + + iface = JSON_SERIALIZABLE_GET_IFACE (serializable); + + return iface->deserialize_property (serializable, + property_name, + value, + pspec, + property_node); +} + +static gboolean +json_serializable_real_deserialize (JsonSerializable *serializable, + const gchar *name, + GValue *value, + GParamSpec *pspec, + JsonNode *node) +{ + JSON_NOTE (GOBJECT, "Default deserialization for property '%s'", pspec->name); + return json_deserialize_pspec (value, pspec, node); +} + +static JsonNode * +json_serializable_real_serialize (JsonSerializable *serializable, + const gchar *name, + const GValue *value, + GParamSpec *pspec) +{ + JSON_NOTE (GOBJECT, "Default serialization for property '%s'", pspec->name); + + if (g_param_value_defaults (pspec, (GValue *)value)) + return NULL; + + return json_serialize_pspec (value, pspec); +} + +static GParamSpec * +json_serializable_real_find_property (JsonSerializable *serializable, + const char *name) +{ + return g_object_class_find_property (G_OBJECT_GET_CLASS (serializable), name); +} + +static GParamSpec ** +json_serializable_real_list_properties (JsonSerializable *serializable, + guint *n_pspecs) +{ + return g_object_class_list_properties (G_OBJECT_GET_CLASS (serializable), n_pspecs); +} + +static void +json_serializable_real_set_property (JsonSerializable *serializable, + GParamSpec *pspec, + const GValue *value) +{ + g_object_set_property (G_OBJECT (serializable), pspec->name, value); +} + +static void +json_serializable_real_get_property (JsonSerializable *serializable, + GParamSpec *pspec, + GValue *value) +{ + g_object_get_property (G_OBJECT (serializable), pspec->name, value); +} + +/* typedef to satisfy G_DEFINE_INTERFACE's naming */ +typedef JsonSerializableIface JsonSerializableInterface; + +static void +json_serializable_default_init (JsonSerializableInterface *iface) +{ + iface->serialize_property = json_serializable_real_serialize; + iface->deserialize_property = json_serializable_real_deserialize; + iface->find_property = json_serializable_real_find_property; + iface->list_properties = json_serializable_real_list_properties; + iface->set_property = json_serializable_real_set_property; + iface->get_property = json_serializable_real_get_property; +} + +G_DEFINE_INTERFACE (JsonSerializable, json_serializable, G_TYPE_OBJECT); + +/** + * json_serializable_default_serialize_property: + * @serializable: a #JsonSerializable object + * @property_name: the name of the property + * @value: the value of the property + * @pspec: a #GParamSpec + * + * Calls the default implementation of the #JsonSerializable + * #JsonSerializableIface.serialize_property() virtual function. + * + * This function can be used inside a custom implementation + * of the #JsonSerializableIface.serialize_property() virtual + * function in lieu of calling the default implementation + * through g_type_default_interface_peek(): + * + * |[ + * JsonSerializable *iface; + * JsonNode *node; + * + * iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE); + * node = iface->serialize_property (serializable, property_name, + * value, + * pspec); + * ]| + * + * Return value: (transfer full): a #JsonNode containing the serialized + * property + * + * Since: 0.10 + */ +JsonNode * +json_serializable_default_serialize_property (JsonSerializable *serializable, + const gchar *property_name, + const GValue *value, + GParamSpec *pspec) +{ + g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL); + g_return_val_if_fail (property_name != NULL, NULL); + g_return_val_if_fail (value != NULL, NULL); + g_return_val_if_fail (pspec != NULL, NULL); + + return json_serializable_real_serialize (serializable, + property_name, + value, pspec); +} + +/** + * json_serializable_default_deserialize_property: + * @serializable: a #JsonSerializable + * @property_name: the name of the property + * @value: a pointer to an uninitialized #GValue + * @pspec: a #GParamSpec + * @property_node: a #JsonNode containing the serialized property + * + * Calls the default implementation of the #JsonSerializable + * deserialize_property() virtual function + * + * This function can be used inside a custom implementation + * of the deserialize_property() virtual function in lieu of: + * + * |[ + * JsonSerializable *iface; + * gboolean res; + * + * iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE); + * res = iface->deserialize_property (serializable, property_name, + * value, + * pspec, + * property_node); + * ]| + * + * Return value: %TRUE if the property was successfully deserialized. + * + * Since: 0.10 + */ +gboolean +json_serializable_default_deserialize_property (JsonSerializable *serializable, + const gchar *property_name, + GValue *value, + GParamSpec *pspec, + JsonNode *property_node) +{ + g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), FALSE); + g_return_val_if_fail (property_name != NULL, FALSE); + g_return_val_if_fail (value != NULL, FALSE); + g_return_val_if_fail (pspec != NULL, FALSE); + g_return_val_if_fail (property_node != NULL, FALSE); + + return json_serializable_real_deserialize (serializable, + property_name, + value, pspec, + property_node); +} + +/** + * json_serializable_find_property: + * @serializable: a #JsonSerializable + * @name: the name of the property + * + * Calls the #JsonSerializableIface.find_property() implementation on + * the @serializable instance. * + * + * Return value: (nullable) (transfer none): the #GParamSpec for the property + * or %NULL if no property was found + * + * Since: 0.14 + */ +GParamSpec * +json_serializable_find_property (JsonSerializable *serializable, + const char *name) +{ + g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL); + g_return_val_if_fail (name != NULL, NULL); + + return JSON_SERIALIZABLE_GET_IFACE (serializable)->find_property (serializable, name); +} + +/** + * json_serializable_list_properties: + * @serializable: a #JsonSerializable + * @n_pspecs: (out): return location for the length of the array + * of #GParamSpec returned by the function + * + * Calls the #JsonSerializableIface.list_properties() implementation on + * the @serializable instance. + * + * Return value: (array length=n_pspecs) (transfer container): an array + * of #GParamSpec. Use g_free() to free the array when done. + * + * Since: 0.14 + */ +GParamSpec ** +json_serializable_list_properties (JsonSerializable *serializable, + guint *n_pspecs) +{ + g_return_val_if_fail (JSON_IS_SERIALIZABLE (serializable), NULL); + + return JSON_SERIALIZABLE_GET_IFACE (serializable)->list_properties (serializable, n_pspecs); +} + +/** + * json_serializable_set_property: + * @serializable: a #JsonSerializable + * @pspec: a #GParamSpec + * @value: the property value to set + * + * Calls the #JsonSerializableIface.set_property() implementation + * on the @serializable instance. + * + * Since: 0.14 + */ +void +json_serializable_set_property (JsonSerializable *serializable, + GParamSpec *pspec, + const GValue *value) +{ + g_return_if_fail (JSON_IS_SERIALIZABLE (serializable)); + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + g_return_if_fail (value != NULL); + + JSON_SERIALIZABLE_GET_IFACE (serializable)->set_property (serializable, + pspec, + value); +} + +/** + * json_serializable_get_property: + * @serializable: a #JsonSerializable + * @pspec: a #GParamSpec + * @value: (out): return location for the property value + * + * Calls the #JsonSerializableIface.get_property() implementation + * on the @serializable instance. + * + * Since: 0.14 + */ +void +json_serializable_get_property (JsonSerializable *serializable, + GParamSpec *pspec, + GValue *value) +{ + g_return_if_fail (JSON_IS_SERIALIZABLE (serializable)); + g_return_if_fail (G_IS_PARAM_SPEC (pspec)); + g_return_if_fail (value != NULL); + + JSON_SERIALIZABLE_GET_IFACE (serializable)->get_property (serializable, + pspec, + value); +} diff --git a/json-glib/json-types-private.h b/json-glib/json-types-private.h new file mode 100644 index 0000000..bc29e80 --- /dev/null +++ b/json-glib/json-types-private.h @@ -0,0 +1,174 @@ +/* json-types-private.h - JSON data types private header + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_TYPES_PRIVATE_H__ +#define __JSON_TYPES_PRIVATE_H__ + +#include "json-types.h" + +G_BEGIN_DECLS + +#define JSON_NODE_IS_VALID(n) \ + ((n) != NULL && \ + (n)->type >= JSON_NODE_OBJECT && \ + (n)->type <= JSON_NODE_NULL && \ + (n)->ref_count >= 1) + +typedef struct _JsonValue JsonValue; + +typedef enum { + JSON_VALUE_INVALID = 0, + JSON_VALUE_INT, + JSON_VALUE_DOUBLE, + JSON_VALUE_BOOLEAN, + JSON_VALUE_STRING, + JSON_VALUE_NULL +} JsonValueType; + +struct _JsonNode +{ + /*< private >*/ + JsonNodeType type; + + volatile gint ref_count; + gboolean immutable : 1; + gboolean allocated : 1; + + union { + JsonObject *object; + JsonArray *array; + JsonValue *value; + } data; + + JsonNode *parent; +}; + +#define JSON_VALUE_INIT { JSON_VALUE_INVALID, 1, FALSE, { 0 }, NULL } +#define JSON_VALUE_INIT_TYPE(t) { (t), 1, FALSE, { 0 }, NULL } +#define JSON_VALUE_IS_VALID(v) ((v) != NULL && (v)->type != JSON_VALUE_INVALID) +#define JSON_VALUE_HOLDS(v,t) ((v) != NULL && (v)->type == (t)) +#define JSON_VALUE_HOLDS_INT(v) (JSON_VALUE_HOLDS((v), JSON_VALUE_INT)) +#define JSON_VALUE_HOLDS_DOUBLE(v) (JSON_VALUE_HOLDS((v), JSON_VALUE_DOUBLE)) +#define JSON_VALUE_HOLDS_BOOLEAN(v) (JSON_VALUE_HOLDS((v), JSON_VALUE_BOOLEAN)) +#define JSON_VALUE_HOLDS_STRING(v) (JSON_VALUE_HOLDS((v), JSON_VALUE_STRING)) +#define JSON_VALUE_HOLDS_NULL(v) (JSON_VALUE_HOLDS((v), JSON_VALUE_NULL)) +#define JSON_VALUE_TYPE(v) (json_value_type((v))) + +struct _JsonValue +{ + JsonValueType type; + + volatile gint ref_count; + gboolean immutable : 1; + + union { + gint64 v_int; + gdouble v_double; + gboolean v_bool; + gchar *v_str; + } data; +}; + +struct _JsonArray +{ + GPtrArray *elements; + + guint immutable_hash; /* valid iff immutable */ + volatile gint ref_count; + gboolean immutable : 1; +}; + +struct _JsonObject +{ + GHashTable *members; + + GQueue members_ordered; + + guint immutable_hash; /* valid iff immutable */ + volatile gint ref_count; + gboolean immutable : 1; +}; + +typedef struct +{ + JsonObject *object; /* unowned */ + GHashTableIter members_iter; /* iterator over @members */ + gpointer padding[2]; /* for future expansion */ +} JsonObjectIterReal; + +G_STATIC_ASSERT (sizeof (JsonObjectIterReal) == sizeof (JsonObjectIter)); + +G_GNUC_INTERNAL +const gchar * json_node_type_get_name (JsonNodeType node_type); +G_GNUC_INTERNAL +const gchar * json_value_type_get_name (JsonValueType value_type); + +G_GNUC_INTERNAL +GQueue * json_object_get_members_internal (JsonObject *object); + +G_GNUC_INTERNAL +GType json_value_type (const JsonValue *value); + +G_GNUC_INTERNAL +JsonValue * json_value_alloc (void); +G_GNUC_INTERNAL +JsonValue * json_value_init (JsonValue *value, + JsonValueType value_type); +G_GNUC_INTERNAL +JsonValue * json_value_ref (JsonValue *value); +G_GNUC_INTERNAL +void json_value_unref (JsonValue *value); +G_GNUC_INTERNAL +void json_value_unset (JsonValue *value); +G_GNUC_INTERNAL +void json_value_free (JsonValue *value); +G_GNUC_INTERNAL +void json_value_set_int (JsonValue *value, + gint64 v_int); +G_GNUC_INTERNAL +gint64 json_value_get_int (const JsonValue *value); +G_GNUC_INTERNAL +void json_value_set_double (JsonValue *value, + gdouble v_double); +G_GNUC_INTERNAL +gdouble json_value_get_double (const JsonValue *value); +G_GNUC_INTERNAL +void json_value_set_boolean (JsonValue *value, + gboolean v_bool); +G_GNUC_INTERNAL +gboolean json_value_get_boolean (const JsonValue *value); +G_GNUC_INTERNAL +void json_value_set_string (JsonValue *value, + const gchar *v_str); +G_GNUC_INTERNAL +const gchar * json_value_get_string (const JsonValue *value); + +G_GNUC_INTERNAL +void json_value_seal (JsonValue *value); + +G_GNUC_INTERNAL +guint json_value_hash (gconstpointer key); + +G_END_DECLS + +#endif /* __JSON_TYPES_PRIVATE_H__ */ diff --git a/json-glib/json-types.h b/json-glib/json-types.h new file mode 100644 index 0000000..cd18c66 --- /dev/null +++ b/json-glib/json-types.h @@ -0,0 +1,525 @@ +/* json-types.h - JSON data types + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_TYPES_H__ +#define __JSON_TYPES_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include +#include + +G_BEGIN_DECLS + +/** + * JSON_NODE_TYPE: + * @node: a #JsonNode + * + * Evaluates to the #JsonNodeType contained by @node + */ +#define JSON_NODE_TYPE(node) (json_node_get_node_type ((node))) + +/** + * JSON_NODE_HOLDS: + * @node: a #JsonNode + * @t: a #JsonNodeType + * + * Evaluates to %TRUE if the @node holds type @t + * + * Since: 0.10 + */ +#define JSON_NODE_HOLDS(node,t) (json_node_get_node_type ((node)) == (t)) + +/** + * JSON_NODE_HOLDS_VALUE: + * @node: a #JsonNode + * + * Evaluates to %TRUE if @node holds a %JSON_NODE_VALUE + * + * Since: 0.10 + */ +#define JSON_NODE_HOLDS_VALUE(node) (JSON_NODE_HOLDS ((node), JSON_NODE_VALUE)) + +/** + * JSON_NODE_HOLDS_OBJECT: + * @node: a #JsonNode + * + * Evaluates to %TRUE if @node holds a %JSON_NODE_OBJECT + * + * Since: 0.10 + */ +#define JSON_NODE_HOLDS_OBJECT(node) (JSON_NODE_HOLDS ((node), JSON_NODE_OBJECT)) + +/** + * JSON_NODE_HOLDS_ARRAY: + * @node: a #JsonNode + * + * Evaluates to %TRUE if @node holds a %JSON_NODE_ARRAY + * + * Since: 0.10 + */ +#define JSON_NODE_HOLDS_ARRAY(node) (JSON_NODE_HOLDS ((node), JSON_NODE_ARRAY)) + +/** + * JSON_NODE_HOLDS_NULL: + * @node: a #JsonNode + * + * Evaluates to %TRUE if @node holds a %JSON_NODE_NULL + * + * Since: 0.10 + */ +#define JSON_NODE_HOLDS_NULL(node) (JSON_NODE_HOLDS ((node), JSON_NODE_NULL)) + +#define JSON_TYPE_NODE (json_node_get_type ()) +#define JSON_TYPE_OBJECT (json_object_get_type ()) +#define JSON_TYPE_ARRAY (json_array_get_type ()) + +/** + * JsonNode: + * + * A generic container of JSON data types. The contents of the #JsonNode + * structure are private and should only be accessed via the provided + * functions and never directly. + */ +typedef struct _JsonNode JsonNode; + +/** + * JsonObject: + * + * A JSON object type. The contents of the #JsonObject structure are private + * and should only be accessed by the provided API + */ +typedef struct _JsonObject JsonObject; + +/** + * JsonArray: + * + * A JSON array type. The contents of the #JsonArray structure are private + * and should only be accessed by the provided API + */ +typedef struct _JsonArray JsonArray; + +/** + * JsonNodeType: + * @JSON_NODE_OBJECT: The node contains a #JsonObject + * @JSON_NODE_ARRAY: The node contains a #JsonArray + * @JSON_NODE_VALUE: The node contains a fundamental type + * @JSON_NODE_NULL: Special type, for nodes containing null + * + * Indicates the content of a #JsonNode. + */ +typedef enum { + JSON_NODE_OBJECT, + JSON_NODE_ARRAY, + JSON_NODE_VALUE, + JSON_NODE_NULL +} JsonNodeType; + +/** + * JsonObjectForeach: + * @object: the iterated #JsonObject + * @member_name: the name of the member + * @member_node: a #JsonNode containing the @member_name value + * @user_data: data passed to the function + * + * The function to be passed to json_object_foreach_member(). You + * should not add or remove members to and from @object within + * this function. It is safe to change the value of @member_node. + * + * Since: 0.8 + */ +typedef void (* JsonObjectForeach) (JsonObject *object, + const gchar *member_name, + JsonNode *member_node, + gpointer user_data); + +/** + * JsonArrayForeach: + * @array: the iterated #JsonArray + * @index_: the index of the element + * @element_node: a #JsonNode containing the value at @index_ + * @user_data: data passed to the function + * + * The function to be passed to json_array_foreach_element(). You + * should not add or remove elements to and from @array within + * this function. It is safe to change the value of @element_node. + * + * Since: 0.8 + */ +typedef void (* JsonArrayForeach) (JsonArray *array, + guint index_, + JsonNode *element_node, + gpointer user_data); + +/* + * JsonNode + */ + +JSON_AVAILABLE_IN_1_0 +GType json_node_get_type (void) G_GNUC_CONST; +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_new (JsonNodeType type); + +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_alloc (void); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_init (JsonNode *node, + JsonNodeType type); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_init_object (JsonNode *node, + JsonObject *object); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_init_array (JsonNode *node, + JsonArray *array); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_init_int (JsonNode *node, + gint64 value); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_init_double (JsonNode *node, + gdouble value); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_init_boolean (JsonNode *node, + gboolean value); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_init_string (JsonNode *node, + const char *value); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_init_null (JsonNode *node); + +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_copy (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_node_free (JsonNode *node); + +JSON_AVAILABLE_IN_1_2 +JsonNode * json_node_ref (JsonNode *node); +JSON_AVAILABLE_IN_1_2 +void json_node_unref (JsonNode *node); + +JSON_AVAILABLE_IN_1_0 +JsonNodeType json_node_get_node_type (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +GType json_node_get_value_type (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_node_set_parent (JsonNode *node, + JsonNode *parent); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_node_get_parent (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +const gchar * json_node_type_name (JsonNode *node); + +JSON_AVAILABLE_IN_1_0 +void json_node_set_object (JsonNode *node, + JsonObject *object); +JSON_AVAILABLE_IN_1_0 +void json_node_take_object (JsonNode *node, + JsonObject *object); +JSON_AVAILABLE_IN_1_0 +JsonObject * json_node_get_object (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +JsonObject * json_node_dup_object (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_node_set_array (JsonNode *node, + JsonArray *array); +JSON_AVAILABLE_IN_1_0 +void json_node_take_array (JsonNode *node, + JsonArray *array); +JSON_AVAILABLE_IN_1_0 +JsonArray * json_node_get_array (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +JsonArray * json_node_dup_array (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_node_set_value (JsonNode *node, + const GValue *value); +JSON_AVAILABLE_IN_1_0 +void json_node_get_value (JsonNode *node, + GValue *value); +JSON_AVAILABLE_IN_1_0 +void json_node_set_string (JsonNode *node, + const gchar *value); +JSON_AVAILABLE_IN_1_0 +const gchar * json_node_get_string (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +gchar * json_node_dup_string (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_node_set_int (JsonNode *node, + gint64 value); +JSON_AVAILABLE_IN_1_0 +gint64 json_node_get_int (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_node_set_double (JsonNode *node, + gdouble value); +JSON_AVAILABLE_IN_1_0 +gdouble json_node_get_double (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_node_set_boolean (JsonNode *node, + gboolean value); +JSON_AVAILABLE_IN_1_0 +gboolean json_node_get_boolean (JsonNode *node); +JSON_AVAILABLE_IN_1_0 +gboolean json_node_is_null (JsonNode *node); + +JSON_AVAILABLE_IN_1_2 +void json_node_seal (JsonNode *node); +JSON_AVAILABLE_IN_1_2 +gboolean json_node_is_immutable (JsonNode *node); + +JSON_AVAILABLE_IN_1_2 +guint json_string_hash (gconstpointer key); +JSON_AVAILABLE_IN_1_2 +gboolean json_string_equal (gconstpointer a, + gconstpointer b); +JSON_AVAILABLE_IN_1_2 +gint json_string_compare (gconstpointer a, + gconstpointer b); + +JSON_AVAILABLE_IN_1_2 +guint json_node_hash (gconstpointer key); +JSON_AVAILABLE_IN_1_2 +gboolean json_node_equal (gconstpointer a, + gconstpointer b); + +/* + * JsonObject + */ +JSON_AVAILABLE_IN_1_0 +GType json_object_get_type (void) G_GNUC_CONST; +JSON_AVAILABLE_IN_1_0 +JsonObject * json_object_new (void); +JSON_AVAILABLE_IN_1_0 +JsonObject * json_object_ref (JsonObject *object); +JSON_AVAILABLE_IN_1_0 +void json_object_unref (JsonObject *object); + +JSON_DEPRECATED_IN_1_0_FOR(json_object_set_member) +void json_object_add_member (JsonObject *object, + const gchar *member_name, + JsonNode *node); + +JSON_AVAILABLE_IN_1_0 +void json_object_set_member (JsonObject *object, + const gchar *member_name, + JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_object_set_int_member (JsonObject *object, + const gchar *member_name, + gint64 value); +JSON_AVAILABLE_IN_1_0 +void json_object_set_double_member (JsonObject *object, + const gchar *member_name, + gdouble value); +JSON_AVAILABLE_IN_1_0 +void json_object_set_boolean_member (JsonObject *object, + const gchar *member_name, + gboolean value); +JSON_AVAILABLE_IN_1_0 +void json_object_set_string_member (JsonObject *object, + const gchar *member_name, + const gchar *value); +JSON_AVAILABLE_IN_1_0 +void json_object_set_null_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +void json_object_set_array_member (JsonObject *object, + const gchar *member_name, + JsonArray *value); +JSON_AVAILABLE_IN_1_0 +void json_object_set_object_member (JsonObject *object, + const gchar *member_name, + JsonObject *value); +JSON_AVAILABLE_IN_1_0 +GList * json_object_get_members (JsonObject *object); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_object_get_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_object_dup_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +gint64 json_object_get_int_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +gdouble json_object_get_double_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +gboolean json_object_get_boolean_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +const gchar * json_object_get_string_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +gboolean json_object_get_null_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +JsonArray * json_object_get_array_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +JsonObject * json_object_get_object_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +gboolean json_object_has_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +void json_object_remove_member (JsonObject *object, + const gchar *member_name); +JSON_AVAILABLE_IN_1_0 +GList * json_object_get_values (JsonObject *object); +JSON_AVAILABLE_IN_1_0 +guint json_object_get_size (JsonObject *object); +JSON_AVAILABLE_IN_1_0 +void json_object_foreach_member (JsonObject *object, + JsonObjectForeach func, + gpointer data); + +JSON_AVAILABLE_IN_1_2 +void json_object_seal (JsonObject *object); +JSON_AVAILABLE_IN_1_2 +gboolean json_object_is_immutable (JsonObject *object); + +JSON_AVAILABLE_IN_1_2 +guint json_object_hash (gconstpointer key); +JSON_AVAILABLE_IN_1_2 +gboolean json_object_equal (gconstpointer a, + gconstpointer b); + +/** + * JsonObjectIter: + * + * An iterator used to iterate over the members of a #JsonObject. This must + * be allocated on the stack and initialised using json_object_iter_init(). + * The order in which members are returned by the iterator is undefined. The + * iterator is invalidated if its #JsonObject is modified during iteration. + * + * All the fields in the #JsonObjectIter structure are private and should + * never be accessed directly. + * + * Since: 1.2 + */ +typedef struct { + /*< private >*/ + gpointer priv_pointer[6]; + int priv_int[2]; + gboolean priv_boolean[1]; +} JsonObjectIter; + +JSON_AVAILABLE_IN_1_2 +void json_object_iter_init (JsonObjectIter *iter, + JsonObject *object); +JSON_AVAILABLE_IN_1_2 +gboolean json_object_iter_next (JsonObjectIter *iter, + const gchar **member_name, + JsonNode **member_node); + +JSON_AVAILABLE_IN_1_0 +GType json_array_get_type (void) G_GNUC_CONST; +JSON_AVAILABLE_IN_1_0 +JsonArray * json_array_new (void); +JSON_AVAILABLE_IN_1_0 +JsonArray * json_array_sized_new (guint n_elements); +JSON_AVAILABLE_IN_1_0 +JsonArray * json_array_ref (JsonArray *array); +JSON_AVAILABLE_IN_1_0 +void json_array_unref (JsonArray *array); +JSON_AVAILABLE_IN_1_0 +void json_array_add_element (JsonArray *array, + JsonNode *node); +JSON_AVAILABLE_IN_1_0 +void json_array_add_int_element (JsonArray *array, + gint64 value); +JSON_AVAILABLE_IN_1_0 +void json_array_add_double_element (JsonArray *array, + gdouble value); +JSON_AVAILABLE_IN_1_0 +void json_array_add_boolean_element (JsonArray *array, + gboolean value); +JSON_AVAILABLE_IN_1_0 +void json_array_add_string_element (JsonArray *array, + const gchar *value); +JSON_AVAILABLE_IN_1_0 +void json_array_add_null_element (JsonArray *array); +JSON_AVAILABLE_IN_1_0 +void json_array_add_array_element (JsonArray *array, + JsonArray *value); +JSON_AVAILABLE_IN_1_0 +void json_array_add_object_element (JsonArray *array, + JsonObject *value); +JSON_AVAILABLE_IN_1_0 +GList * json_array_get_elements (JsonArray *array); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_array_get_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +gint64 json_array_get_int_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +gdouble json_array_get_double_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +gboolean json_array_get_boolean_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +const gchar * json_array_get_string_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +gboolean json_array_get_null_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +JsonArray * json_array_get_array_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +JsonObject * json_array_get_object_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +JsonNode * json_array_dup_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +void json_array_remove_element (JsonArray *array, + guint index_); +JSON_AVAILABLE_IN_1_0 +guint json_array_get_length (JsonArray *array); +JSON_AVAILABLE_IN_1_0 +void json_array_foreach_element (JsonArray *array, + JsonArrayForeach func, + gpointer data); +JSON_AVAILABLE_IN_1_2 +void json_array_seal (JsonArray *array); +JSON_AVAILABLE_IN_1_2 +gboolean json_array_is_immutable (JsonArray *array); + +JSON_AVAILABLE_IN_1_2 +guint json_array_hash (gconstpointer key); +JSON_AVAILABLE_IN_1_2 +gboolean json_array_equal (gconstpointer a, + gconstpointer b); + +#ifdef G_DEFINE_AUTOPTR_CLEANUP_FUNC +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonArray, json_array_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonObject, json_object_unref) +G_DEFINE_AUTOPTR_CLEANUP_FUNC (JsonNode, json_node_unref) +#endif + +G_END_DECLS + +#endif /* __JSON_TYPES_H__ */ diff --git a/json-glib/json-utils.c b/json-glib/json-utils.c new file mode 100644 index 0000000..2ba3690 --- /dev/null +++ b/json-glib/json-utils.c @@ -0,0 +1,102 @@ +/* json-utils.c - JSON utility API + * + * This file is part of JSON-GLib + * Copyright 2015 Emmanuele Bassi + * + * 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, see . + */ + +/** + * SECTION:json-utils + * @Title: Utility API + * @Short_description: Various utility functions + * + * Various utility functions. + */ + +#include "config.h" + +#include "json-utils.h" +#include "json-parser.h" +#include "json-generator.h" + +/** + * json_from_string: + * @str: a valid UTF-8 string containing JSON data + * @error: return location for a #GError + * + * Parses the string in @str and returns a #JsonNode representing + * the JSON tree. + * + * In case of parsing error, this function returns %NULL and sets + * @error appropriately. + * + * Returns: (transfer full): a #JsonNode, or %NULL + * + * Since: 1.2 + */ +JsonNode * +json_from_string (const char *str, + GError **error) +{ + JsonParser *parser; + JsonNode *retval; + + g_return_val_if_fail (str != NULL, NULL); + + parser = json_parser_new (); + if (!json_parser_load_from_data (parser, str, -1, error)) + { + g_object_unref (parser); + return NULL; + } + + retval = json_parser_steal_root (parser); + + g_object_unref (parser); + + return retval; +} + +/** + * json_to_string: + * @node: a #JsonNode + * @pretty: whether the output should be prettyfied for printing + * + * Generates a stringified JSON representation of the contents of + * the passed @node. + * + * Returns: (transfer full): the string representation of the #JsonNode + * + * Since: 1.2 + */ +char * +json_to_string (JsonNode *node, + gboolean pretty) +{ + JsonGenerator *generator; + char *retval; + + g_return_val_if_fail (node != NULL, NULL); + + generator = json_generator_new (); + json_generator_set_pretty (generator, pretty); + json_generator_set_root (generator, node); + + retval = json_generator_to_data (generator, NULL); + + g_object_unref (generator); + + return retval; +} diff --git a/json-glib/json-utils.h b/json-glib/json-utils.h new file mode 100644 index 0000000..e709ecd --- /dev/null +++ b/json-glib/json-utils.h @@ -0,0 +1,40 @@ +/* json-utils.h - JSON utility API + * + * This file is part of JSON-GLib + * Copyright 2015 Emmanuele Bassi + * + * 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, see . + */ + +#ifndef __JSON_UTILS_H__ +#define __JSON_UTILS_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +JSON_AVAILABLE_IN_1_2 +JsonNode * json_from_string (const char *str, + GError **error); +JSON_AVAILABLE_IN_1_2 +char * json_to_string (JsonNode *node, + gboolean pretty); + +G_END_DECLS + +#endif /* __JSON_UTILS_H__ */ diff --git a/json-glib/json-value.c b/json-glib/json-value.c new file mode 100644 index 0000000..1b6f971 --- /dev/null +++ b/json-glib/json-value.c @@ -0,0 +1,282 @@ +/* json-value.c - JSON value container + * + * This file is part of JSON-GLib + * Copyright (C) 2012 Emmanuele Bassi + * Copyright (C) 2015 Collabora Ltd. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + * Philip Withnall + */ + +#include "config.h" + +#include + +#include "json-types-private.h" + +const gchar * +json_value_type_get_name (JsonValueType value_type) +{ + switch (value_type) + { + case JSON_VALUE_INVALID: + return "Unset"; + + case JSON_VALUE_INT: + return "Integer"; + + case JSON_VALUE_DOUBLE: + return "Floating Point"; + + case JSON_VALUE_BOOLEAN: + return "Boolean"; + + case JSON_VALUE_STRING: + return "String"; + + case JSON_VALUE_NULL: + return "Null"; + } + + return "Undefined"; +} + +GType +json_value_type (const JsonValue *value) +{ + switch (value->type) + { + case JSON_VALUE_INVALID: + return G_TYPE_INVALID; + + case JSON_VALUE_INT: + return G_TYPE_INT64; + + case JSON_VALUE_DOUBLE: + return G_TYPE_DOUBLE; + + case JSON_VALUE_BOOLEAN: + return G_TYPE_BOOLEAN; + + case JSON_VALUE_STRING: + return G_TYPE_STRING; + + case JSON_VALUE_NULL: + return G_TYPE_INVALID; + } + + return G_TYPE_INVALID; +} + +JsonValue * +json_value_alloc (void) +{ + JsonValue *res = g_slice_new0 (JsonValue); + + res->ref_count = 1; + + return res; +} + +JsonValue * +json_value_init (JsonValue *value, + JsonValueType value_type) +{ + g_return_val_if_fail (value != NULL, NULL); + + if (value->type != JSON_VALUE_INVALID) + json_value_unset (value); + + value->type = value_type; + + return value; +} + +JsonValue * +json_value_ref (JsonValue *value) +{ + g_return_val_if_fail (value != NULL, NULL); + + value->ref_count++; + + return value; +} + +void +json_value_unref (JsonValue *value) +{ + g_return_if_fail (value != NULL); + + if (--value->ref_count == 0) + json_value_free (value); +} + +void +json_value_unset (JsonValue *value) +{ + g_return_if_fail (value != NULL); + + switch (value->type) + { + case JSON_VALUE_INVALID: + break; + + case JSON_VALUE_INT: + value->data.v_int = 0; + break; + + case JSON_VALUE_DOUBLE: + value->data.v_double = 0.0; + break; + + case JSON_VALUE_BOOLEAN: + value->data.v_bool = FALSE; + break; + + case JSON_VALUE_STRING: + g_free (value->data.v_str); + value->data.v_str = NULL; + break; + + case JSON_VALUE_NULL: + break; + } +} + +void +json_value_free (JsonValue *value) +{ + if (G_LIKELY (value != NULL)) + { + json_value_unset (value); + g_slice_free (JsonValue, value); + } +} + +/** + * json_value_seal: + * @value: a #JsonValue + * + * Seals the #JsonValue, making it immutable to further changes. + * + * If the @value is already immutable, this is a no-op. + * + * Since: 1.2 + */ +void +json_value_seal (JsonValue *value) +{ + g_return_if_fail (JSON_VALUE_IS_VALID (value)); + g_return_if_fail (value->ref_count > 0); + + value->immutable = TRUE; +} + +guint +json_value_hash (gconstpointer key) +{ + JsonValue *value; + guint value_hash; + guint type_hash; + + value = (JsonValue *) key; + + /* Hash the type and value separately. + * Use the top 3 bits to store the type. */ + type_hash = value->type << (sizeof (guint) * 8 - 3); + + switch (value->type) + { + case JSON_VALUE_NULL: + value_hash = 0; + break; + case JSON_VALUE_BOOLEAN: + value_hash = json_value_get_boolean (value) ? 1 : 0; + break; + case JSON_VALUE_STRING: + value_hash = json_string_hash (json_value_get_string (value)); + break; + case JSON_VALUE_INT: { + gint64 v = json_value_get_int (value); + value_hash = g_int64_hash (&v); + break; + } + case JSON_VALUE_DOUBLE: { + gdouble v = json_value_get_double (value); + value_hash = g_double_hash (&v); + break; + } + case JSON_VALUE_INVALID: + default: + g_assert_not_reached (); + } + + /* Mask out the top 3 bits of the @value_hash. */ + value_hash &= ~(7 << (sizeof (guint) * 8 - 3)); + + return (type_hash | value_hash); +} + +#define _JSON_VALUE_DEFINE_SET(Type,EType,CType,VField) \ +void \ +json_value_set_##Type (JsonValue *value, CType VField) \ +{ \ + g_return_if_fail (JSON_VALUE_IS_VALID (value)); \ + g_return_if_fail (JSON_VALUE_HOLDS (value, JSON_VALUE_##EType)); \ + g_return_if_fail (!value->immutable); \ +\ + value->data.VField = VField; \ +\ +} + +#define _JSON_VALUE_DEFINE_GET(Type,EType,CType,VField) \ +CType \ +json_value_get_##Type (const JsonValue *value) \ +{ \ + g_return_val_if_fail (JSON_VALUE_IS_VALID (value), 0); \ + g_return_val_if_fail (JSON_VALUE_HOLDS (value, JSON_VALUE_##EType), 0); \ +\ + return value->data.VField; \ +} + +#define _JSON_VALUE_DEFINE_SET_GET(Type,EType,CType,VField) \ +_JSON_VALUE_DEFINE_SET(Type,EType,CType,VField) \ +_JSON_VALUE_DEFINE_GET(Type,EType,CType,VField) + +_JSON_VALUE_DEFINE_SET_GET(int, INT, gint64, v_int) + +_JSON_VALUE_DEFINE_SET_GET(double, DOUBLE, gdouble, v_double) + +_JSON_VALUE_DEFINE_SET_GET(boolean, BOOLEAN, gboolean, v_bool) + +void +json_value_set_string (JsonValue *value, + const gchar *v_str) +{ + g_return_if_fail (JSON_VALUE_IS_VALID (value)); + g_return_if_fail (JSON_VALUE_HOLDS_STRING (value)); + g_return_if_fail (!value->immutable); + + g_free (value->data.v_str); + value->data.v_str = g_strdup (v_str); +} + +_JSON_VALUE_DEFINE_GET(string, STRING, const gchar *, v_str) + +#undef _JSON_VALUE_DEFINE_SET_GET +#undef _JSON_VALUE_DEFINE_GET +#undef _JSON_VALUE_DEFINE_SET diff --git a/json-glib/json-version-macros.h b/json-glib/json-version-macros.h new file mode 100644 index 0000000..fdbcea9 --- /dev/null +++ b/json-glib/json-version-macros.h @@ -0,0 +1,167 @@ +/* json-version-macros.h - JSON-GLib symbol versioning macros + * + * This file is part of JSON-GLib + * Copyright © 2014 Emmanuele Bassi + * + * 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, see . + */ + +#ifndef __JSON_VERSION_MACROS_H__ +#define __JSON_VERSION_MACROS_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +#include "json-version.h" + +#ifndef _JSON_EXTERN +#define _JSON_EXTERN extern +#endif + +#ifdef JSON_DISABLE_DEPRECATION_WARNINGS +#define JSON_DEPRECATED _JSON_EXTERN +#define JSON_DEPRECATED_FOR(f) _JSON_EXTERN +#define JSON_UNAVAILABLE(maj,min) _JSON_EXTERN +#else +#define JSON_DEPRECATED G_DEPRECATED _JSON_EXTERN +#define JSON_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) _JSON_EXTERN +#define JSON_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) _JSON_EXTERN +#endif + +/* XXX: Each new cycle should add a new version symbol here */ +#define JSON_VERSION_1_0 (G_ENCODE_VERSION (1, 0)) + +#define JSON_VERSION_1_2 (G_ENCODE_VERSION (1, 2)) + +#define JSON_VERSION_1_4 (G_ENCODE_VERSION (1, 4)) + +/* evaluates to the current stable version; for development cycles, + * this means the next stable target + */ +#if (JSON_MINOR_VERSION == 99) +#define JSON_VERSION_CUR_STABLE (G_ENCODE_VERSION (JSON_MAJOR_VERSION + 1, 0)) +#elif (JSON_MINOR_VERSION % 2) +#define JSON_VERSION_CUR_STABLE (G_ENCODE_VERSION (JSON_MAJOR_VERSION, JSON_MINOR_VERSION + 1)) +#else +#define JSON_VERSION_CUR_STABLE (G_ENCODE_VERSION (JSON_MAJOR_VERSION, JSON_MINOR_VERSION)) +#endif + +/* evaluates to the previous stable version */ +#if (JSON_MINOR_VERSION == 99) +#define JSON_VERSION_PREV_STABLE (G_ENCODE_VERSION (JSON_MAJOR_VERSION + 1, 0)) +#elif (JSON_MINOR_VERSION % 2) +#define JSON_VERSION_PREV_STABLE (G_ENCODE_VERSION (JSON_MAJOR_VERSION, JSON_MINOR_VERSION - 1)) +#else +#define JSON_VERSION_PREV_STABLE (G_ENCODE_VERSION (JSON_MAJOR_VERSION, JSON_MINOR_VERSION - 2)) +#endif + +/** + * JSON_VERSION_MIN_REQUIRED: + * + * A macro that should be defined by the user prior to including + * the gdk.h header. + * The definition should be one of the predefined JSON version + * macros: %JSON_VERSION_1_0, %JSON_VERSION_1_2,... + * + * This macro defines the lower bound for the JSON-GLib API to use. + * + * If a function has been deprecated in a newer version of JSON-GLib, + * it is possible to use this symbol to avoid the compiler warnings + * without disabling warning for every deprecated function. + * + * Since: 1.0 + */ +#ifndef JSON_VERSION_MIN_REQUIRED +# define JSON_VERSION_MIN_REQUIRED (JSON_VERSION_CUR_STABLE) +#endif + +/** + * JSON_VERSION_MAX_ALLOWED: + * + * A macro that should be defined by the user prior to including + * the json-glib.h header. + + * The definition should be one of the predefined JSON-GLib version + * macros: %JSON_VERSION_1_0, %JSON_VERSION_1_2,... + * + * This macro defines the upper bound for the JSON API-GLib to use. + * + * If a function has been introduced in a newer version of JSON-GLib, + * it is possible to use this symbol to get compiler warnings when + * trying to use that function. + * + * Since: 1.0 + */ +#ifndef JSON_VERSION_MAX_ALLOWED +# if JSON_VERSION_MIN_REQUIRED > JSON_VERSION_PREV_STABLE +# define JSON_VERSION_MAX_ALLOWED (JSON_VERSION_MIN_REQUIRED) +# else +# define JSON_VERSION_MAX_ALLOWED (JSON_VERSION_CUR_STABLE) +# endif +#endif + +/* sanity checks */ +#if JSON_VERSION_MAX_ALLOWED < JSON_VERSION_MIN_REQUIRED +#error "JSON_VERSION_MAX_ALLOWED must be >= JSON_VERSION_MIN_REQUIRED" +#endif +#if JSON_VERSION_MIN_REQUIRED < JSON_VERSION_1_0 +#error "JSON_VERSION_MIN_REQUIRED must be >= JSON_VERSION_1_0" +#endif + +/* XXX: Every new stable minor release should add a set of macros here */ + +#if JSON_VERSION_MIN_REQUIRED >= JSON_VERSION_1_0 +# define JSON_DEPRECATED_IN_1_0 JSON_DEPRECATED +# define JSON_DEPRECATED_IN_1_0_FOR(f) JSON_DEPRECATED_FOR(f) +#else +# define JSON_DEPRECATED_IN_1_0 _JSON_EXTERN +# define JSON_DEPRECATED_IN_1_0_FOR(f) _JSON_EXTERN +#endif + +#if JSON_VERSION_MAX_ALLOWED < JSON_VERSION_1_0 +# define JSON_AVAILABLE_IN_1_0 JSON_UNAVAILABLE(1, 0) +#else +# define JSON_AVAILABLE_IN_1_0 _JSON_EXTERN +#endif + +#if JSON_VERSION_MIN_REQUIRED >= JSON_VERSION_1_2 +# define JSON_DEPRECATED_IN_1_2 JSON_DEPRECATED +# define JSON_DEPRECATED_IN_1_2_FOR(f) JSON_DEPRECATED_FOR(f) +#else +# define JSON_DEPRECATED_IN_1_2 _JSON_EXTERN +# define JSON_DEPRECATED_IN_1_2_FOR(f) _JSON_EXTERN +#endif + +#if JSON_VERSION_MAX_ALLOWED < JSON_VERSION_1_2 +# define JSON_AVAILABLE_IN_1_2 JSON_UNAVAILABLE(1, 2) +#else +# define JSON_AVAILABLE_IN_1_2 _JSON_EXTERN +#endif + +#if JSON_VERSION_MIN_REQUIRED >= JSON_VERSION_1_4 +# define JSON_DEPRECATED_IN_1_4 JSON_DEPRECATED +# define JSON_DEPRECATED_IN_1_4_FOR(f) JSON_DEPRECATED_FOR(f) +#else +# define JSON_DEPRECATED_IN_1_4 _JSON_EXTERN +# define JSON_DEPRECATED_IN_1_4_FOR(f) _JSON_EXTERN +#endif + +#if JSON_VERSION_MAX_ALLOWED < JSON_VERSION_1_4 +# define JSON_AVAILABLE_IN_1_4 JSON_UNAVAILABLE(1, 4) +#else +# define JSON_AVAILABLE_IN_1_4 _JSON_EXTERN +#endif + +#endif /* __JSON_VERSION_MACROS_H__ */ diff --git a/json-glib/json-version.h.in b/json-glib/json-version.h.in new file mode 100644 index 0000000..d18caa2 --- /dev/null +++ b/json-glib/json-version.h.in @@ -0,0 +1,102 @@ +/* json-version.h - JSON-GLib versioning information + * + * This file is part of JSON-GLib + * Copyright (C) 2007 OpenedHand Ltd. + * Copyright (C) 2009 Intel Corp. + * + * 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, see . + * + * Author: + * Emmanuele Bassi + */ + +#ifndef __JSON_VERSION_H__ +#define __JSON_VERSION_H__ + +#if !defined(__JSON_GLIB_INSIDE__) && !defined(JSON_COMPILATION) +#error "Only can be included directly." +#endif + +/** + * SECTION:json-version + * @short_description: JSON-GLib version checking + * + * JSON-GLib provides macros to check the version of the library + * at compile-time + */ + +/** + * JSON_MAJOR_VERSION: + * + * Json major version component (e.g. 1 if %JSON_VERSION is 1.2.3) + */ +#define JSON_MAJOR_VERSION (@JSON_MAJOR_VERSION@) + +/** + * JSON_MINOR_VERSION: + * + * Json minor version component (e.g. 2 if %JSON_VERSION is 1.2.3) + */ +#define JSON_MINOR_VERSION (@JSON_MINOR_VERSION@) + +/** + * JSON_MICRO_VERSION: + * + * Json micro version component (e.g. 3 if %JSON_VERSION is 1.2.3) + */ +#define JSON_MICRO_VERSION (@JSON_MICRO_VERSION@) + +/** + * JSON_VERSION + * + * Json version. + */ +#define JSON_VERSION (@JSON_VERSION@) + +/** + * JSON_VERSION_S: + * + * JSON-GLib version, encoded as a string, useful for printing and + * concatenation. + */ +#define JSON_VERSION_S "@JSON_VERSION@" + +#define JSON_ENCODE_VERSION(major,minor,micro) \ + ((major) << 24 | (minor) << 16 | (micro) << 8) + +/** + * JSON_VERSION_HEX: + * + * JSON-GLib version, encoded as an hexadecimal number, useful for + * integer comparisons. + */ +#define JSON_VERSION_HEX \ + (JSON_ENCODE_VERSION (JSON_MAJOR_VERSION, JSON_MINOR_VERSION, JSON_MICRO_VERSION)) + +/** + * JSON_CHECK_VERSION: + * @major: required major version + * @minor: required minor version + * @micro: required micro version + * + * Compile-time version checking. Evaluates to %TRUE if the version + * of Json is greater than the required one. + */ +#define JSON_CHECK_VERSION(major,minor,micro) \ + (JSON_MAJOR_VERSION > (major) || \ + (JSON_MAJOR_VERSION == (major) && JSON_MINOR_VERSION > (minor)) || \ + (JSON_MAJOR_VERSION == (major) && JSON_MINOR_VERSION == (minor) && \ + JSON_MICRO_VERSION >= (micro))) + +#endif /* __JSON_VERSION_H__ */ diff --git a/json-glib/meson.build b/json-glib/meson.build new file mode 100644 index 0000000..2cc566c --- /dev/null +++ b/json-glib/meson.build @@ -0,0 +1,128 @@ +install_header_subdir = join_paths(json_api_name, 'json-glib') +install_header_dir = join_paths(json_includedir, install_header_subdir) + +configure_file(output: 'config.h', configuration: cdata) + +source_h = [ + 'json-builder.h', + 'json-generator.h', + 'json-gobject.h', + 'json-gvariant.h', + 'json-parser.h', + 'json-path.h', + 'json-reader.h', + 'json-types.h', + 'json-utils.h', + 'json-version-macros.h' +] + +json_glib_enums = gnome.mkenums('json-enum-types', + sources: source_h, + h_template: 'json-enum-types.h.in', + c_template: 'json-enum-types.c.in', + install_header: true, + install_dir: install_header_dir) +# Keep a reference to the generated header, for internal dependencies +json_enum_types_h = json_glib_enums.get(1) + +source_c = [ + 'json-array.c', + 'json-builder.c', + 'json-debug.c', + 'json-gboxed.c', + 'json-generator.c', + 'json-gobject.c', + 'json-gvariant.c', + 'json-node.c', + 'json-object.c', + 'json-parser.c', + 'json-path.c', + 'json-reader.c', + 'json-scanner.c', + 'json-serializable.c', + 'json-utils.c', + 'json-value.c', +] + +version_data = configuration_data() +version_data.set('JSON_MAJOR_VERSION', json_version_major) +version_data.set('JSON_MINOR_VERSION', json_version_minor) +version_data.set('JSON_MICRO_VERSION', json_version_micro) +version_data.set('JSON_VERSION', meson.project_version()) + +json_version_h = configure_file(input: 'json-version.h.in', + output: 'json-version.h', + configuration: version_data, + install: true, + install_dir: install_header_dir) + +install_headers(source_h + [ 'json-glib.h', ], subdir: install_header_subdir) + +json_c_args = [ + '-DJSON_COMPILATION', + '-DG_LOG_DOMAIN="Json"', + '-DJSON_LOCALEDIR="@0@"'.format(json_localedir) +] + +json_lib = library(json_api_name, + source_c + json_glib_enums, + version: libversion, + soversion: soversion, + include_directories: root_dir, + dependencies: [ gio_dep, gobject_dep, ], + c_args: json_c_args + common_cflags, + link_args: common_ldflags, + install: true) + +pkgg = import('pkgconfig') + +pkgg.generate(libraries: [ json_lib ], + subdirs: json_api_name, + version: json_version, + name: 'JSON-GLib', + filebase: json_api_name, + description: 'JSON Parser for GLib.', + requires: 'gio-2.0') + +gir = find_program('g-ir-scanner', required: false) +build_gir = gir.found() and get_option('introspection') +if build_gir + gir_args = [ + '--quiet', + '--c-include=json-glib/json-glib.h', + '-DJSON_COMPILATION', + ] + + gnome.generate_gir(json_lib, + sources: source_c + source_h + json_glib_enums + [ json_version_h ], + namespace: 'Json', + nsversion: json_api_version, + identifier_prefix: 'Json', + symbol_prefix: 'json', + export_packages: json_api_name, + includes: [ 'GObject-2.0', 'Gio-2.0', ], + install: true, + extra_args: gir_args) +endif + +json_glib_dep = declare_dependency(link_with: json_lib, + include_directories: root_dir, + dependencies: [ gobject_dep, gio_dep, ], + sources: [ json_enum_types_h ]) + +tools = [ + [ 'json-glib-validate', [ 'json-glib-validate.c', ] ], + [ 'json-glib-format', [ 'json-glib-format.c', ] ], +] + +foreach t: tools + bin_name = t[0] + bin_sources = t[1] + + executable(bin_name, bin_sources, + c_args: json_c_args, + dependencies: json_glib_dep, + install: true) +endforeach + +subdir('tests') diff --git a/json-glib/tests/array.c b/json-glib/tests/array.c new file mode 100644 index 0000000..426cd72 --- /dev/null +++ b/json-glib/tests/array.c @@ -0,0 +1,150 @@ +#include "json-test-utils.h" + +static void +test_empty_array (void) +{ + JsonArray *array = json_array_new (); + + g_assert_cmpint (json_array_get_length (array), ==, 0); + g_assert (json_array_get_elements (array) == NULL); + + json_array_unref (array); +} + +static void +test_add_element (void) +{ + JsonArray *array = json_array_new (); + JsonNode *node = json_node_new (JSON_NODE_NULL); + + g_assert_cmpint (json_array_get_length (array), ==, 0); + + json_array_add_element (array, node); + g_assert_cmpint (json_array_get_length (array), ==, 1); + + node = json_array_get_element (array, 0); + g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_NULL); + g_assert (json_array_get_null_element (array, 0)); + + json_array_add_int_element (array, 42); + g_assert_cmpint (json_array_get_length (array), ==, 2); + g_assert_cmpint (json_array_get_int_element (array, 1), ==, 42); + + json_array_add_double_element (array, 3.14); + g_assert_cmpint (json_array_get_length (array), ==, 3); + json_assert_fuzzy_equals (json_array_get_double_element (array, 2), 3.14, 0.001); + + json_array_add_boolean_element (array, TRUE); + g_assert_cmpint (json_array_get_length (array), ==, 4); + g_assert (json_array_get_boolean_element (array, 3)); + + json_array_add_string_element (array, "Hello"); + g_assert_cmpint (json_array_get_length (array), ==, 5); + g_assert_cmpstr (json_array_get_string_element (array, 4), ==, "Hello"); + + json_array_add_string_element (array, NULL); + g_assert_cmpint (json_array_get_length (array), ==, 6); + g_assert (json_array_get_string_element (array, 5) == NULL); + g_assert (json_array_get_element (array, 5) != NULL); + g_assert (json_array_get_null_element (array, 5)); + + json_array_add_array_element (array, NULL); + g_assert (json_array_get_array_element (array, 6) == NULL); + g_assert (json_array_get_null_element (array, 6)); + + json_array_add_object_element (array, json_object_new ()); + g_assert (json_array_get_object_element (array, 7) != NULL); + + json_array_add_object_element (array, NULL); + g_assert (json_array_get_object_element (array, 8) == NULL); + g_assert (json_array_get_null_element (array, 8)); + + json_array_unref (array); +} + +static void +test_remove_element (void) +{ + JsonArray *array = json_array_new (); + JsonNode *node = json_node_new (JSON_NODE_NULL); + + json_array_add_element (array, node); + + json_array_remove_element (array, 0); + g_assert_cmpint (json_array_get_length (array), ==, 0); + + json_array_unref (array); +} + +typedef struct _TestForeachFixture +{ + GList *elements; + gint n_elements; + gint iterations; +} TestForeachFixture; + +static const struct { + JsonNodeType element_type; + GType element_gtype; +} type_verify[] = { + { JSON_NODE_VALUE, G_TYPE_INT64 }, + { JSON_NODE_VALUE, G_TYPE_BOOLEAN }, + { JSON_NODE_VALUE, G_TYPE_STRING }, + { JSON_NODE_NULL, G_TYPE_INVALID } +}; + +static void +verify_foreach (JsonArray *array, + guint index_, + JsonNode *element_node, + gpointer user_data) +{ + TestForeachFixture *fixture = user_data; + + g_assert (g_list_find (fixture->elements, element_node)); + g_assert (json_node_get_node_type (element_node) == type_verify[index_].element_type); + g_assert (json_node_get_value_type (element_node) == type_verify[index_].element_gtype); + + fixture->iterations += 1; +} + +static void +test_foreach_element (void) +{ + JsonArray *array = json_array_new (); + TestForeachFixture fixture = { 0, }; + + json_array_add_int_element (array, 42); + json_array_add_boolean_element (array, TRUE); + json_array_add_string_element (array, "hello"); + json_array_add_null_element (array); + + fixture.elements = json_array_get_elements (array); + g_assert (fixture.elements != NULL); + + fixture.n_elements = json_array_get_length (array); + g_assert_cmpint (fixture.n_elements, ==, g_list_length (fixture.elements)); + + fixture.iterations = 0; + + json_array_foreach_element (array, verify_foreach, &fixture); + + g_assert_cmpint (fixture.iterations, ==, fixture.n_elements); + + g_list_free (fixture.elements); + json_array_unref (array); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/array/empty-array", test_empty_array); + g_test_add_func ("/array/add-element", test_add_element); + g_test_add_func ("/array/remove-element", test_remove_element); + g_test_add_func ("/array/foreach-element", test_foreach_element); + + return g_test_run (); +} diff --git a/json-glib/tests/boxed.c b/json-glib/tests/boxed.c new file mode 100644 index 0000000..6e52e2a --- /dev/null +++ b/json-glib/tests/boxed.c @@ -0,0 +1,263 @@ +#include +#include +#include + +#include + +#include +#include + +#define TEST_TYPE_BOXED (test_boxed_get_type ()) +#define TEST_TYPE_OBJECT (test_object_get_type ()) +#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject)) +#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass)) +#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass)) + +typedef struct _TestBoxed TestBoxed; +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; + +struct _TestBoxed +{ + gint foo; + gboolean bar; +}; + +struct _TestObject +{ + GObject parent_instance; + + TestBoxed blah; +}; + +struct _TestObjectClass +{ + GObjectClass parent_class; +}; + +GType test_object_get_type (void); + +/*** implementation ***/ + +static gpointer +test_boxed_copy (gpointer src) +{ + return g_slice_dup (TestBoxed, src); +} + +static void +test_boxed_free (gpointer boxed) +{ + if (G_LIKELY (boxed != NULL)) + g_slice_free (TestBoxed, boxed); +} + +static JsonNode * +test_boxed_serialize (gconstpointer boxed) +{ + const TestBoxed *test = boxed; + JsonObject *object; + JsonNode *node; + + if (boxed == NULL) + return json_node_new (JSON_NODE_NULL); + + object = json_object_new (); + node = json_node_new (JSON_NODE_OBJECT); + + json_object_set_int_member (object, "foo", test->foo); + json_object_set_boolean_member (object, "bar", test->bar); + + json_node_take_object (node, object); + + if (g_test_verbose ()) + { + g_print ("Serialize: { foo: %" G_GINT64_FORMAT ", bar: %s }\n", + json_object_get_int_member (object, "foo"), + json_object_get_boolean_member (object, "bar") ? "true" : "false"); + } + + return node; +} + +static gpointer +test_boxed_deserialize (JsonNode *node) +{ + JsonObject *object; + TestBoxed *test; + + if (json_node_get_node_type (node) != JSON_NODE_OBJECT) + return NULL; + + object = json_node_get_object (node); + + test = g_slice_new (TestBoxed); + test->foo = json_object_get_int_member (object, "foo"); + test->bar = json_object_get_boolean_member (object, "bar"); + + if (g_test_verbose ()) + { + g_print ("Deserialize: { foo: %d, bar: %s }\n", + test->foo, + test->bar ? "true" : "false"); + } + + return test; +} + +GType +test_boxed_get_type (void) +{ + static GType b_type = 0; + + if (G_UNLIKELY (b_type == 0)) + { + b_type = g_boxed_type_register_static ("TestBoxed", + test_boxed_copy, + test_boxed_free); + + if (g_test_verbose ()) + g_print ("Registering transform functions\n"); + + json_boxed_register_serialize_func (b_type, JSON_NODE_OBJECT, + test_boxed_serialize); + json_boxed_register_deserialize_func (b_type, JSON_NODE_OBJECT, + test_boxed_deserialize); + } + + return b_type; +} + +enum +{ + PROP_0, + + PROP_BLAH +}; + +G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT); + +static void +test_object_finalize (GObject *gobject) +{ + G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject); +} + +static void +test_object_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_BLAH: + { + const TestBoxed *blah = g_value_get_boxed (value); + + TEST_OBJECT (gobject)->blah = *blah; + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +test_object_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_BLAH: + g_value_set_boxed (value, &(TEST_OBJECT (gobject)->blah)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +test_object_class_init (TestObjectClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = test_object_set_property; + gobject_class->get_property = test_object_get_property; + gobject_class->finalize = test_object_finalize; + + g_object_class_install_property (gobject_class, + PROP_BLAH, + g_param_spec_boxed ("blah", "Blah", "Blah", + TEST_TYPE_BOXED, + G_PARAM_READWRITE)); +} + +static void +test_object_init (TestObject *object) +{ + object->blah.foo = 0; + object->blah.bar = FALSE; +} + +static const gchar *serialize_data = +"{\n" +" \"blah\" : {\n" +" \"foo\" : 42,\n" +" \"bar\" : true\n" +" }\n" +"}"; + +static void +test_serialize_boxed (void) +{ + TestBoxed boxed = { 42, TRUE }; + GObject *obj; + gchar *data; + gsize len; + + obj = g_object_new (TEST_TYPE_OBJECT, "blah", &boxed, NULL); + + data = json_gobject_to_data (obj, &len); + + g_assert_cmpint (len, ==, strlen (serialize_data)); + g_assert_cmpstr (data, ==, serialize_data); + + if (g_test_verbose ()) + g_print ("TestObject:\n%s\n", data); + + g_free (data); + g_object_unref (obj); +} + +static void +test_deserialize_boxed (void) +{ + + GObject *obj; + + obj = json_gobject_from_data (TEST_TYPE_OBJECT, serialize_data, -1, NULL); + g_assert (TEST_IS_OBJECT (obj)); + g_assert_cmpint (TEST_OBJECT (obj)->blah.foo, ==, 42); + g_assert (TEST_OBJECT (obj)->blah.bar); + + g_object_unref (obj); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/boxed/serialize-property", test_serialize_boxed); + g_test_add_func ("/boxed/deserialize-property", test_deserialize_boxed); + + return g_test_run (); +} diff --git a/json-glib/tests/builder.c b/json-glib/tests/builder.c new file mode 100644 index 0000000..b3e07d6 --- /dev/null +++ b/json-glib/tests/builder.c @@ -0,0 +1,170 @@ +#include +#include +#include + +#include + +#include + +static const gchar *complex_object = "{\"depth1\":[1,{\"depth2\":[3,[null,false],\"after array\"],\"value2\":true}],\"object1\":{},\"value3\":null,\"value4\":42,\"\":54}"; + +static const gchar *empty_object = "{\"a\":{}}"; + +static const gchar *reset_object = "{\"test\":\"reset\"}"; +static const gchar *reset_array = "[\"reset\"]"; + +static void +test_builder_complex (void) +{ + JsonBuilder *builder = json_builder_new (); + JsonNode *node; + JsonGenerator *generator; + gsize length; + gchar *data; + + json_builder_begin_object (builder); + + json_builder_set_member_name (builder, "depth1"); + json_builder_begin_array (builder); + json_builder_add_int_value (builder, 1); + + json_builder_begin_object (builder); + + json_builder_set_member_name (builder, "depth2"); + json_builder_begin_array (builder); + json_builder_add_int_value (builder, 3); + + json_builder_begin_array (builder); + json_builder_add_null_value (builder); + json_builder_add_boolean_value (builder, FALSE); + json_builder_end_array (builder); + + json_builder_add_string_value (builder, "after array"); + json_builder_end_array (builder); /* depth2 */ + + json_builder_set_member_name (builder, "value2"); + json_builder_add_boolean_value (builder, TRUE); + json_builder_end_object (builder); + + json_builder_end_array (builder); /* depth1 */ + + json_builder_set_member_name (builder, "object1"); + json_builder_begin_object (builder); + json_builder_end_object (builder); + + json_builder_set_member_name (builder, "value3"); + json_builder_add_null_value (builder); + + json_builder_set_member_name (builder, "value4"); + json_builder_add_int_value (builder, 42); + + json_builder_set_member_name (builder, ""); + json_builder_add_int_value (builder, 54); + + json_builder_end_object (builder); + + node = json_builder_get_root (builder); + g_object_unref (builder); + + generator = json_generator_new (); + json_generator_set_root (generator, node); + data = json_generator_to_data (generator, &length); + + if (g_test_verbose ()) + g_print ("Builder complex: '%*s'\n", (int)length, data); + + g_assert_cmpint (length, ==, strlen (complex_object)); + g_assert_cmpstr (data, ==, complex_object); + + g_free (data); + json_node_free (node); + g_object_unref (generator); +} + +static void +test_builder_empty (void) +{ + JsonBuilder *builder = json_builder_new (); + JsonNode *node; + JsonGenerator *generator; + gsize length; + gchar *data; + + json_builder_begin_object (builder); + + json_builder_set_member_name (builder, "a"); + + json_builder_begin_object (builder); + json_builder_end_object (builder); + + json_builder_end_object (builder); + + node = json_builder_get_root (builder); + g_object_unref (builder); + + generator = json_generator_new (); + json_generator_set_root (generator, node); + data = json_generator_to_data (generator, &length); + + if (g_test_verbose ()) + g_print ("Builder empty: '%*s'\n", (int)length, data); + + g_assert_cmpint (length, ==, strlen (empty_object)); + g_assert_cmpstr (data, ==, empty_object); + + g_free (data); + json_node_free (node); + g_object_unref (generator); +} + +static void +test_builder_reset (void) +{ + JsonBuilder *builder = json_builder_new (); + JsonGenerator *generator = json_generator_new (); + JsonNode *node; + gsize length; + gchar *data; + + json_builder_begin_object (builder); + json_builder_set_member_name (builder, "test"); + json_builder_add_string_value (builder, "reset"); + json_builder_end_object (builder); + + node = json_builder_get_root (builder); + json_generator_set_root (generator, node); + data = json_generator_to_data (generator, &length); + g_assert (strncmp (data, reset_object, length) == 0); + + g_free (data); + json_node_free (node); + + json_builder_reset (builder); + + json_builder_begin_array (builder); + json_builder_add_string_value (builder, "reset"); + json_builder_end_array (builder); + + node = json_builder_get_root (builder); + json_generator_set_root (generator, node); + data = json_generator_to_data (generator, &length); + g_assert (strncmp (data, reset_array, length) == 0); + + g_free (data); + json_node_free (node); + g_object_unref (builder); + g_object_unref (generator); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/builder/complex", test_builder_complex); + g_test_add_func ("/builder/empty", test_builder_empty); + g_test_add_func ("/builder/reset", test_builder_reset); + + return g_test_run (); +} diff --git a/json-glib/tests/generator.c b/json-glib/tests/generator.c new file mode 100644 index 0000000..e7dabff --- /dev/null +++ b/json-glib/tests/generator.c @@ -0,0 +1,464 @@ +#include "config.h" + +#include +#include +#include + +#include + +#include + +#include + +static const gchar *empty_array = "[]"; +static const gchar *empty_object = "{}"; + +static const gchar *simple_array = "[true,false,null,42,\"foo\"]"; +static const gchar *nested_array = "[true,[false,null],42]"; + +static const gchar *simple_object = "{\"Bool1\":true,\"Bool2\":false,\"Null\":null,\"Int\":42,\"\":54,\"String\":\"foo\"}"; +/* taken from the RFC 4627, Examples section */ +static const gchar *nested_object = +"{" + "\"Image\":{" + "\"Width\":800," + "\"Height\":600," + "\"Title\":\"View from 15th Floor\"," + "\"Thumbnail\":{" + "\"Url\":\"http://www.example.com/image/481989943\"," + "\"Height\":125," + "\"Width\":\"100\"" + "}," + "\"IDs\":[116,943,234,38793]" + "}" +"}"; + +static const char *pretty_examples[] = { + "[\n]", + + "{\n}", + + "[\n" + "\ttrue,\n" + "\tfalse,\n" + "\tnull,\n" + "\t\"hello\"\n" + "]", + + "{\n" + "\t\"foo\" : 42,\n" + "\t\"bar\" : true,\n" + "\t\"baz\" : null\n" + "}", +}; + +static const int n_pretty_examples = G_N_ELEMENTS (pretty_examples); + +static const struct { + const gchar *lang; + const gchar *sep; + guint matches : 1; +} decimal_separator[] = { + { "C", ".", TRUE }, + { "de", ",", FALSE }, + { "en", ".", TRUE }, + { "fr", ",", FALSE } +}; + +static void +test_empty_array (void) +{ + JsonGenerator *gen = json_generator_new (); + JsonNode *root; + gchar *data; + gsize len; + + root = json_node_new (JSON_NODE_ARRAY); + json_node_take_array (root, json_array_new ()); + + json_generator_set_root (gen, root); + g_object_set (gen, "pretty", FALSE, "indent", 0, "indent-char", ' ', NULL); + + data = json_generator_to_data (gen, &len); + + g_assert_cmpint (len, ==, strlen (empty_array)); + g_assert_cmpstr (data, ==, empty_array); + + g_assert (json_generator_get_pretty (gen) == FALSE); + g_assert_cmpint (json_generator_get_indent (gen), ==, 0); + g_assert_cmpint (json_generator_get_indent_char (gen), ==, ' '); + + g_free (data); + json_node_free (root); + g_object_unref (gen); +} + +static void +test_empty_object (void) +{ + JsonGenerator *gen = json_generator_new (); + JsonNode *root; + gchar *data; + gsize len; + + root = json_node_new (JSON_NODE_OBJECT); + json_node_take_object (root, json_object_new ()); + + json_generator_set_root (gen, root); + g_object_set (gen, "pretty", FALSE, NULL); + + data = json_generator_to_data (gen, &len); + + g_assert_cmpint (len, ==, strlen (empty_object)); + g_assert_cmpstr (data, ==, empty_object); + + g_free (data); + json_node_free (root); + g_object_unref (gen); +} + +static void +test_simple_array (void) +{ + JsonGenerator *generator = json_generator_new (); + JsonNode *root; + JsonArray *array; + gchar *data; + gsize len; + + root = json_node_new (JSON_NODE_ARRAY); + array = json_array_sized_new (5); + + json_array_add_boolean_element (array, TRUE); + json_array_add_boolean_element (array, FALSE); + json_array_add_null_element (array); + json_array_add_int_element (array, 42); + json_array_add_string_element (array, "foo"); + + json_node_take_array (root, array); + json_generator_set_root (generator, root); + + g_object_set (generator, "pretty", FALSE, NULL); + data = json_generator_to_data (generator, &len); + + if (g_test_verbose ()) + g_print ("checking simple array `%s' (expected: %s)\n", + data, + simple_array); + + g_assert_cmpint (len, ==, strlen (simple_array)); + g_assert_cmpstr (data, ==, simple_array); + + g_free (data); + json_node_free (root); + g_object_unref (generator); +} + +static void +test_nested_array (void) +{ + JsonGenerator *generator = json_generator_new (); + JsonNode *root; + JsonArray *array, *nested; + gchar *data; + gsize len; + + root = json_node_new (JSON_NODE_ARRAY); + array = json_array_sized_new (3); + + json_array_add_boolean_element (array, TRUE); + + { + nested = json_array_sized_new (2); + + json_array_add_boolean_element (nested, FALSE); + json_array_add_null_element (nested); + + json_array_add_array_element (array, nested); + } + + json_array_add_int_element (array, 42); + + json_node_take_array (root, array); + json_generator_set_root (generator, root); + + g_object_set (generator, "pretty", FALSE, NULL); + data = json_generator_to_data (generator, &len); + + g_assert_cmpint (len, ==, strlen (nested_array)); + g_assert_cmpstr (data, ==, nested_array); + + g_free (data); + json_node_free (root); + g_object_unref (generator); +} + +static void +test_simple_object (void) +{ + JsonGenerator *generator = json_generator_new (); + JsonNode *root; + JsonObject *object; + gchar *data; + gsize len; + + root = json_node_new (JSON_NODE_OBJECT); + object = json_object_new (); + + json_object_set_boolean_member (object, "Bool1", TRUE); + json_object_set_boolean_member (object, "Bool2", FALSE); + json_object_set_null_member (object, "Null"); + json_object_set_int_member (object, "Int", 42); + json_object_set_int_member (object, "", 54); + json_object_set_string_member (object, "String", "foo"); + + json_node_take_object (root, object); + json_generator_set_root (generator, root); + + g_object_set (generator, "pretty", FALSE, NULL); + data = json_generator_to_data (generator, &len); + + if (g_test_verbose ()) + g_print ("checking simple object `%s' (expected: %s)\n", + data, + simple_object); + + g_assert_cmpint (len, ==, strlen (simple_object)); + g_assert_cmpstr (data, ==, simple_object); + + g_free (data); + json_node_free (root); + g_object_unref (generator); +} + +static void +test_nested_object (void) +{ + JsonGenerator *generator = json_generator_new (); + JsonNode *root; + JsonObject *object, *nested; + JsonArray *array; + gchar *data; + gsize len; + + root = json_node_new (JSON_NODE_OBJECT); + object = json_object_new (); + + json_object_set_int_member (object, "Width", 800); + json_object_set_int_member (object, "Height", 600); + json_object_set_string_member (object, "Title", "View from 15th Floor"); + + { + nested = json_object_new (); + + json_object_set_string_member (nested, "Url", "http://www.example.com/image/481989943"); + json_object_set_int_member (nested, "Height", 125); + json_object_set_string_member (nested, "Width", "100"); + + json_object_set_object_member (object, "Thumbnail", nested); + } + + { + array = json_array_new (); + + json_array_add_int_element (array, 116); + json_array_add_int_element (array, 943); + json_array_add_int_element (array, 234); + json_array_add_int_element (array, 38793); + + json_object_set_array_member (object, "IDs", array); + } + + nested = json_object_new (); + json_object_set_object_member (nested, "Image", object); + + json_node_take_object (root, nested); + json_generator_set_root (generator, root); + + g_object_set (generator, "pretty", FALSE, NULL); + data = json_generator_to_data (generator, &len); + + if (g_test_verbose ()) + g_print ("checking nested object `%s' (expected: %s)\n", + data, + nested_object); + + g_assert_cmpint (len, ==, strlen (nested_object)); + g_assert_cmpstr (data, ==, nested_object); + + g_free (data); + json_node_free (root); + g_object_unref (generator); +} + +static void +test_decimal_separator (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + JsonGenerator *generator = json_generator_new (); + gchar *old_locale; + gint i; + + json_node_set_double (node, 3.14); + + json_generator_set_root (generator, node); + + old_locale = setlocale (LC_NUMERIC, NULL); + + for (i = 0; i < G_N_ELEMENTS (decimal_separator); i++) + { + gchar *str, *expected; + + setlocale (LC_NUMERIC, decimal_separator[i].lang); + + str = json_generator_to_data (generator, NULL); + + if (g_test_verbose ()) + g_print ("%s: value: %.2f - string: '%s'\n", + G_STRFUNC, + json_node_get_double (node), + str); + + g_assert (str != NULL); + expected = strstr (str, decimal_separator[i].sep); + if (decimal_separator[i].matches) + g_assert (expected != NULL); + else + g_assert (expected == NULL); + + g_free (str); + } + + setlocale (LC_NUMERIC, old_locale); + + g_object_unref (generator); + json_node_free (node); +} + + +static void +test_double_stays_double (void) +{ + gchar *str; + JsonNode *node = json_node_new (JSON_NODE_VALUE); + JsonGenerator *generator = json_generator_new (); + + json_node_set_double (node, 1.0); + + json_generator_set_root (generator, node); + + str = json_generator_to_data (generator, NULL); + g_assert_cmpstr (str, ==, "1.0"); + + g_free (str); + g_object_unref (generator); + json_node_free (node); +} + + +static void +test_pretty (void) +{ + JsonParser *parser = json_parser_new (); + JsonGenerator *generator = json_generator_new (); + int i; + + json_generator_set_pretty (generator, TRUE); + json_generator_set_indent (generator, 1); + json_generator_set_indent_char (generator, '\t'); + + for (i = 0; i < n_pretty_examples; i++) + { + JsonNode *root; + char *data; + gsize len; + + g_assert (json_parser_load_from_data (parser, pretty_examples[i], -1, NULL)); + + root = json_parser_get_root (parser); + g_assert (root != NULL); + + json_generator_set_root (generator, root); + + data = json_generator_to_data (generator, &len); + + if (g_test_verbose ()) + g_print ("** checking pretty printing:\n%s\n** expected:\n%s\n", + data, + pretty_examples[i]); + + g_assert_cmpint (len, ==, strlen (pretty_examples[i])); + g_assert_cmpstr (data, ==, pretty_examples[i]); + + g_free (data); + } + + g_object_unref (generator); + g_object_unref (parser); +} + +typedef struct { + const gchar *str; + const gchar *expect; +} FixtureString; + +static const FixtureString string_fixtures[] = { + { "abc", "\"abc\"" }, + { "a\x7fxc", "\"a\\u007fxc\"" }, + { "a\033xc", "\"a\\u001bxc\"" }, + { "a\nxc", "\"a\\nxc\"" }, + { "a\\xc", "\"a\\\\xc\"" }, + { "Barney B\303\244r", "\"Barney B\303\244r\"" }, +}; + +static void +test_string_encode (gconstpointer data) +{ + const FixtureString *fixture = data; + JsonGenerator *generator = json_generator_new (); + JsonNode *node; + gsize length; + gchar *output; + + node = json_node_init_string (json_node_alloc (), fixture->str);\ + json_generator_set_root (generator, node); + + output = json_generator_to_data (generator, &length); + g_assert_cmpstr (output, ==, fixture->expect); + g_assert_cmpuint (length, ==, strlen (fixture->expect)); + g_free (output); + json_node_free (node); + + g_object_unref (generator); +} +int +main (int argc, + char *argv[]) +{ + gchar *escaped; + gchar *name; + gint i; + + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/generator/empty-array", test_empty_array); + g_test_add_func ("/generator/empty-object", test_empty_object); + g_test_add_func ("/generator/simple-array", test_simple_array); + g_test_add_func ("/generator/nested-array", test_nested_array); + g_test_add_func ("/generator/simple-object", test_simple_object); + g_test_add_func ("/generator/nested-object", test_nested_object); + g_test_add_func ("/generator/decimal-separator", test_decimal_separator); + g_test_add_func ("/generator/double-stays-double", test_double_stays_double); + g_test_add_func ("/generator/pretty", test_pretty); + + for (i = 0; i < G_N_ELEMENTS (string_fixtures); i++) + { + escaped = g_strescape (string_fixtures[i].str, NULL); + name = g_strdup_printf ("/generator/string/%s", escaped); + g_test_add_data_func (name, string_fixtures + i, test_string_encode); + g_free (escaped); + g_free (name); + } + + return g_test_run (); +} diff --git a/json-glib/tests/gvariant.c b/json-glib/tests/gvariant.c new file mode 100644 index 0000000..e88b1b9 --- /dev/null +++ b/json-glib/tests/gvariant.c @@ -0,0 +1,259 @@ +#include +#include +#include + +typedef struct +{ + gchar *test_name; + gchar *signature; + gchar *variant_data; + gchar *json_data; +} TestCase; + +/* each entry in this list spawns to a GVariant-to-JSON and + JSON-to-GVariant test */ +static const TestCase two_way_test_cases[] = + { + /* boolean */ + { "/boolean", "(b)", "(true,)", "[true]" }, + + /* byte */ + { "/byte", "(y)", "(byte 0xff,)", "[255]" }, + + /* int16 */ + { "/int16", "(n)", "(int16 -12345,)", "[-12345]" }, + + /* uint16 */ + { "/uint16", "(q)", "(uint16 40001,)", "[40001]" }, + + /* int32 */ + { "/int32", "(i)", "(-7654321,)", "[-7654321]" }, + + /* uint32 */ + { "/uint32", "(u)", "(uint32 12345678,)", "[12345678]" }, + + /* int64 */ + { "/int64", "(x)", "(int64 -666999666999,)", "[-666999666999]" }, + + /* uint64 */ + { "/uint64", "(t)", "(uint64 1999999999999999,)", "[1999999999999999]" }, + + /* handle */ + { "/handle", "(h)", "(handle 1,)", "[1]" }, + + /* double */ + { "/double", "(d)", "(1.23,)", "[1.23]" }, + + /* double */ + { "/double-whole", "(d)", "(123.0,)", "[123.0]" }, + + /* string */ + { "/string", "(s)", "('hello world!',)", "[\"hello world!\"]" }, + + /* object-path */ + { "/object-path", "(o)", "(objectpath '/org/gtk/json_glib',)", "[\"/org/gtk/json_glib\"]" }, + + /* signature */ + { "/signature", "(g)", "(signature '(asna{sv}i)',)", "[\"(asna{sv}i)\"]" }, + + /* maybe - null string */ + { "/maybe/simple/null", "(ms)", "(@ms nothing,)", "[null]" }, + + /* maybe - simple string */ + { "/maybe/simple/string", "(ms)", "(@ms 'maybe string',)", "[\"maybe string\"]" }, + + /* maybe - null container */ + { "/maybe/container/null", "(m(sn))", "(@m(sn) nothing,)", "[null]" }, + + /* maybe - tuple container */ + { "/maybe/container/tuple", "(m(sn))", "(@m(sn) ('foo', 0),)", "[[\"foo\",0]]" }, + + /* maybe - variant boolean */ + { "/maybe/variant/boolean", "(mv)", "(@mv ,)", "[true]" }, + + /* empty array */ + { "/array/empty", "as", "@as []", "[]" }, + + /* array of bytes */ + { "/array/byte", "ay", "[byte 0x01, 0x0a, 0x03, 0xff]", "[1,10,3,255]" }, + + /* array of strings */ + { "/array/string", "as", "['a', 'b', 'ab', 'ba']", "[\"a\",\"b\",\"ab\",\"ba\"]" }, + + /* array of array of int32 */ + { "/array/array/int32", "aai", "[[1, 2], [3, 4], [5, 6]]", "[[1,2],[3,4],[5,6]]" }, + + /* array of variants */ + { "/array/variant", "av", "[, , <'oops'>, , <0.5>]", "[true,1,\"oops\",-2,0.5]" }, + + /* tuple */ + { "/tuple", "(bynqiuxthds)", + "(false, byte 0x00, int16 -1, uint16 1, -2, uint32 2, int64 429496729, uint64 3, handle 16, 2.48, 'end')", + "[false,0,-1,1,-2,2,429496729,3,16,2.48,\"end\"]" }, + + /* empty dictionary */ + { "/dictionary/empty", "a{sv}", "@a{sv} {}", "{}" }, + + /* single dictionary entry */ + { "/dictionary/single-entry", "{ss}", "{'hello', 'world'}", "{\"hello\":\"world\"}" }, + + /* dictionary - string : int32 */ + { "/dictionary/string-int32", "a{si}", "{'foo': 1, 'bar': 2}", "{\"foo\":1,\"bar\":2}" }, + + /* dictionary - string : variant */ + { "/dictionary/string-variant", "a{sv}", "{'str': <'hi!'>, 'bool': }", "{\"str\":\"hi!\",\"bool\":true}" }, + + /* dictionary - int64 : variant */ + { "/dictionary/int64-variant", "a{xv}", + "{int64 -5: <'minus five'>, 10: <'ten'>}", "{\"-5\":\"minus five\",\"10\":\"ten\"}" }, + + /* dictionary - uint64 : variant */ + { "/dictionary/uint64-boolean", "a{tb}", + "{uint64 999888777666: true, 0: false}", "{\"999888777666\":true,\"0\":false}" }, + + /* dictionary - boolean : variant */ + { "/dictionary/boolean-variant", "a{by}", "{true: byte 0x01, false: 0x00}", "{\"true\":1,\"false\":0}" }, + + /* dictionary - double : string */ + { "/dictionary/double-string", "a{ds}", "{1.0: 'one point zero'}", "{\"1.000000\":\"one point zero\"}" }, + + /* variant - string */ + { "/variant/string", "(v)", "(<'string within variant'>,)", "[\"string within variant\"]" }, + + /* variant - maybe null */ + { "/variant/maybe/null", "(v)", "(<@mv nothing>,)", "[null]" }, + + /* variant - dictionary */ + { "/variant/dictionary", "v", "<{'foo': <'bar'>, 'hi': }>", "{\"foo\":\"bar\",\"hi\":1024}" }, + + /* variant - variant - array */ + { "/variant/variant/array", "v", "<[<'any'>, <'thing'>, , ]>", "[\"any\",\"thing\",0,-1]" }, + + /* deep-nesting */ + { "/deep-nesting", + "a(a(a(a(a(a(a(a(a(a(s))))))))))", + "[([([([([([([([([([('sorprise',)],)],)],)],)],)],)],)],)],)]", + "[[[[[[[[[[[[[[[[[[[[\"sorprise\"]]]]]]]]]]]]]]]]]]]]" }, + + /* mixed1 */ + { "/mixed1", + "a{s(syba(od))}", + "{'foo': ('bar', byte 0x64, true, [(objectpath '/baz', 1.3), ('/cat', -2.5)])}", + "{\"foo\":[\"bar\",100,true,[[\"/baz\",1.3],[\"/cat\",-2.5]]]}" }, + + /* mixed2 */ + { "/mixed2", + "(a{by}amsvmaba{qm(sg)})", + "({true: byte 0x01, false: 0x00}, [@ms 'do', nothing, 'did'], <@av []>, @mab nothing, {uint16 10000: @m(sg) ('yes', 'august'), 0: nothing})", + "[{\"true\":1,\"false\":0},[\"do\",null,\"did\"],[],null,{\"10000\":[\"yes\",\"august\"],\"0\":null}]" }, + }; + +static const TestCase json_to_gvariant_test_cases[] = + { + { "/string-to-boolean", "(b)", "(true,)", "[\"true\"]" }, + { "/string-to-byte", "(y)", "(byte 0xff,)", "[\"255\"]" }, + { "/string-to-int16", "(n)", "(int16 -12345,)", "[\"-12345\"]" }, + { "/string-to-uint16", "(q)", "(uint16 40001,)", "[\"40001\"]" }, + { "/string-to-int32", "(i)", "(-7654321,)", "[\"-7654321\"]" }, + { "/string-to-int64", "(x)", "(int64 -666999666999,)", "[\"-666999666999\"]" }, + { "/string-to-uint64", "(t)", "(uint64 1999999999999999,)", "[\"1999999999999999\"]" }, + { "/string-to-double", "(d)", "(1.23,)", "[\"1.23\"]" }, + { "/string-to-double-whole", "(d)", "(123.0,)", "[\"123.0\"]" }, + }; + +static void +test_gvariant_to_json (gconstpointer test_data) +{ + TestCase *test_case = (TestCase *) test_data; + GVariant *variant; + gchar *json_data; + gsize len; + + variant = g_variant_parse (G_VARIANT_TYPE (test_case->signature), + test_case->variant_data, + NULL, + NULL, + NULL); + + json_data = json_gvariant_serialize_data (variant, &len); + g_assert (json_data != NULL); + + g_assert_cmpstr (test_case->json_data, ==, json_data); + + g_free (json_data); + g_variant_unref (variant); +} + +static void +test_json_to_gvariant (gconstpointer test_data) +{ + TestCase *test_case = (TestCase *) test_data; + GVariant *variant; + gchar *variant_data; + GError *error = NULL; + + variant = json_gvariant_deserialize_data (test_case->json_data, + -1, + test_case->signature, + &error); + + if (variant == NULL) + { + g_assert_no_error (error); + g_error_free (error); + } + else + { + variant_data = g_variant_print (variant, TRUE); + + g_assert_cmpstr (test_case->variant_data, ==, variant_data); + + g_free (variant_data); + g_variant_unref (variant); + } +} + +gint +main (gint argc, gchar *argv[]) +{ + gint i; + TestCase test_case; + gchar *test_name; + + g_test_init (&argc, &argv, NULL); + + /* GVariant to JSON */ + for (i = 0; i < G_N_ELEMENTS (two_way_test_cases); i++) + { + test_case = two_way_test_cases[i]; + test_name = g_strdup_printf ("/gvariant/to-json/%s", test_case.test_name); + + g_test_add_data_func (test_name, &two_way_test_cases[i], test_gvariant_to_json); + + g_free (test_name); + } + + /* JSON to GVariant */ + for (i = 0; i < G_N_ELEMENTS (two_way_test_cases); i++) + { + test_case = two_way_test_cases[i]; + test_name = g_strdup_printf ("/gvariant/from-json/%s", test_case.test_name); + + g_test_add_data_func (test_name, &two_way_test_cases[i], test_json_to_gvariant); + + g_free (test_name); + } + + /* JSON to GVariant one way tests */ + for (i = 0; i < G_N_ELEMENTS (json_to_gvariant_test_cases); i++) + { + test_case = json_to_gvariant_test_cases[i]; + test_name = g_strdup_printf ("/gvariant/from-json/%s", test_case.test_name); + + g_test_add_data_func (test_name, &json_to_gvariant_test_cases[i], test_json_to_gvariant); + + g_free (test_name); + } + + return g_test_run (); +} diff --git a/json-glib/tests/invalid.c b/json-glib/tests/invalid.c new file mode 100644 index 0000000..b782566 --- /dev/null +++ b/json-glib/tests/invalid.c @@ -0,0 +1,268 @@ +#include "config.h" + +#include +#include + +#include + +#include + +static void +test_invalid_bareword (gconstpointer user_data) +{ + const char *json = user_data; + GError *error = NULL; + JsonParser *parser; + gboolean res; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("invalid data: '%s'...", json); + + res = json_parser_load_from_data (parser, json, -1, &error); + + g_assert (!res); + g_assert_error (error, JSON_PARSER_ERROR, JSON_PARSER_ERROR_INVALID_BAREWORD); + + if (g_test_verbose ()) + g_print ("expected error: %s\n", error->message); + + g_clear_error (&error); + + g_object_unref (parser); +} + +static void +test_invalid_assignment (gconstpointer user_data) +{ + const char *json = user_data; + GError *error = NULL; + JsonParser *parser; + gboolean res; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("invalid data: '%s'...", json); + + res = json_parser_load_from_data (parser, json, -1, &error); + + g_assert (!res); + g_assert (error != NULL); + + if (g_test_verbose ()) + g_print ("expected error: %s\n", error->message); + + g_clear_error (&error); + + g_object_unref (parser); +} + +static void +test_invalid_value (gconstpointer user_data) +{ + const char *json = user_data; + GError *error = NULL; + JsonParser *parser; + gboolean res; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("invalid data: '%s'...", json); + + res = json_parser_load_from_data (parser, json, -1, &error); + + g_assert (!res); + g_assert (error != NULL); + + if (g_test_verbose ()) + g_print ("expected error: %s\n", error->message); + + g_clear_error (&error); + + g_object_unref (parser); +} + +static void +test_invalid_array (gconstpointer user_data) +{ + const char *json = user_data; + GError *error = NULL; + JsonParser *parser; + gboolean res; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("invalid data: '%s'...", json); + + res = json_parser_load_from_data (parser, json, -1, &error); + + g_assert (!res); + g_assert (error != NULL); + + if (g_test_verbose ()) + g_print ("expected error: %s\n", error->message); + + g_clear_error (&error); + + g_object_unref (parser); +} + +static void +test_invalid_object (gconstpointer user_data) +{ + const char *json = user_data; + GError *error = NULL; + JsonParser *parser; + gboolean res; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("invalid data: '%s'...", json); + + res = json_parser_load_from_data (parser, json, -1, &error); + + g_assert (!res); + g_assert (error != NULL); + + if (g_test_verbose ()) + g_print ("expected error: %s\n", error->message); + + g_clear_error (&error); + + g_object_unref (parser); +} + +static void +test_missing_comma (gconstpointer user_data) +{ + const char *json = user_data; + GError *error = NULL; + JsonParser *parser; + gboolean res; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("invalid data: '%s'...", json); + + res = json_parser_load_from_data (parser, json, -1, &error); + + g_assert (!res); + g_assert_error (error, JSON_PARSER_ERROR, JSON_PARSER_ERROR_MISSING_COMMA); + + if (g_test_verbose ()) + g_print ("expected error: %s\n", error->message); + + g_clear_error (&error); + + g_object_unref (parser); +} + +static void +test_trailing_comma (gconstpointer user_data) +{ + const char *json = user_data; + GError *error = NULL; + JsonParser *parser; + gboolean res; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("invalid data: '%s'...", json); + + res = json_parser_load_from_data (parser, json, -1, &error); + + g_assert (!res); + g_assert_error (error, JSON_PARSER_ERROR, JSON_PARSER_ERROR_TRAILING_COMMA); + + if (g_test_verbose ()) + g_print ("expected error: %s\n", error->message); + + g_clear_error (&error); + + g_object_unref (parser); +} + +static const struct +{ + const char *path; + const char *json; + gpointer func; +} test_invalid[] = { + /* bareword */ + { "bareword-1", "rainbows", test_invalid_bareword }, + { "bareword-2", "[ unicorns ]", test_invalid_bareword }, + { "bareword-3", "{ \"foo\" : ponies }", test_invalid_bareword }, + { "bareword-4", "[ 3, 2, 1, lift_off ]", test_invalid_bareword }, + { "bareword-5", "{ foo : 42 }", test_invalid_bareword }, + + /* values */ + { "values-1", "[ -false ]", test_invalid_value }, + + /* assignment */ + { "assignment-1", "var foo", test_invalid_assignment }, + { "assignment-2", "var foo = no", test_invalid_assignment }, + { "assignment-3", "var = true", test_invalid_assignment }, + { "assignment-4", "var blah = 42:", test_invalid_assignment }, + { "assignment-5", "let foo = true;", test_invalid_assignment }, + + /* arrays */ + { "array-1", "[ true, false", test_invalid_array }, + { "array-2", "[ true }", test_invalid_array }, + { "array-3", "[ \"foo\" : 42 ]", test_invalid_array }, + + /* objects */ + { "object-1", "{ foo : 42 }", test_invalid_object }, + { "object-2", "{ 42 : \"foo\" }", test_invalid_object }, + { "object-3", "{ \"foo\", 42 }", test_invalid_object }, + { "object-4", "{ \"foo\" : 42 ]", test_invalid_object }, + { "object-5", "{ \"blah\" }", test_invalid_object }, + { "object-6", "{ \"a\" : 0 \"b\" : 1 }", test_invalid_object }, + { "object-7", "{ null: false }", test_invalid_object }, + + /* missing commas */ + { "missing-comma-1", "[ true false ]", test_missing_comma }, + { "missing-comma-2", "{ \"foo\" : 42 \"bar\": null }", test_missing_comma }, + + /* trailing commas */ + { "trailing-comma-1", "[ true, ]", test_trailing_comma }, + { "trailing-comma-2", "{ \"foo\" : 42, }", test_trailing_comma }, +}; + +static guint n_test_invalid = G_N_ELEMENTS (test_invalid); + +int +main (int argc, + char *argv[]) +{ + int i; + + g_test_init (&argc, &argv, NULL); + + for (i = 0; i < n_test_invalid; i++) + { + char *test_path = g_strconcat ("/invalid/json/", test_invalid[i].path, NULL); + + g_test_add_data_func_full (test_path, + (gpointer) test_invalid[i].json, + test_invalid[i].func, + NULL); + + g_free (test_path); + } + + return g_test_run (); +} diff --git a/json-glib/tests/json-test-utils.h b/json-glib/tests/json-test-utils.h new file mode 100644 index 0000000..83a02c6 --- /dev/null +++ b/json-glib/tests/json-test-utils.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +#define json_fuzzy_equals(n1,n2,epsilon) \ + (((n1) > (n2) ? ((n1) - (n2)) : ((n2) - (n1))) < (epsilon)) + +#define json_assert_fuzzy_equals(n1,n2,epsilon) \ + G_STMT_START { \ + double __n1 = (n1), __n2 = (n2), __epsilon = (epsilon); \ + if (json_fuzzy_equals (__n1, __n2, __epsilon)) ; else { \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #n1 " == " #n2 " (+/- " #epsilon ")", \ + __n1, "==", __n2, 'f'); \ + } \ + } G_STMT_END + +#define json_assert_almost_equals(n1,n2) \ + json_assert_fuzzy_equals (n1, n2, DBL_EPSILON) diff --git a/json-glib/tests/meson.build b/json-glib/tests/meson.build new file mode 100644 index 0000000..a80e8ce --- /dev/null +++ b/json-glib/tests/meson.build @@ -0,0 +1,54 @@ +tests = [ + 'array', + 'boxed', + 'builder', + 'generator', + 'gvariant', + 'invalid', + 'node', + 'object', + 'parser', + 'path', + 'reader', + 'serialize-simple', + 'serialize-complex', + 'serialize-full', +] + +test_data = [ + 'stream-load.json', +] + +installed_test_bindir = join_paths(json_libexecdir, 'installed-tests', json_api_name) +installed_test_datadir = join_paths(json_datadir, 'installed-tests', json_api_name) + +install_data(test_data, install_dir: installed_test_bindir) + +foreach t: tests + installed_test = '@0@.test'.format(t) + data = custom_target(installed_test, + output: installed_test, + command: [ + python3, + gen_installed_test, + '--testdir=@0@'.format(installed_test_bindir), + '--testname=@0@'.format(t), + '--outdir=@OUTDIR@', + '--outfile=@0@'.format(installed_test), + ], + install: true, + install_dir: installed_test_datadir) + + exe = executable(t, '@0@.c'.format(t), + c_args: json_c_args, + install: true, + install_dir: installed_test_bindir, + dependencies: [ json_glib_dep, ]) + + test(t, exe, + args: [ '--tap', '-k' ], + env: [ + 'G_TEST_SRCDIR=@0@'.format(meson.current_source_dir()), + 'G_TEST_BUILDDIR=@0@'.format(meson.current_build_dir()), + ]) +endforeach diff --git a/json-glib/tests/node.c b/json-glib/tests/node.c new file mode 100644 index 0000000..80beb78 --- /dev/null +++ b/json-glib/tests/node.c @@ -0,0 +1,583 @@ +#include "json-test-utils.h" + +static void +test_init_int (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + + json_node_set_int (node, 42); + g_assert_cmpint (json_node_get_int (node), ==, 42); + + json_node_free (node); +} + +static void +test_init_double (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + + json_node_set_double (node, 3.14159); + json_assert_fuzzy_equals (json_node_get_double (node), 3.14159, 0.00001); + + json_node_free (node); +} + +static void +test_init_boolean (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + + json_node_set_boolean (node, TRUE); + g_assert (json_node_get_boolean (node)); + + json_node_free (node); +} + +static void +test_init_string (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + + json_node_set_string (node, "Hello, World"); + g_assert_cmpstr (json_node_get_string (node), ==, "Hello, World"); + + json_node_free (node); +} + +static void +test_copy_null (void) +{ + JsonNode *node = json_node_new (JSON_NODE_NULL); + JsonNode *copy = json_node_copy (node); + + g_assert_cmpint (json_node_get_node_type (node), ==, json_node_get_node_type (copy)); + g_assert_cmpint (json_node_get_value_type (node), ==, json_node_get_value_type (copy)); + g_assert_cmpstr (json_node_type_name (node), ==, json_node_type_name (copy)); + + json_node_free (copy); + json_node_free (node); +} + +static void +test_copy_value (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + JsonNode *copy; + + json_node_set_string (node, "hello"); + + copy = json_node_copy (node); + g_assert_cmpint (json_node_get_node_type (node), ==, json_node_get_node_type (copy)); + g_assert_cmpstr (json_node_type_name (node), ==, json_node_type_name (copy)); + g_assert_cmpstr (json_node_get_string (node), ==, json_node_get_string (copy)); + + json_node_free (copy); + json_node_free (node); +} + +static void +test_copy_object (void) +{ + JsonObject *obj = json_object_new (); + JsonNode *node = json_node_new (JSON_NODE_OBJECT); + JsonNode *value = json_node_new (JSON_NODE_VALUE); + JsonNode *copy; + + json_node_set_int (value, 42); + json_object_set_member (obj, "answer", value); + + json_node_take_object (node, obj); + + copy = json_node_copy (node); + + g_assert_cmpint (json_node_get_node_type (node), ==, json_node_get_node_type (copy)); + g_assert (json_node_get_object (node) == json_node_get_object (copy)); + + json_node_free (copy); + json_node_free (node); +} + +static void +test_null (void) +{ + JsonNode *node = json_node_new (JSON_NODE_NULL); + + g_assert (JSON_NODE_HOLDS_NULL (node)); + g_assert (json_node_is_null (node)); + g_assert_cmpint (json_node_get_value_type (node), ==, G_TYPE_INVALID); + g_assert_cmpstr (json_node_type_name (node), ==, "NULL"); + + json_node_free (node); +} + +static void +test_get_int (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + + json_node_set_int (node, 0); + g_assert_cmpint (json_node_get_int (node), ==, 0); + json_assert_almost_equals (json_node_get_double (node), 0.0); + g_assert (!json_node_get_boolean (node)); + g_assert (!json_node_is_null (node)); + + json_node_set_int (node, 42); + g_assert_cmpint (json_node_get_int (node), ==, 42); + json_assert_almost_equals (json_node_get_double (node), 42.0); + g_assert (json_node_get_boolean (node)); + g_assert (!json_node_is_null (node)); + + json_node_free (node); +} + +static void +test_get_double (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + + json_node_set_double (node, 3.14); + json_assert_fuzzy_equals (json_node_get_double (node), 3.14, 0.001); + g_assert_cmpint (json_node_get_int (node), ==, 3); + g_assert (json_node_get_boolean (node)); + + json_node_free (node); +} + +static void +test_gvalue (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + GValue value = { 0, }; + GValue check = { 0, }; + + g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE); + + g_value_init (&value, G_TYPE_INT64); + g_value_set_int64 (&value, 42); + + g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_TYPE_INT64); + g_assert_cmpint (g_value_get_int64 (&value), ==, 42); + + json_node_set_value (node, &value); + json_node_get_value (node, &check); + + g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_VALUE_TYPE (&check)); + g_assert_cmpint (g_value_get_int64 (&value), ==, g_value_get_int64 (&check)); + g_assert_cmpint (G_VALUE_TYPE (&check), ==, G_TYPE_INT64); + g_assert_cmpint (g_value_get_int64 (&check), ==, 42); + + g_value_unset (&value); + g_value_unset (&check); + + g_value_init (&value, G_TYPE_STRING); + g_value_set_string (&value, "Hello, World!"); + + g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_TYPE_STRING); + g_assert_cmpstr (g_value_get_string (&value), ==, "Hello, World!"); + + json_node_set_value (node, &value); + json_node_get_value (node, &check); + + g_assert_cmpint (G_VALUE_TYPE (&value), ==, G_VALUE_TYPE (&check)); + g_assert_cmpstr (g_value_get_string (&value), ==, g_value_get_string (&check)); + g_assert_cmpint (G_VALUE_TYPE (&check), ==, G_TYPE_STRING); + g_assert_cmpstr (g_value_get_string (&check), ==, "Hello, World!"); + + g_value_unset (&value); + g_value_unset (&check); + json_node_free (node); +} + +static void +test_gvalue_autopromotion (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + GValue value = { 0, }; + GValue check = { 0, }; + + g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE); + + if (g_test_verbose ()) + g_print ("Autopromotion of int to int64\n"); + + g_value_init (&value, G_TYPE_INT); + g_value_set_int (&value, 42); + + json_node_set_value (node, &value); + json_node_get_value (node, &check); + + if (g_test_verbose ()) + g_print ("Expecting an gint64, got a %s\n", g_type_name (G_VALUE_TYPE (&check))); + + g_assert_cmpint (G_VALUE_TYPE (&check), ==, G_TYPE_INT64); + g_assert_cmpint (g_value_get_int64 (&check), ==, 42); + g_assert_cmpint (G_VALUE_TYPE (&value), !=, G_VALUE_TYPE (&check)); + g_assert_cmpint ((gint64) g_value_get_int (&value), ==, g_value_get_int64 (&check)); + + g_value_unset (&value); + g_value_unset (&check); + + if (g_test_verbose ()) + g_print ("Autopromotion of float to double\n"); + + g_value_init (&value, G_TYPE_FLOAT); + g_value_set_float (&value, 3.14159f); + + json_node_set_value (node, &value); + json_node_get_value (node, &check); + + if (g_test_verbose ()) + g_print ("Expecting a gdouble, got a %s\n", g_type_name (G_VALUE_TYPE (&check))); + + g_assert_cmpint (G_VALUE_TYPE (&check), ==, G_TYPE_DOUBLE); + json_assert_fuzzy_equals (g_value_get_double (&check), 3.14159, 0.00001); + g_assert_cmpint (G_VALUE_TYPE (&value), !=, G_VALUE_TYPE (&check)); + json_assert_almost_equals (g_value_get_float (&value), g_value_get_double (&check)); + + g_value_unset (&value); + g_value_unset (&check); + + json_node_free (node); +} + +/* Test that creating then sealing a node containing an int causes it to be + * immutable. */ +static void +test_seal_int (void) +{ + JsonNode *node = NULL; + + node = json_node_init_int (json_node_alloc (), 1); + + g_assert_false (json_node_is_immutable (node)); + json_node_seal (node); + g_assert_true (json_node_is_immutable (node)); + json_node_free (node); +} + +/* Test that creating then sealing a node containing a double causes it to be + * immutable. */ +static void +test_seal_double (void) +{ + JsonNode *node = NULL; + + node = json_node_init_double (json_node_alloc (), 15.2); + g_assert_false (json_node_is_immutable (node)); + json_node_seal (node); + g_assert_true (json_node_is_immutable (node)); + json_node_free (node); +} + +/* Test that creating then sealing a node containing a boolean causes it to be + * immutable. */ +static void +test_seal_boolean (void) +{ + JsonNode *node = NULL; + + node = json_node_init_boolean (json_node_alloc (), TRUE); + g_assert_false (json_node_is_immutable (node)); + json_node_seal (node); + g_assert_true (json_node_is_immutable (node)); + json_node_free (node); +} + +/* Test that creating then sealing a node containing a string causes it to be + * immutable. */ +static void +test_seal_string (void) +{ + JsonNode *node = NULL; + + node = json_node_init_string (json_node_alloc (), "hi there"); + g_assert_false (json_node_is_immutable (node)); + json_node_seal (node); + g_assert_true (json_node_is_immutable (node)); + json_node_free (node); +} + +/* Test that creating then sealing a node containing a null causes it to be + * immutable. */ +static void +test_seal_null (void) +{ + JsonNode *node = NULL; + + node = json_node_init_null (json_node_alloc ()); + g_assert_false (json_node_is_immutable (node)); + json_node_seal (node); + g_assert_true (json_node_is_immutable (node)); + json_node_free (node); +} + +/* Test that creating then sealing a node containing an object causes it to be + * immutable. */ +static void +test_seal_object (void) +{ + JsonNode *node = NULL; + JsonObject *object = NULL; + + object = json_object_new (); + node = json_node_init_object (json_node_alloc (), object); + + g_assert_false (json_object_is_immutable (object)); + g_assert_false (json_node_is_immutable (node)); + json_node_seal (node); + g_assert_true (json_node_is_immutable (node)); + g_assert_true (json_object_is_immutable (object)); + + json_node_free (node); + json_object_unref (object); +} + +/* Test that creating then sealing a node containing an array causes it to be + * immutable. */ +static void +test_seal_array (void) +{ + JsonNode *node = NULL; + JsonArray *array = NULL; + + array = json_array_new (); + node = json_node_init_array (json_node_alloc (), array); + + g_assert_false (json_array_is_immutable (array)); + g_assert_false (json_node_is_immutable (node)); + json_node_seal (node); + g_assert_true (json_node_is_immutable (node)); + g_assert_true (json_array_is_immutable (array)); + + json_node_free (node); + json_array_unref (array); +} + +/* Test that an immutable node containing an int cannot be modified. */ +static void +test_immutable_int (void) +{ + if (g_test_subprocess ()) + { + JsonNode *node = NULL; + + node = json_node_init_int (json_node_alloc (), 5); + json_node_seal (node); + + /* Boom. */ + json_node_set_int (node, 1); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Json-CRITICAL **: json_node_set_int: " + "assertion '!node->immutable' failed*"); +} + +/* Test that an immutable node containing a double cannot be modified. */ +static void +test_immutable_double (void) +{ + if (g_test_subprocess ()) + { + JsonNode *node = NULL; + + node = json_node_init_double (json_node_alloc (), 5.6); + json_node_seal (node); + + /* Boom. */ + json_node_set_double (node, 1.1); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Json-CRITICAL **: json_node_set_double: " + "assertion '!node->immutable' failed*"); +} + +/* Test that an immutable node containing a boolean cannot be modified. */ +static void +test_immutable_boolean (void) +{ + if (g_test_subprocess ()) + { + JsonNode *node = NULL; + + node = json_node_init_boolean (json_node_alloc (), TRUE); + json_node_seal (node); + + /* Boom. */ + json_node_set_boolean (node, FALSE); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Json-CRITICAL **: json_node_set_boolean: " + "assertion '!node->immutable' failed*"); +} + +/* Test that an immutable node containing a string cannot be modified. */ +static void +test_immutable_string (void) +{ + if (g_test_subprocess ()) + { + JsonNode *node = NULL; + + node = json_node_init_string (json_node_alloc (), "bonghits"); + json_node_seal (node); + + /* Boom. */ + json_node_set_string (node, "asdasd"); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Json-CRITICAL **: json_node_set_string: " + "assertion '!node->immutable' failed*"); +} + +/* Test that an immutable node containing an object cannot be modified. */ +static void +test_immutable_object (void) +{ + if (g_test_subprocess ()) + { + JsonNode *node = NULL; + + node = json_node_init_object (json_node_alloc (), json_object_new ()); + json_node_seal (node); + + /* Boom. */ + json_node_set_object (node, json_object_new ()); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Json-CRITICAL **: json_node_set_object: " + "assertion '!node->immutable' failed*"); +} + +/* Test that an immutable node containing an array cannot be modified. */ +static void +test_immutable_array (void) +{ + if (g_test_subprocess ()) + { + JsonNode *node = NULL; + + node = json_node_init_array (json_node_alloc (), json_array_new ()); + json_node_seal (node); + + /* Boom. */ + json_node_set_array (node, json_array_new ()); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Json-CRITICAL **: json_node_set_array: " + "assertion '!node->immutable' failed*"); +} + +/* Test that an immutable node containing a value cannot be modified. */ +static void +test_immutable_value (void) +{ + if (g_test_subprocess ()) + { + JsonNode *node = NULL; + GValue val = G_VALUE_INIT; + + node = json_node_init_int (json_node_alloc (), 5); + json_node_seal (node); + + /* Boom. */ + g_value_init (&val, G_TYPE_INT); + g_value_set_int (&val, 50); + json_node_set_value (node, &val); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Json-CRITICAL **: json_node_set_value: " + "assertion '!node->immutable' failed*"); +} + +/* Test that an immutable node can be reparented but not to an immutable + * parent. */ +static void +test_immutable_parent (void) +{ + if (g_test_subprocess ()) + { + JsonNode *node = NULL; + JsonNode *parent_mutable = NULL; + JsonNode *parent_immutable = NULL; + JsonObject *object_mutable = NULL; + JsonObject *object_immutable = NULL; + + node = json_node_init_int (json_node_alloc (), 5); + json_node_seal (node); + + object_mutable = json_object_new (); + object_immutable = json_object_new (); + + parent_mutable = json_node_init_object (json_node_alloc (), + object_mutable); + parent_immutable = json_node_init_object (json_node_alloc (), + object_immutable); + + json_node_seal (parent_immutable); + + /* Can we reparent the immutable node? */ + json_object_set_member (object_mutable, "test", node); + json_node_set_parent (node, parent_mutable); + + json_object_remove_member (object_mutable, "test"); + json_node_set_parent (node, NULL); + + /* Boom. */ + json_node_set_parent (node, parent_immutable); + } + + g_test_trap_subprocess (NULL, 0, 0); + g_test_trap_assert_failed (); + g_test_trap_assert_stderr ("*Json-CRITICAL **: json_node_set_parent: *"); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/nodes/init/int", test_init_int); + g_test_add_func ("/nodes/init/double", test_init_double); + g_test_add_func ("/nodes/init/boolean", test_init_boolean); + g_test_add_func ("/nodes/init/string", test_init_string); + g_test_add_func ("/nodes/init/null", test_null); + g_test_add_func ("/nodes/copy/null", test_copy_null); + g_test_add_func ("/nodes/copy/value", test_copy_value); + g_test_add_func ("/nodes/copy/object", test_copy_object); + g_test_add_func ("/nodes/get/int", test_get_int); + g_test_add_func ("/nodes/get/double", test_get_double); + g_test_add_func ("/nodes/gvalue", test_gvalue); + g_test_add_func ("/nodes/gvalue/autopromotion", test_gvalue_autopromotion); + g_test_add_func ("/nodes/seal/int", test_seal_int); + g_test_add_func ("/nodes/seal/double", test_seal_double); + g_test_add_func ("/nodes/seal/boolean", test_seal_boolean); + g_test_add_func ("/nodes/seal/string", test_seal_string); + g_test_add_func ("/nodes/seal/null", test_seal_null); + g_test_add_func ("/nodes/seal/object", test_seal_object); + g_test_add_func ("/nodes/seal/array", test_seal_array); + g_test_add_func ("/nodes/immutable/int", test_immutable_int); + g_test_add_func ("/nodes/immutable/double", test_immutable_double); + g_test_add_func ("/nodes/immutable/boolean", test_immutable_boolean); + g_test_add_func ("/nodes/immutable/string", test_immutable_string); + g_test_add_func ("/nodes/immutable/object", test_immutable_object); + g_test_add_func ("/nodes/immutable/array", test_immutable_array); + g_test_add_func ("/nodes/immutable/value", test_immutable_value); + g_test_add_func ("/nodes/immutable/parent", test_immutable_parent); + + return g_test_run (); +} diff --git a/json-glib/tests/object.c b/json-glib/tests/object.c new file mode 100644 index 0000000..03a478c --- /dev/null +++ b/json-glib/tests/object.c @@ -0,0 +1,213 @@ +#include +#include +#include + +#include +#include + +static void +test_empty_object (void) +{ + JsonObject *object = json_object_new (); + + g_assert_cmpint (json_object_get_size (object), ==, 0); + g_assert (json_object_get_members (object) == NULL); + + json_object_unref (object); +} + +static void +test_add_member (void) +{ + JsonObject *object = json_object_new (); + JsonNode *node = json_node_new (JSON_NODE_NULL); + + g_assert_cmpint (json_object_get_size (object), ==, 0); + + json_object_set_member (object, "Null", node); + g_assert_cmpint (json_object_get_size (object), ==, 1); + + node = json_object_get_member (object, "Null"); + g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_NULL); + + json_object_unref (object); +} + +static void +test_set_member (void) +{ + JsonNode *node = json_node_new (JSON_NODE_VALUE); + JsonObject *object = json_object_new (); + + g_assert_cmpint (json_object_get_size (object), ==, 0); + + json_node_set_string (node, "Hello"); + + json_object_set_member (object, "String", node); + g_assert_cmpint (json_object_get_size (object), ==, 1); + + node = json_object_get_member (object, "String"); + g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE); + g_assert_cmpstr (json_node_get_string (node), ==, "Hello"); + + json_object_set_string_member (object, "String", "World"); + node = json_object_get_member (object, "String"); + g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE); + g_assert_cmpstr (json_node_get_string (node), ==, "World"); + + json_object_set_string_member (object, "String", "Goodbye"); + g_assert_cmpstr (json_object_get_string_member (object, "String"), ==, "Goodbye"); + + json_object_set_array_member (object, "Array", NULL); + g_assert_cmpint (JSON_NODE_TYPE (json_object_get_member (object, "Array")), ==, JSON_NODE_NULL); + + json_object_set_object_member (object, "Object", NULL); + g_assert (json_object_get_null_member (object, "Object") == TRUE); + + json_object_set_object_member (object, "", NULL); + g_assert (json_object_get_null_member (object, "") == TRUE); + + json_object_unref (object); +} + +static void +test_remove_member (void) +{ + JsonObject *object = json_object_new (); + JsonNode *node = json_node_new (JSON_NODE_NULL); + + json_object_set_member (object, "Null", node); + + json_object_remove_member (object, "Null"); + g_assert_cmpint (json_object_get_size (object), ==, 0); + + json_object_unref (object); +} + +typedef struct _TestForeachFixture +{ + gint n_members; +} TestForeachFixture; + +static const struct { + const gchar *member_name; + JsonNodeType member_type; + GType member_gtype; +} type_verify[] = { + { "integer", JSON_NODE_VALUE, G_TYPE_INT64 }, + { "boolean", JSON_NODE_VALUE, G_TYPE_BOOLEAN }, + { "string", JSON_NODE_VALUE, G_TYPE_STRING }, + { "double", JSON_NODE_VALUE, G_TYPE_DOUBLE }, + { "null", JSON_NODE_NULL, G_TYPE_INVALID }, + { "", JSON_NODE_VALUE, G_TYPE_INT64 } +}; + +static void +verify_foreach (JsonObject *object, + const gchar *member_name, + JsonNode *member_node, + gpointer user_data) +{ + TestForeachFixture *fixture = user_data; + gint i; + + for (i = 0; i < G_N_ELEMENTS (type_verify); i++) + { + if (strcmp (member_name, type_verify[i].member_name) == 0) + { + g_assert (json_node_get_node_type (member_node) == type_verify[i].member_type); + g_assert (json_node_get_value_type (member_node) == type_verify[i].member_gtype); + break; + } + } + + fixture->n_members += 1; +} + +static void +test_foreach_member (void) +{ + JsonObject *object = json_object_new (); + TestForeachFixture fixture = { 0, }; + + json_object_set_int_member (object, "integer", 42); + json_object_set_boolean_member (object, "boolean", TRUE); + json_object_set_string_member (object, "string", "hello"); + json_object_set_double_member (object, "double", 3.14159); + json_object_set_null_member (object, "null"); + json_object_set_int_member (object, "", 0); + + json_object_foreach_member (object, verify_foreach, &fixture); + + g_assert_cmpint (fixture.n_members, ==, json_object_get_size (object)); + + json_object_unref (object); +} + +static void +test_iter (void) +{ + JsonObject *object = NULL; + TestForeachFixture fixture = { 0, }; + JsonObjectIter iter; + const gchar *member_name; + JsonNode *member_node; + + object = json_object_new (); + + json_object_set_int_member (object, "integer", 42); + json_object_set_boolean_member (object, "boolean", TRUE); + json_object_set_string_member (object, "string", "hello"); + json_object_set_double_member (object, "double", 3.14159); + json_object_set_null_member (object, "null"); + json_object_set_int_member (object, "", 0); + + json_object_iter_init (&iter, object); + + while (json_object_iter_next (&iter, &member_name, &member_node)) + verify_foreach (object, member_name, member_node, &fixture); + + g_assert_cmpint (fixture.n_members, ==, json_object_get_size (object)); + + json_object_unref (object); +} + +static void +test_empty_member (void) +{ + JsonObject *object = json_object_new (); + + json_object_set_string_member (object, "string", ""); + g_assert (json_object_has_member (object, "string")); + g_assert_cmpstr (json_object_get_string_member (object, "string"), ==, ""); + + json_object_set_string_member (object, "null", NULL); + g_assert (json_object_has_member (object, "null")); + g_assert (json_object_get_string_member (object, "null") == NULL); + + json_object_set_null_member (object, "array"); + g_assert (json_object_get_array_member (object, "array") == NULL); + + json_object_set_object_member (object, "object", NULL); + g_assert (json_object_get_member (object, "object") != NULL); + g_assert (json_object_get_object_member (object, "object") == NULL); + + json_object_unref (object); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/object/empty-object", test_empty_object); + g_test_add_func ("/object/add-member", test_add_member); + g_test_add_func ("/object/set-member", test_set_member); + g_test_add_func ("/object/remove-member", test_remove_member); + g_test_add_func ("/object/foreach-member", test_foreach_member); + g_test_add_func ("/object/iter", test_iter); + g_test_add_func ("/object/empty-member", test_empty_member); + + return g_test_run (); +} diff --git a/json-glib/tests/parser.c b/json-glib/tests/parser.c new file mode 100644 index 0000000..7af4329 --- /dev/null +++ b/json-glib/tests/parser.c @@ -0,0 +1,769 @@ +#include "json-test-utils.h" +#include + +static const gchar *test_empty_string = ""; +static const gchar *test_empty_array_string = "[ ]"; +static const gchar *test_empty_object_string = "{ }"; + +static void +verify_int_value (JsonNode *node) +{ + g_assert_cmpint (42, ==, json_node_get_int (node)); +} + +static void +verify_negative_int_value (JsonNode *node) +{ + g_assert_cmpint (-1, ==, json_node_get_int (node)); +} + +static void +verify_boolean_value (JsonNode *node) +{ + g_assert_cmpint (TRUE, ==, json_node_get_boolean (node)); +} + +static void +verify_string_value (JsonNode *node) +{ + g_assert_cmpstr ("string", ==, json_node_get_string (node)); +} + +static void +verify_double_value (JsonNode *node) +{ + json_assert_fuzzy_equals (10.2e3, json_node_get_double (node), 0.1); +} + +static void +verify_negative_double_value (JsonNode *node) +{ + json_assert_fuzzy_equals (-3.14, json_node_get_double (node), 0.01); +} + +static const struct { + const gchar *str; + JsonNodeType type; + GType gtype; + void (* verify_value) (JsonNode *node); +} test_base_values[] = { + { "null", JSON_NODE_NULL, G_TYPE_INVALID, NULL, }, + { "42", JSON_NODE_VALUE, G_TYPE_INT64, verify_int_value }, + { "true", JSON_NODE_VALUE, G_TYPE_BOOLEAN, verify_boolean_value }, + { "\"string\"", JSON_NODE_VALUE, G_TYPE_STRING, verify_string_value }, + { "10.2e3", JSON_NODE_VALUE, G_TYPE_DOUBLE, verify_double_value }, + { "-1", JSON_NODE_VALUE, G_TYPE_INT64, verify_negative_int_value }, + { "-3.14", JSON_NODE_VALUE, G_TYPE_DOUBLE, verify_negative_double_value }, +}; + +static const struct { + const gchar *str; + gint len; + gint element; + JsonNodeType type; + GType gtype; +} test_simple_arrays[] = { + { "[ true ]", 1, 0, JSON_NODE_VALUE, G_TYPE_BOOLEAN }, + { "[ true, false, null ]", 3, 2, JSON_NODE_NULL, G_TYPE_INVALID }, + { "[ 1, 2, 3.14, \"test\" ]", 4, 3, JSON_NODE_VALUE, G_TYPE_STRING } +}; + +static const gchar *test_nested_arrays[] = { + "[ 42, [ ], null ]", + "[ [ ], [ true, [ true ] ] ]", + "[ [ false, true, 42 ], [ true, false, 3.14 ], \"test\" ]", + "[ true, { } ]", + "[ false, { \"test\" : 42 } ]", + "[ { \"test\" : 42 }, null ]", + "[ true, { \"test\" : 42 }, null ]", + "[ { \"channel\" : \"/meta/connect\" } ]" +}; + +static const struct { + const gchar *str; + gint size; + const gchar *member; + JsonNodeType type; + GType gtype; +} test_simple_objects[] = { + { "{ \"test\" : 42 }", 1, "test", JSON_NODE_VALUE, G_TYPE_INT64 }, + { "{ \"name\" : \"\", \"state\" : 1 }", 2, "name", JSON_NODE_VALUE, G_TYPE_STRING }, + { "{ \"foo\" : \"bar\", \"baz\" : null }", 2, "baz", JSON_NODE_NULL, G_TYPE_INVALID }, + { "{ \"channel\" : \"/meta/connect\" }", 1, "channel", JSON_NODE_VALUE, G_TYPE_STRING }, + { "{ \"halign\":0.5, \"valign\":0.5 }", 2, "valign", JSON_NODE_VALUE, G_TYPE_DOUBLE }, + { "{ \"\" : \"emptiness\" }", 1, "", JSON_NODE_VALUE, G_TYPE_STRING } +}; + +static const gchar *test_nested_objects[] = { + "{ \"array\" : [ false, \"foo\" ], \"object\" : { \"foo\" : true } }", + "{ " + "\"type\" : \"ClutterGroup\", " + "\"width\" : 1, " + "\"children\" : [ " + "{ " + "\"type\" : \"ClutterRectangle\", " + "\"children\" : [ " + "{ \"type\" : \"ClutterText\", \"text\" : \"hello there\" }" + "] " + "}, " + "{ " + "\"type\" : \"ClutterGroup\", " + "\"width\" : 1, " + "\"children\" : [ " + "{ \"type\" : \"ClutterText\", \"text\" : \"hello\" }" + "] " + "} " + "] " + "}" +}; + +static const struct { + const gchar *str; + const gchar *var; +} test_assignments[] = { + { "var foo = [ false, false, true ]", "foo" }, + { "var bar = [ true, 42 ];", "bar" }, + { "var baz = { \"foo\" : false }", "baz" } +}; + +static const struct +{ + const gchar *str; + const gchar *member; + const gchar *match; +} test_unicode[] = { + { "{ \"test\" : \"foo \\u00e8\" }", "test", "foo è" } +}; + +static guint n_test_base_values = G_N_ELEMENTS (test_base_values); +static guint n_test_simple_arrays = G_N_ELEMENTS (test_simple_arrays); +static guint n_test_nested_arrays = G_N_ELEMENTS (test_nested_arrays); +static guint n_test_simple_objects = G_N_ELEMENTS (test_simple_objects); +static guint n_test_nested_objects = G_N_ELEMENTS (test_nested_objects); +static guint n_test_assignments = G_N_ELEMENTS (test_assignments); +static guint n_test_unicode = G_N_ELEMENTS (test_unicode); + +static void +test_empty_with_parser (JsonParser *parser) +{ + GError *error = NULL; + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with empty string...\n"); + + if (!json_parser_load_from_data (parser, test_empty_string, -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + if (g_test_verbose ()) + g_print ("checking json_parser_get_root...\n"); + + g_assert (NULL == json_parser_get_root (parser)); + } +} + +static void +test_empty (void) +{ + JsonParser *parser; + + /* Check with and without immutability enabled, as there have been bugs with + * NULL root nodes on immutable parsers. */ + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + test_empty_with_parser (parser); + g_object_unref (parser); + + parser = json_parser_new_immutable (); + g_assert (JSON_IS_PARSER (parser)); + test_empty_with_parser (parser); + g_object_unref (parser); +} + +static void +test_base_value (void) +{ + gint i; + JsonParser *parser; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with base-values...\n"); + + for (i = 0; i < n_test_base_values; i++) + { + GError *error = NULL; + + if (!json_parser_load_from_data (parser, test_base_values[i].str, -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + JsonNode *root; + + g_assert (NULL != json_parser_get_root (parser)); + + root = json_parser_get_root (parser); + g_assert (root != NULL); + g_assert (json_node_get_parent (root) == NULL); + + if (g_test_verbose ()) + g_print ("checking root node is of the desired type %s...\n", + test_base_values[i].gtype == G_TYPE_INVALID ? "" + : g_type_name (test_base_values[i].gtype)); + g_assert_cmpint (JSON_NODE_TYPE (root), ==, test_base_values[i].type); + g_assert_cmpint (json_node_get_value_type (root), ==, test_base_values[i].gtype); + + if (test_base_values[i].verify_value) + test_base_values[i].verify_value (root); + } + } + + g_object_unref (parser); +} + +static void +test_empty_array (void) +{ + JsonParser *parser; + GError *error = NULL; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with empty array...\n"); + + if (!json_parser_load_from_data (parser, test_empty_array_string, -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + JsonNode *root; + JsonArray *array; + + g_assert (NULL != json_parser_get_root (parser)); + + if (g_test_verbose ()) + g_print ("checking root node is an array...\n"); + root = json_parser_get_root (parser); + g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_ARRAY); + g_assert (json_node_get_parent (root) == NULL); + + array = json_node_get_array (root); + g_assert (array != NULL); + + if (g_test_verbose ()) + g_print ("checking array is empty...\n"); + g_assert_cmpint (json_array_get_length (array), ==, 0); + } + + g_object_unref (parser); +} + +static void +test_simple_array (void) +{ + gint i; + JsonParser *parser; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with simple arrays...\n"); + + for (i = 0; i < n_test_simple_arrays; i++) + { + GError *error = NULL; + + if (g_test_verbose ()) + g_print ("Parsing: '%s'\n", test_simple_arrays[i].str); + + if (!json_parser_load_from_data (parser, test_simple_arrays[i].str, -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + JsonNode *root, *node; + JsonArray *array; + + g_assert (NULL != json_parser_get_root (parser)); + + if (g_test_verbose ()) + g_print ("checking root node is an array...\n"); + root = json_parser_get_root (parser); + g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_ARRAY); + g_assert (json_node_get_parent (root) == NULL); + + array = json_node_get_array (root); + g_assert (array != NULL); + + if (g_test_verbose ()) + g_print ("checking array is of the desired length (%d)...\n", + test_simple_arrays[i].len); + g_assert_cmpint (json_array_get_length (array), ==, test_simple_arrays[i].len); + + if (g_test_verbose ()) + g_print ("checking element %d is of the desired type %s...\n", + test_simple_arrays[i].element, + g_type_name (test_simple_arrays[i].gtype)); + node = json_array_get_element (array, test_simple_arrays[i].element); + g_assert (node != NULL); + g_assert (json_node_get_parent (node) == root); + g_assert_cmpint (JSON_NODE_TYPE (node), ==, test_simple_arrays[i].type); + g_assert_cmpint (json_node_get_value_type (node), ==, test_simple_arrays[i].gtype); + } + } + + g_object_unref (parser); +} + +static void +test_nested_array (void) +{ + gint i; + JsonParser *parser; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with nested arrays...\n"); + + for (i = 0; i < n_test_nested_arrays; i++) + { + GError *error = NULL; + + if (!json_parser_load_from_data (parser, test_nested_arrays[i], -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + JsonNode *root; + JsonArray *array; + + g_assert (NULL != json_parser_get_root (parser)); + + if (g_test_verbose ()) + g_print ("checking root node is an array...\n"); + root = json_parser_get_root (parser); + g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_ARRAY); + g_assert (json_node_get_parent (root) == NULL); + + array = json_node_get_array (root); + g_assert (array != NULL); + + if (g_test_verbose ()) + g_print ("checking array is not empty...\n"); + g_assert_cmpint (json_array_get_length (array), >, 0); + } + } + + g_object_unref (parser); +} + +static void +test_empty_object (void) +{ + JsonParser *parser; + GError *error = NULL; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with empty object...\n"); + + if (!json_parser_load_from_data (parser, test_empty_object_string, -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + JsonNode *root; + JsonObject *object; + + g_assert (NULL != json_parser_get_root (parser)); + + if (g_test_verbose ()) + g_print ("checking root node is an object...\n"); + root = json_parser_get_root (parser); + g_assert (json_node_get_parent (root) == NULL); + g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_OBJECT); + g_assert (json_node_get_parent (root) == NULL); + + object = json_node_get_object (root); + g_assert (object != NULL); + + if (g_test_verbose ()) + g_print ("checking object is empty...\n"); + g_assert_cmpint (json_object_get_size (object), ==, 0); + } + + g_object_unref (parser); +} + +static void +test_simple_object (void) +{ + gint i; + JsonParser *parser; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with simple objects...\n"); + + for (i = 0; i < n_test_simple_objects; i++) + { + GError *error = NULL; + + if (!json_parser_load_from_data (parser, test_simple_objects[i].str, -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + JsonNode *root, *node; + JsonObject *object; + + g_assert (NULL != json_parser_get_root (parser)); + + if (g_test_verbose ()) + g_print ("checking root node is an object...\n"); + root = json_parser_get_root (parser); + g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_OBJECT); + g_assert (json_node_get_parent (root) == NULL); + + object = json_node_get_object (root); + g_assert (object != NULL); + + if (g_test_verbose ()) + g_print ("checking object is of the desired size (%d)...\n", + test_simple_objects[i].size); + g_assert_cmpint (json_object_get_size (object), ==, test_simple_objects[i].size); + + if (g_test_verbose ()) + g_print ("checking member '%s' is of the desired type %s...\n", + test_simple_objects[i].member, + g_type_name (test_simple_objects[i].gtype)); + node = json_object_get_member (object, test_simple_objects[i].member); + g_assert (node != NULL); + g_assert (json_node_get_parent (node) == root); + g_assert_cmpint (JSON_NODE_TYPE (node), ==, test_simple_objects[i].type); + g_assert_cmpint (json_node_get_value_type (node), ==, test_simple_objects[i].gtype); + } + } + + g_object_unref (parser); +} + +static void +test_nested_object (void) +{ + gint i; + JsonParser *parser; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with nested objects...\n"); + + for (i = 0; i < n_test_nested_objects; i++) + { + GError *error = NULL; + + if (!json_parser_load_from_data (parser, test_nested_objects[i], -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + JsonNode *root; + JsonObject *object; + + g_assert (NULL != json_parser_get_root (parser)); + + if (g_test_verbose ()) + g_print ("checking root node is an object...\n"); + root = json_parser_get_root (parser); + g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_OBJECT); + g_assert (json_node_get_parent (root) == NULL); + + object = json_node_get_object (root); + g_assert (object != NULL); + + if (g_test_verbose ()) + g_print ("checking object is not empty...\n"); + g_assert_cmpint (json_object_get_size (object), >, 0); + } + } + + g_object_unref (parser); +} + +static void +test_assignment (void) +{ + gint i; + JsonParser *parser; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with assignments...\n"); + + for (i = 0; i < n_test_assignments; i++) + { + GError *error = NULL; + + if (!json_parser_load_from_data (parser, test_assignments[i].str, -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + gchar *var; + + if (g_test_verbose ()) + g_print ("checking assignment...\n"); + + g_assert (json_parser_has_assignment (parser, &var) == TRUE); + g_assert (var != NULL); + g_assert_cmpstr (var, ==, test_assignments[i].var); + g_assert (NULL != json_parser_get_root (parser)); + } + } + + g_object_unref (parser); +} + +static void +test_unicode_escape (void) +{ + gint i; + JsonParser *parser; + + parser = json_parser_new (); + g_assert (JSON_IS_PARSER (parser)); + + if (g_test_verbose ()) + g_print ("checking json_parser_load_from_data with unicode escape...\n"); + + for (i = 0; i < n_test_unicode; i++) + { + GError *error = NULL; + + if (!json_parser_load_from_data (parser, test_unicode[i].str, -1, &error)) + { + if (g_test_verbose ()) + g_print ("Error: %s\n", error->message); + + g_error_free (error); + g_object_unref (parser); + exit (1); + } + else + { + JsonNode *root, *node; + JsonObject *object; + + g_assert (NULL != json_parser_get_root (parser)); + + if (g_test_verbose ()) + g_print ("checking root node is an object...\n"); + root = json_parser_get_root (parser); + g_assert_cmpint (JSON_NODE_TYPE (root), ==, JSON_NODE_OBJECT); + + object = json_node_get_object (root); + g_assert (object != NULL); + + if (g_test_verbose ()) + g_print ("checking object is not empty...\n"); + g_assert_cmpint (json_object_get_size (object), >, 0); + + node = json_object_get_member (object, test_unicode[i].member); + g_assert_cmpint (JSON_NODE_TYPE (node), ==, JSON_NODE_VALUE); + + if (g_test_verbose ()) + g_print ("checking simple string equality...\n"); + g_assert_cmpstr (json_node_get_string (node), ==, test_unicode[i].match); + + if (g_test_verbose ()) + g_print ("checking for valid UTF-8...\n"); + g_assert (g_utf8_validate (json_node_get_string (node), -1, NULL)); + } + } + + g_object_unref (parser); +} + +static void +test_stream_sync (void) +{ + JsonParser *parser; + GFile *file; + GFileInputStream *stream; + GError *error = NULL; + JsonNode *root; + JsonArray *array; + char *path; + + parser = json_parser_new (); + + path = g_test_build_filename (G_TEST_DIST, "stream-load.json", NULL); + file = g_file_new_for_path (path); + stream = g_file_read (file, NULL, &error); + g_assert_no_error (error); + g_assert (stream != NULL); + + json_parser_load_from_stream (parser, G_INPUT_STREAM (stream), NULL, &error); + g_assert_no_error (error); + + root = json_parser_get_root (parser); + g_assert (root != NULL); + g_assert (JSON_NODE_HOLDS_ARRAY (root)); + + array = json_node_get_array (root); + g_assert_cmpint (json_array_get_length (array), ==, 1); + g_assert (JSON_NODE_HOLDS_OBJECT (json_array_get_element (array, 0))); + g_assert (json_object_has_member (json_array_get_object_element (array, 0), "hello")); + + g_object_unref (stream); + g_object_unref (file); + g_object_unref (parser); + g_free (path); +} + +static void +on_load_complete (GObject *gobject, + GAsyncResult *result, + gpointer user_data) +{ + JsonParser *parser = JSON_PARSER (gobject); + GMainLoop *main_loop = user_data; + GError *error = NULL; + JsonNode *root; + JsonArray *array; + + json_parser_load_from_stream_finish (parser, result, &error); + g_assert_no_error (error); + + root = json_parser_get_root (parser); + g_assert (root != NULL); + g_assert (JSON_NODE_HOLDS_ARRAY (root)); + + array = json_node_get_array (root); + g_assert_cmpint (json_array_get_length (array), ==, 1); + g_assert (JSON_NODE_HOLDS_OBJECT (json_array_get_element (array, 0))); + g_assert (json_object_has_member (json_array_get_object_element (array, 0), "hello")); + + g_main_loop_quit (main_loop); +} + +static void +test_stream_async (void) +{ + GMainLoop *main_loop; + GError *error = NULL; + JsonParser *parser = json_parser_new (); + GFile *file; + GFileInputStream *stream; + char *path; + + path = g_test_build_filename (G_TEST_DIST, "stream-load.json", NULL); + file = g_file_new_for_path (path); + stream = g_file_read (file, NULL, &error); + g_assert (error == NULL); + g_assert (stream != NULL); + + main_loop = g_main_loop_new (NULL, FALSE); + + json_parser_load_from_stream_async (parser, G_INPUT_STREAM (stream), NULL, + on_load_complete, + main_loop); + + g_main_loop_run (main_loop); + + g_main_loop_unref (main_loop); + g_object_unref (stream); + g_object_unref (file); + g_object_unref (parser); + g_free (path); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/parser/empty-string", test_empty); + g_test_add_func ("/parser/base-value", test_base_value); + g_test_add_func ("/parser/empty-array", test_empty_array); + g_test_add_func ("/parser/simple-array", test_simple_array); + g_test_add_func ("/parser/nested-array", test_nested_array); + g_test_add_func ("/parser/empty-object", test_empty_object); + g_test_add_func ("/parser/simple-object", test_simple_object); + g_test_add_func ("/parser/nested-object", test_nested_object); + g_test_add_func ("/parser/assignment", test_assignment); + g_test_add_func ("/parser/unicode-escape", test_unicode_escape); + g_test_add_func ("/parser/stream-sync", test_stream_sync); + g_test_add_func ("/parser/stream-async", test_stream_async); + + return g_test_run (); +} diff --git a/json-glib/tests/path.c b/json-glib/tests/path.c new file mode 100644 index 0000000..e6d82c2 --- /dev/null +++ b/json-glib/tests/path.c @@ -0,0 +1,319 @@ +#include +#include +#include + +static const char *test_json = +"{ \"store\": {" +" \"book\": [ " +" { \"category\": \"reference\"," +" \"author\": \"Nigel Rees\"," +" \"title\": \"Sayings of the Century\"," +" \"price\": \"8.95\"" +" }," +" { \"category\": \"fiction\"," +" \"author\": \"Evelyn Waugh\"," +" \"title\": \"Sword of Honour\"," +" \"price\": \"12.99\"" +" }," +" { \"category\": \"fiction\"," +" \"author\": \"Herman Melville\"," +" \"title\": \"Moby Dick\"," +" \"isbn\": \"0-553-21311-3\"," +" \"price\": \"8.99\"" +" }," +" { \"category\": \"fiction\"," +" \"author\": \"J. R. R. Tolkien\"," +" \"title\": \"The Lord of the Rings\"," +" \"isbn\": \"0-395-19395-8\"," +" \"price\": \"22.99\"" +" }" +" ]," +" \"bicycle\": {" +" \"color\": \"red\"," +" \"price\": \"19.95\"" +" }" +" }" +"}"; + +static const struct { + const char *desc; + const char *expr; + const char *res; + + guint is_valid : 1; + + JsonPathError error_code; +} test_expressions[] = { + { + "INVALID: invalid first character", + "/", + NULL, + FALSE, + JSON_PATH_ERROR_INVALID_QUERY, + }, + { + "INVALID: Invalid character following root", + "$ponies", + NULL, + FALSE, + JSON_PATH_ERROR_INVALID_QUERY, + }, + { + "INVALID: missing member name or wildcard after dot", + "$.store.", + NULL, + FALSE, + JSON_PATH_ERROR_INVALID_QUERY, + }, + { + "INVALID: Malformed slice (missing step)", + "$.store.book[0:1:]", + NULL, + FALSE, + JSON_PATH_ERROR_INVALID_QUERY, + }, + { + "INVALID: Malformed set", + "$.store.book[0,1~2]", + NULL, + FALSE, + JSON_PATH_ERROR_INVALID_QUERY, + }, + { + "INVALID: Malformed array notation", + "${'store'}", + NULL, + FALSE, + JSON_PATH_ERROR_INVALID_QUERY, + }, + { + "INVALID: Malformed slice (invalid separator)", + "$.store.book[0~2]", + NULL, + FALSE, + JSON_PATH_ERROR_INVALID_QUERY, + }, + { + "Title of the first book in the store, using objct notation.", + "$.store.book[0].title", + "[\"Sayings of the Century\"]", + TRUE, + }, + { + "Title of the first book in the store, using array notation.", + "$['store']['book'][0]['title']", + "[\"Sayings of the Century\"]", + TRUE, + }, + { + "All the authors from the every book.", + "$.store.book[*].author", + "[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]", + TRUE, + }, + { + "All the authors.", + "$..author", + "[\"Nigel Rees\",\"Evelyn Waugh\",\"Herman Melville\",\"J. R. R. Tolkien\"]", + TRUE, + }, + { + "Everything inside the store.", + "$.store.*", + NULL, + TRUE, + }, + { + "All the prices in the store.", + "$.store..price", + "[\"8.95\",\"12.99\",\"8.99\",\"22.99\",\"19.95\"]", + TRUE, + }, + { + "The third book.", + "$..book[2]", + "[{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":\"8.99\"}]", + TRUE, + }, + { + "The last book.", + "$..book[-1:]", + "[{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":\"22.99\"}]", + TRUE, + }, + { + "The first two books.", + "$..book[0,1]", + "[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":\"8.95\"},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":\"12.99\"}]", + TRUE, + }, + { + "The first two books, using a slice.", + "$..book[:2]", + "[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":\"8.95\"},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":\"12.99\"}]", + TRUE, + }, + { + "All the books.", + "$['store']['book'][*]", + "[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":\"8.95\"},{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":\"12.99\"},{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":\"8.99\"},{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":\"22.99\"}]", + TRUE, + }, + { + "All the members of the bicycle object.", + "$.store.bicycle.*", + "[\"red\",\"19.95\"]", + TRUE, + }, + { + "The root node.", + "$", + "[{\"store\":{\"book\":[{\"category\":\"reference\",\"author\":\"Nigel Rees\",\"title\":\"Sayings of the Century\",\"price\":\"8.95\"}," + "{\"category\":\"fiction\",\"author\":\"Evelyn Waugh\",\"title\":\"Sword of Honour\",\"price\":\"12.99\"}," + "{\"category\":\"fiction\",\"author\":\"Herman Melville\",\"title\":\"Moby Dick\",\"isbn\":\"0-553-21311-3\",\"price\":\"8.99\"}," + "{\"category\":\"fiction\",\"author\":\"J. R. R. Tolkien\",\"title\":\"The Lord of the Rings\",\"isbn\":\"0-395-19395-8\",\"price\":\"22.99\"}]," + "\"bicycle\":{\"color\":\"red\",\"price\":\"19.95\"}}}]", + TRUE, + } +}; + +static void +path_expressions_valid (gconstpointer data) +{ + const int index_ = GPOINTER_TO_INT (data); + const char *expr = test_expressions[index_].expr; + const char *desc = test_expressions[index_].desc; + + JsonPath *path = json_path_new (); + GError *error = NULL; + + if (g_test_verbose ()) + g_print ("* %s ('%s')\n", desc, expr); + + g_assert (json_path_compile (path, expr, &error)); + g_assert_no_error (error); + + g_object_unref (path); +} + +static void +path_expressions_invalid (gconstpointer data) +{ + const int index_ = GPOINTER_TO_INT (data); + const char *expr = test_expressions[index_].expr; + const char *desc = test_expressions[index_].desc; + const JsonPathError code = test_expressions[index_].error_code; + + JsonPath *path = json_path_new (); + GError *error = NULL; + + if (g_test_verbose ()) + g_print ("* %s ('%s')\n", desc, expr); + + + g_assert (!json_path_compile (path, expr, &error)); + g_assert_error (error, JSON_PATH_ERROR, code); + + g_object_unref (path); + g_clear_error (&error); +} + +static void +path_match (gconstpointer data) +{ + const int index_ = GPOINTER_TO_INT (data); + const char *desc = test_expressions[index_].desc; + const char *expr = test_expressions[index_].expr; + const char *res = test_expressions[index_].res; + + JsonParser *parser = json_parser_new (); + JsonGenerator *gen = json_generator_new (); + JsonPath *path = json_path_new (); + JsonNode *root; + JsonNode *matches; + char *str; + + json_parser_load_from_data (parser, test_json, -1, NULL); + root = json_parser_get_root (parser); + + g_assert (json_path_compile (path, expr, NULL)); + + matches = json_path_match (path, root); + g_assert (JSON_NODE_HOLDS_ARRAY (matches)); + + json_generator_set_root (gen, matches); + str = json_generator_to_data (gen, NULL); + + if (g_test_verbose ()) + { + g_print ("* %s ('%s') =>\n" + "- result: %s\n" + "- expected: %s\n", + desc, expr, + str, + res); + } + + g_assert_cmpstr (str, ==, res); + + g_free (str); + json_node_free (matches); + + g_object_unref (parser); + g_object_unref (path); + g_object_unref (gen); +} + +int +main (int argc, + char *argv[]) +{ + int i, j; + + g_test_init (&argc, &argv, NULL); + g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id="); + + for (i = 0, j = 1; i < G_N_ELEMENTS (test_expressions); i++) + { + char *path; + + if (!test_expressions[i].is_valid) + continue; + + path = g_strdup_printf ("/path/expressions/valid/%d", j++); + + g_test_add_data_func (path, GINT_TO_POINTER (i), path_expressions_valid); + + g_free (path); + } + + for (i = 0, j = 1; i < G_N_ELEMENTS (test_expressions); i++) + { + char *path; + + if (test_expressions[i].is_valid) + continue; + + path = g_strdup_printf ("/path/expressions/invalid/%d", j++); + + g_test_add_data_func (path, GINT_TO_POINTER (i), path_expressions_invalid); + + g_free (path); + } + + for (i = 0, j = 1; i < G_N_ELEMENTS (test_expressions); i++) + { + char *path; + + if (!test_expressions[i].is_valid || test_expressions[i].res == NULL) + continue; + + path = g_strdup_printf ("/path/match/%d", j++); + + g_test_add_data_func (path, GINT_TO_POINTER (i), path_match); + + g_free (path); + } + + return g_test_run (); +} diff --git a/json-glib/tests/reader.c b/json-glib/tests/reader.c new file mode 100644 index 0000000..d0a046b --- /dev/null +++ b/json-glib/tests/reader.c @@ -0,0 +1,228 @@ +#include "json-test-utils.h" + +static const gchar *test_base_array_data = +"[ 0, true, null, \"foo\", 3.14, [ false ], { \"bar\" : 42 } ]"; + +static const gchar *test_base_object_data = +"{ \"text\" : \"hello, world!\", \"foo\" : null, \"blah\" : 47, \"double\" : 42.47 }"; + +static const gchar *test_reader_level_data = +" { \"list\": { \"181195771\": { \"given_url\": \"http://www.gnome.org/json-glib-test\" } } }"; + +/* https://bugzilla.gnome.org/show_bug.cgi?id=758580 */ +static const char *test_reader_null_value_data = +"{ \"v\": null }"; + +static const gchar *expected_member_name[] = { + "text", + "foo", + "blah", + "double", +}; + +static void +test_base_object (void) +{ + JsonParser *parser = json_parser_new (); + JsonReader *reader = json_reader_new (NULL); + GError *error = NULL; + gchar **members; + gsize n_members, i; + + json_parser_load_from_data (parser, test_base_object_data, -1, &error); + g_assert (error == NULL); + + json_reader_set_root (reader, json_parser_get_root (parser)); + + g_assert (json_reader_is_object (reader)); + g_assert_cmpint (json_reader_count_members (reader), ==, 4); + + members = json_reader_list_members (reader); + g_assert (members != NULL); + + n_members = g_strv_length (members); + g_assert_cmpint (n_members, ==, json_reader_count_members (reader)); + + for (i = 0; i < n_members; i++) + g_assert_cmpstr (members[i], ==, expected_member_name[i]); + + g_strfreev (members); + + g_assert (json_reader_read_member (reader, "text")); + g_assert (json_reader_is_value (reader)); + g_assert_cmpstr (json_reader_get_string_value (reader), ==, "hello, world!"); + json_reader_end_member (reader); + + g_assert (json_reader_read_member (reader, "foo")); + g_assert (json_reader_get_null_value (reader)); + json_reader_end_member (reader); + + g_assert (!json_reader_read_member (reader, "bar")); + g_assert (json_reader_get_error (reader) != NULL); + g_assert_error ((GError *) json_reader_get_error (reader), + JSON_READER_ERROR, + JSON_READER_ERROR_INVALID_MEMBER); + json_reader_end_member (reader); + g_assert (json_reader_get_error (reader) == NULL); + + g_assert (json_reader_read_element (reader, 2)); + g_assert_cmpstr (json_reader_get_member_name (reader), ==, "blah"); + g_assert (json_reader_is_value (reader)); + g_assert_cmpint (json_reader_get_int_value (reader), ==, 47); + json_reader_end_element (reader); + g_assert (json_reader_get_error (reader) == NULL); + + json_reader_read_member (reader, "double"); + json_assert_fuzzy_equals (json_reader_get_double_value (reader), 42.47, 0.01); + json_reader_end_element (reader); + + g_object_unref (reader); + g_object_unref (parser); +} + +static void +test_base_array (void) +{ + JsonParser *parser = json_parser_new (); + JsonReader *reader = json_reader_new (NULL); + GError *error = NULL; + + json_parser_load_from_data (parser, test_base_array_data, -1, &error); + g_assert (error == NULL); + + json_reader_set_root (reader, json_parser_get_root (parser)); + + g_assert (json_reader_is_array (reader)); + g_assert_cmpint (json_reader_count_elements (reader), ==, 7); + + json_reader_read_element (reader, 0); + g_assert (json_reader_is_value (reader)); + g_assert_cmpint (json_reader_get_int_value (reader), ==, 0); + json_reader_end_element (reader); + + json_reader_read_element (reader, 1); + g_assert (json_reader_is_value (reader)); + g_assert (json_reader_get_boolean_value (reader)); + json_reader_end_element (reader); + + json_reader_read_element (reader, 3); + g_assert (json_reader_is_value (reader)); + g_assert_cmpstr (json_reader_get_string_value (reader), ==, "foo"); + json_reader_end_element (reader); + + json_reader_read_element (reader, 5); + g_assert (!json_reader_is_value (reader)); + g_assert (json_reader_is_array (reader)); + json_reader_end_element (reader); + + json_reader_read_element (reader, 6); + g_assert (json_reader_is_object (reader)); + + json_reader_read_member (reader, "bar"); + g_assert (json_reader_is_value (reader)); + g_assert_cmpint (json_reader_get_int_value (reader), ==, 42); + json_reader_end_member (reader); + + json_reader_end_element (reader); + + g_assert (!json_reader_read_element (reader, 7)); + g_assert_error ((GError *) json_reader_get_error (reader), + JSON_READER_ERROR, + JSON_READER_ERROR_INVALID_INDEX); + json_reader_end_element (reader); + g_assert (json_reader_get_error (reader) == NULL); + + g_object_unref (reader); + g_object_unref (parser); + g_clear_error (&error); +} + +static void +test_reader_level (void) +{ + JsonParser *parser = json_parser_new (); + JsonReader *reader = json_reader_new (NULL); + GError *error = NULL; + char **members; + + json_parser_load_from_data (parser, test_reader_level_data, -1, &error); + g_assert (error == NULL); + + json_reader_set_root (reader, json_parser_get_root (parser)); + + g_assert (json_reader_count_members (reader) > 0); + + /* Grab the list */ + g_assert (json_reader_read_member (reader, "list")); + g_assert_cmpstr (json_reader_get_member_name (reader), ==, "list"); + + members = json_reader_list_members (reader); + g_assert (members != NULL); + g_strfreev (members); + + g_assert (json_reader_read_member (reader, "181195771")); + g_assert_cmpstr (json_reader_get_member_name (reader), ==, "181195771"); + + g_assert (!json_reader_read_member (reader, "resolved_url")); + g_assert_cmpstr (json_reader_get_member_name (reader), ==, NULL); + g_assert (json_reader_get_error (reader) != NULL); + json_reader_end_member (reader); + + g_assert_cmpstr (json_reader_get_member_name (reader), ==, "181195771"); + + g_assert (json_reader_read_member (reader, "given_url")); + g_assert_cmpstr (json_reader_get_member_name (reader), ==, "given_url"); + g_assert_cmpstr (json_reader_get_string_value (reader), ==, "http://www.gnome.org/json-glib-test"); + json_reader_end_member (reader); + + g_assert_cmpstr (json_reader_get_member_name (reader), ==, "181195771"); + + json_reader_end_member (reader); + + g_assert_cmpstr (json_reader_get_member_name (reader), ==, "list"); + + json_reader_end_member (reader); + + g_assert_cmpstr (json_reader_get_member_name (reader), ==, NULL); + + g_clear_object (&reader); + g_clear_object (&parser); +} + +static void +test_reader_null_value (void) +{ + JsonParser *parser = json_parser_new (); + JsonReader *reader = json_reader_new (NULL); + GError *error = NULL; + + g_test_bug ("758580"); + + json_parser_load_from_data (parser, test_reader_null_value_data, -1, &error); + g_assert_no_error (error); + + json_reader_set_root (reader, json_parser_get_root (parser)); + + json_reader_read_member (reader, "v"); + g_assert_true (json_reader_is_value (reader)); + g_assert_no_error (json_reader_get_error (reader)); + g_assert_nonnull (json_reader_get_value (reader)); + + g_object_unref (reader); + g_object_unref (parser); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + g_test_bug_base ("http://bugzilla.gnome.org/show_bug.cgi?id="); + + g_test_add_func ("/reader/base-array", test_base_array); + g_test_add_func ("/reader/base-object", test_base_object); + g_test_add_func ("/reader/level", test_reader_level); + g_test_add_func ("/reader/null-value", test_reader_null_value); + + return g_test_run (); +} diff --git a/json-glib/tests/serialize-complex.c b/json-glib/tests/serialize-complex.c new file mode 100644 index 0000000..226e722 --- /dev/null +++ b/json-glib/tests/serialize-complex.c @@ -0,0 +1,310 @@ +#include +#include +#include + +#include + +#include +#include + +#define TEST_TYPE_BOXED (test_boxed_get_type ()) +#define TEST_TYPE_OBJECT (test_object_get_type ()) +#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject)) +#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass)) +#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass)) + +typedef struct _TestBoxed TestBoxed; +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; + +struct _TestBoxed +{ + gint foo; + gboolean bar; +}; + +struct _TestObject +{ + GObject parent_instance; + + gint foo; + gboolean bar; + gchar *baz; + TestBoxed blah; + gdouble meh; +}; + +struct _TestObjectClass +{ + GObjectClass parent_class; +}; + +GType test_object_get_type (void); + +/*** implementation ***/ + +static TestBoxed * +test_boxed_copy (const TestBoxed *src) +{ + TestBoxed *copy = g_slice_new (TestBoxed); + + *copy = *src; + + return copy; +} + +static void +test_boxed_free (TestBoxed *boxed) +{ + if (G_LIKELY (boxed)) + { + g_slice_free (TestBoxed, boxed); + } +} + +GType +test_boxed_get_type (void) +{ + static GType b_type = 0; + + if (G_UNLIKELY (b_type == 0)) + b_type = g_boxed_type_register_static ("TestBoxed", + (GBoxedCopyFunc) test_boxed_copy, + (GBoxedFreeFunc) test_boxed_free); + + return b_type; +} + +enum +{ + PROP_0, + + PROP_FOO, + PROP_BAR, + PROP_BAZ, + PROP_BLAH, + PROP_MEH +}; + +static JsonSerializableIface *serializable_iface = NULL; + +static void json_serializable_iface_init (gpointer g_iface); + +G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (JSON_TYPE_SERIALIZABLE, + json_serializable_iface_init)); + +static JsonNode * +test_object_serialize_property (JsonSerializable *serializable, + const gchar *name, + const GValue *value, + GParamSpec *pspec) +{ + JsonNode *retval = NULL; + + if (strcmp (name, "blah") == 0) + { + TestBoxed *boxed; + JsonObject *obj; + JsonNode *val; + + retval = json_node_new (JSON_NODE_OBJECT); + obj = json_object_new (); + + boxed = g_value_get_boxed (value); + + val = json_node_new (JSON_NODE_VALUE); + json_node_set_int (val, boxed->foo); + json_object_set_member (obj, "foo", val); + + val = json_node_new (JSON_NODE_VALUE); + json_node_set_boolean (val, boxed->bar); + json_object_set_member (obj, "bar", val); + + json_node_take_object (retval, obj); + } + else + retval = serializable_iface->serialize_property (serializable, + name, + value, pspec); + + return retval; +} + +static void +json_serializable_iface_init (gpointer g_iface) +{ + JsonSerializableIface *iface = g_iface; + + serializable_iface = g_type_default_interface_peek (JSON_TYPE_SERIALIZABLE); + + iface->serialize_property = test_object_serialize_property; +} + +static void +test_object_finalize (GObject *gobject) +{ + g_free (TEST_OBJECT (gobject)->baz); + + G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject); +} + +static void +test_object_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_FOO: + TEST_OBJECT (gobject)->foo = g_value_get_int (value); + break; + case PROP_BAR: + TEST_OBJECT (gobject)->bar = g_value_get_boolean (value); + break; + case PROP_BAZ: + g_free (TEST_OBJECT (gobject)->baz); + TEST_OBJECT (gobject)->baz = g_value_dup_string (value); + break; + case PROP_MEH: + TEST_OBJECT (gobject)->meh = g_value_get_double (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +test_object_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_FOO: + g_value_set_int (value, TEST_OBJECT (gobject)->foo); + break; + case PROP_BAR: + g_value_set_boolean (value, TEST_OBJECT (gobject)->bar); + break; + case PROP_BAZ: + g_value_set_string (value, TEST_OBJECT (gobject)->baz); + break; + case PROP_BLAH: + g_value_set_boxed (value, &(TEST_OBJECT (gobject)->blah)); + break; + case PROP_MEH: + g_value_set_double (value, TEST_OBJECT (gobject)->meh); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +test_object_class_init (TestObjectClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = test_object_set_property; + gobject_class->get_property = test_object_get_property; + gobject_class->finalize = test_object_finalize; + + g_object_class_install_property (gobject_class, + PROP_FOO, + g_param_spec_int ("foo", "Foo", "Foo", + 0, G_MAXINT, 42, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BAR, + g_param_spec_boolean ("bar", "Bar", "Bar", + TRUE, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BAZ, + g_param_spec_string ("baz", "Baz", "Baz", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BLAH, + g_param_spec_boxed ("blah", "Blah", "Blah", + TEST_TYPE_BOXED, + G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, + PROP_MEH, + g_param_spec_double ("meh", "Meh", "Meh", + 0.0, 1.0, 0.0, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); +} + +static void +test_object_init (TestObject *object) +{ + object->foo = 42; + object->bar = TRUE; + object->baz = g_strdup ("Test"); + object->meh = 0.0; + + object->blah.foo = object->foo; + object->blah.bar = object->bar; +} + +static void +test_serialize (void) +{ + TestObject *obj = g_object_new (TEST_TYPE_OBJECT, + "foo", 47, + "bar", FALSE, + "baz", "Hello, World!", + "meh", 0.5, + NULL); + JsonParser *parser = NULL; + GError *error = NULL; + JsonObject *object; + JsonNode *node; + gchar *data; + gsize len; + + data = json_gobject_to_data (G_OBJECT (obj), &len); + + g_assert_cmpint (len, >, 0); + if (g_test_verbose ()) + g_print ("TestObject:\n%s\n", data); + + parser = json_parser_new (); + json_parser_load_from_data (parser, data, -1, &error); + g_assert (error == NULL); + + node = json_parser_get_root (parser); + g_assert (json_node_get_node_type (node) == JSON_NODE_OBJECT); + + object = json_node_get_object (node); + g_assert_cmpint (json_object_get_int_member (object, "foo"), ==, 47); + g_assert (!json_object_get_boolean_member (object, "bar")); + g_assert_cmpstr (json_object_get_string_member (object, "baz"), ==, "Hello, World!"); + g_assert_cmpfloat (json_object_get_double_member (object, "meh"), ==, 0.5); + + /* blah is read-only */ + g_assert (json_object_has_member (object, "blah")); + + g_free (data); + g_object_unref (parser); + g_object_unref (obj); + g_clear_error (&error); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/serialize/gobject-boxed", test_serialize); + + return g_test_run (); +} diff --git a/json-glib/tests/serialize-full.c b/json-glib/tests/serialize-full.c new file mode 100644 index 0000000..dd5da7a --- /dev/null +++ b/json-glib/tests/serialize-full.c @@ -0,0 +1,454 @@ +#include +#include +#include + +#include + +#include +#include + +#define TEST_TYPE_ENUM (test_enum_get_type ()) +#define TEST_TYPE_FLAGS (test_flags_get_type ()) +#define TEST_TYPE_BOXED (test_boxed_get_type ()) +#define TEST_TYPE_OBJECT (test_object_get_type ()) +#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject)) +#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass)) +#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass)) + +typedef enum { + TEST_ENUM_FOO, + TEST_ENUM_BAR, + TEST_ENUM_BAZ +} TestEnum; + +typedef enum { + TEST_FLAGS_NONE = 0, + TEST_FLAGS_FOO = 1 << 0, + TEST_FLAGS_BAR = 1 << 1, + TEST_FLAGS_BAZ = 1 << 2 +} TestFlags; + +typedef struct _TestBoxed TestBoxed; +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; + +struct _TestBoxed +{ + gint foo; + gboolean bar; +}; + +struct _TestObject +{ + GObject parent_instance; + + gint m_int; + gboolean m_bool; + gchar *m_str; + TestBoxed m_boxed; + TestEnum m_enum; + gchar **m_strv; + TestFlags m_flags; + + TestObject *m_obj; +}; + +struct _TestObjectClass +{ + GObjectClass parent_class; +}; + +GType test_object_get_type (void); + +/*** implementation ***/ + +static TestBoxed * +test_boxed_copy (const TestBoxed *src) +{ + TestBoxed *copy = g_slice_new (TestBoxed); + + *copy = *src; + + return copy; +} + +static void +test_boxed_free (TestBoxed *boxed) +{ + if (G_LIKELY (boxed)) + { + g_slice_free (TestBoxed, boxed); + } +} + +GType +test_boxed_get_type (void) +{ + static GType b_type = 0; + + if (G_UNLIKELY (b_type == 0)) + b_type = g_boxed_type_register_static ("TestBoxed", + (GBoxedCopyFunc) test_boxed_copy, + (GBoxedFreeFunc) test_boxed_free); + + return b_type; +} + +GType +test_enum_get_type (void) +{ + static GType e_type = 0; + + if (G_UNLIKELY (e_type == 0)) + { + static const GEnumValue values[] = { + { TEST_ENUM_FOO, "TEST_ENUM_FOO", "foo" }, + { TEST_ENUM_BAR, "TEST_ENUM_BAR", "bar" }, + { TEST_ENUM_BAZ, "TEST_ENUM_BAZ", "baz" }, + { 0, NULL, NULL } + }; + + e_type = g_enum_register_static ("TestEnum", values); + } + + return e_type; +} + +GType +test_flags_get_type (void) +{ + static GType e_type = 0; + + if (G_UNLIKELY (e_type == 0)) + { + static const GFlagsValue values[] = { + { TEST_FLAGS_NONE, "TEST_FLAGS_NONE", "none" }, + { TEST_FLAGS_FOO, "TEST_FLAGS_FOO", "foo" }, + { TEST_FLAGS_BAR, "TEST_FLAGS_BAR", "bar" }, + { TEST_FLAGS_BAZ, "TEST_FLAGS_BAZ", "baz" }, + { 0, NULL, NULL } + }; + + e_type = g_flags_register_static ("TestFlags", values); + } + + return e_type; +} + +enum +{ + PROP_0, + + PROP_FOO, + PROP_BAR, + PROP_BAZ, + PROP_BLAH, + PROP_MEH, + PROP_MAH, + PROP_FLAGS, + PROP_TEST +}; + +static void json_serializable_iface_init (gpointer g_iface); + +G_DEFINE_TYPE_WITH_CODE (TestObject, test_object, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (JSON_TYPE_SERIALIZABLE, + json_serializable_iface_init)); + +static JsonNode * +test_object_serialize_property (JsonSerializable *serializable, + const gchar *name, + const GValue *value, + GParamSpec *pspec) +{ + JsonNode *retval; + + if (strcmp (name, "blah") == 0) + { + TestBoxed *boxed; + JsonObject *obj; + + retval = json_node_new (JSON_NODE_OBJECT); + obj = json_object_new (); + + boxed = g_value_get_boxed (value); + + json_object_set_int_member (obj, "foo", boxed->foo); + json_object_set_boolean_member (obj, "bar", boxed->bar); + + json_node_take_object (retval, obj); + + test_boxed_free (boxed); + } + else + { + GValue copy = { 0, }; + + retval = json_node_new (JSON_NODE_VALUE); + + g_value_init (©, G_PARAM_SPEC_VALUE_TYPE (pspec)); + g_value_copy (value, ©); + json_node_set_value (retval, ©); + g_value_unset (©); + } + + return retval; +} + +static void +json_serializable_iface_init (gpointer g_iface) +{ + JsonSerializableIface *iface = g_iface; + + iface->serialize_property = test_object_serialize_property; +} + +static void +test_object_finalize (GObject *gobject) +{ + g_free (TEST_OBJECT (gobject)->m_str); + g_strfreev (TEST_OBJECT (gobject)->m_strv); + + if (TEST_OBJECT (gobject)->m_obj != NULL) + g_object_unref (TEST_OBJECT (gobject)->m_obj); + + G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject); +} + +static void +test_object_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_FOO: + TEST_OBJECT (gobject)->m_int = g_value_get_int (value); + break; + + case PROP_BAR: + TEST_OBJECT (gobject)->m_bool = g_value_get_boolean (value); + break; + + case PROP_BAZ: + g_free (TEST_OBJECT (gobject)->m_str); + TEST_OBJECT (gobject)->m_str = g_value_dup_string (value); + break; + + case PROP_MEH: + TEST_OBJECT (gobject)->m_enum = g_value_get_enum (value); + break; + + case PROP_MAH: + g_strfreev (TEST_OBJECT (gobject)->m_strv); + TEST_OBJECT (gobject)->m_strv = g_strdupv (g_value_get_boxed (value)); + break; + + case PROP_FLAGS: + TEST_OBJECT (gobject)->m_flags = g_value_get_flags (value); + break; + + case PROP_TEST: + g_clear_object (&(TEST_OBJECT (gobject)->m_obj)); + TEST_OBJECT (gobject)->m_obj = g_value_dup_object (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +test_object_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_FOO: + g_value_set_int (value, TEST_OBJECT (gobject)->m_int); + break; + + case PROP_BAR: + g_value_set_boolean (value, TEST_OBJECT (gobject)->m_bool); + break; + + case PROP_BAZ: + g_value_set_string (value, TEST_OBJECT (gobject)->m_str); + break; + + case PROP_BLAH: + g_value_set_boxed (value, &(TEST_OBJECT (gobject)->m_boxed)); + break; + + case PROP_MEH: + g_value_set_enum (value, TEST_OBJECT (gobject)->m_enum); + break; + + case PROP_MAH: + g_value_set_boxed (value, TEST_OBJECT (gobject)->m_strv); + break; + + case PROP_FLAGS: + g_value_set_flags (value, TEST_OBJECT (gobject)->m_flags); + break; + + case PROP_TEST: + g_value_set_object (value, TEST_OBJECT (gobject)->m_obj); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +test_object_class_init (TestObjectClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = test_object_set_property; + gobject_class->get_property = test_object_get_property; + gobject_class->finalize = test_object_finalize; + + g_object_class_install_property (gobject_class, + PROP_FOO, + g_param_spec_int ("foo", "Foo", "Foo", + 0, G_MAXINT, 42, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BAR, + g_param_spec_boolean ("bar", "Bar", "Bar", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property (gobject_class, + PROP_BAZ, + g_param_spec_string ("baz", "Baz", "Baz", + NULL, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BLAH, + g_param_spec_boxed ("blah", "Blah", "Blah", + TEST_TYPE_BOXED, + G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, + PROP_MEH, + g_param_spec_enum ("meh", "Meh", "Meh", + TEST_TYPE_ENUM, + TEST_ENUM_BAR, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_MAH, + g_param_spec_boxed ("mah", "Mah", "Mah", + G_TYPE_STRV, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_FLAGS, + g_param_spec_flags ("flags", "Flags", "Flags", + TEST_TYPE_FLAGS, + TEST_FLAGS_NONE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + g_object_class_install_property (gobject_class, + PROP_TEST, + g_param_spec_object ("test", "Test", "Test", + TEST_TYPE_OBJECT, + G_PARAM_READWRITE)); +} + +static void +test_object_init (TestObject *object) +{ + object->m_int = 0; + object->m_bool = FALSE; + object->m_str = NULL; + + object->m_boxed.foo = object->m_int; + object->m_boxed.bar = object->m_bool; + + object->m_enum = TEST_ENUM_BAR; + + object->m_strv = NULL; + + object->m_flags = TEST_FLAGS_NONE; + + object->m_obj = NULL; +} + +static const gchar *var_test = +"{\n" +" \"foo\" : 42,\n" +" \"bar\" : true,\n" +" \"baz\" : \"hello\",\n" +" \"meh\" : \"baz\",\n" +" \"mah\" : [ \"hello\", \", \", \"world\", \"!\" ],\n" +" \"test\" : {\n" +" \"bar\" : true,\n" +" \"baz\" : \"world\",\n" +" \"meh\" : 0,\n" +" \"flags\" : \"foo|bar\"" +" }\n" +"}"; + +static void +test_deserialize (void) +{ + TestObject *test; + GObject *object; + GError *error; + gchar *str; + + error = NULL; + object = json_gobject_from_data (TEST_TYPE_OBJECT, var_test, -1, &error); + if (error) + g_error ("*** Unable to parse buffer: %s\n", error->message); + + if (g_test_verbose ()) + g_print ("*** TestObject ***\n" + " foo: %s\n" + " bar: %s\n" + " baz: %s\n" + " meh: %s\n", + TEST_OBJECT (object)->m_int == 42 ? "" : "", + TEST_OBJECT (object)->m_bool == TRUE ? "" : "", + TEST_OBJECT (object)->m_str != NULL ? "" : "", + TEST_OBJECT (object)->m_enum == TEST_ENUM_BAZ ? "" : ""); + + g_assert_cmpint (TEST_OBJECT (object)->m_int, ==, 42); + g_assert (TEST_OBJECT (object)->m_bool); + g_assert_cmpstr (TEST_OBJECT (object)->m_str, ==, "hello"); + g_assert_cmpint (TEST_OBJECT (object)->m_enum, ==, TEST_ENUM_BAZ); + + g_assert (TEST_OBJECT (object)->m_strv != NULL); + g_assert_cmpint (g_strv_length (TEST_OBJECT (object)->m_strv), ==, 4); + + str = g_strjoinv (NULL, TEST_OBJECT (object)->m_strv); + g_assert_cmpstr (str, ==, "hello, world!"); + g_free (str); + + g_assert (TEST_IS_OBJECT (TEST_OBJECT (object)->m_obj)); + test = TEST_OBJECT (TEST_OBJECT (object)->m_obj); + g_assert (test->m_bool); + g_assert_cmpstr (test->m_str, ==, "world"); + g_assert_cmpint (test->m_enum, ==, TEST_ENUM_FOO); + g_assert_cmpint (test->m_flags, ==, TEST_FLAGS_FOO | TEST_FLAGS_BAR); + + g_object_unref (object); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/deserialize/json-to-gobject", test_deserialize); + + return g_test_run (); +} diff --git a/json-glib/tests/serialize-simple.c b/json-glib/tests/serialize-simple.c new file mode 100644 index 0000000..e2e7be2 --- /dev/null +++ b/json-glib/tests/serialize-simple.c @@ -0,0 +1,165 @@ +#include +#include +#include + +#include + +#include +#include + +#define TEST_TYPE_OBJECT (test_object_get_type ()) +#define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TEST_TYPE_OBJECT, TestObject)) +#define TEST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TEST_TYPE_OBJECT, TestObjectClass)) +#define TEST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TEST_TYPE_OBJECT)) +#define TEST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TEST_TYPE_OBJECT, TestObjectClass)) + +typedef struct _TestObject TestObject; +typedef struct _TestObjectClass TestObjectClass; + +struct _TestObject +{ + GObject parent_instance; + + gint foo; + gboolean bar; + gchar *baz; +}; + +struct _TestObjectClass +{ + GObjectClass parent_class; +}; + +GType test_object_get_type (void); + +/*** implementation ***/ + +enum +{ + PROP_0, + + PROP_FOO, + PROP_BAR, + PROP_BAZ +}; + +G_DEFINE_TYPE (TestObject, test_object, G_TYPE_OBJECT); + +static void +test_object_finalize (GObject *gobject) +{ + g_free (TEST_OBJECT (gobject)->baz); + + G_OBJECT_CLASS (test_object_parent_class)->finalize (gobject); +} + +static void +test_object_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_FOO: + TEST_OBJECT (gobject)->foo = g_value_get_int (value); + break; + case PROP_BAR: + TEST_OBJECT (gobject)->bar = g_value_get_boolean (value); + break; + case PROP_BAZ: + g_free (TEST_OBJECT (gobject)->baz); + TEST_OBJECT (gobject)->baz = g_value_dup_string (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +test_object_get_property (GObject *gobject, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + switch (prop_id) + { + case PROP_FOO: + g_value_set_int (value, TEST_OBJECT (gobject)->foo); + break; + case PROP_BAR: + g_value_set_boolean (value, TEST_OBJECT (gobject)->bar); + break; + case PROP_BAZ: + g_value_set_string (value, TEST_OBJECT (gobject)->baz); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + } +} + +static void +test_object_class_init (TestObjectClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->set_property = test_object_set_property; + gobject_class->get_property = test_object_get_property; + gobject_class->finalize = test_object_finalize; + + g_object_class_install_property (gobject_class, + PROP_FOO, + g_param_spec_int ("foo", "Foo", "Foo", + 0, G_MAXINT, 42, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BAR, + g_param_spec_boolean ("bar", "Bar", "Bar", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, + PROP_BAZ, + g_param_spec_string ("baz", "Baz", "Baz", + NULL, + G_PARAM_READWRITE)); +} + +static void +test_object_init (TestObject *object) +{ + object->foo = 42; + object->bar = FALSE; + object->baz = g_strdup ("Test"); +} + +static void +test_serialize (void) +{ + TestObject *obj = g_object_new (TEST_TYPE_OBJECT, "bar", TRUE, NULL); + gchar *data; + gsize len; + + data = json_gobject_to_data (G_OBJECT (obj), &len); + + g_assert (data != NULL); + g_assert_cmpint (len, >, 0); + g_assert_cmpint (len, ==, strlen (data)); + + if (g_test_verbose ()) + g_print ("TestObject:\n%s\n", data); + + g_free (data); + g_object_unref (obj); +} + +int +main (int argc, + char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/serialize/gobject", test_serialize); + + return g_test_run (); +} diff --git a/json-glib/tests/stream-load.json b/json-glib/tests/stream-load.json new file mode 100644 index 0000000..203f03f --- /dev/null +++ b/json-glib/tests/stream-load.json @@ -0,0 +1 @@ +[ { "hello" : "world!\n" } ] diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..1105d32 --- /dev/null +++ b/meson.build @@ -0,0 +1,165 @@ +project('json-glib', 'c', version: '1.4.4', + license: 'LGPLv2.1+', + default_options: [ + 'warning_level=1', + 'buildtype=debugoptimized', + 'c_std=c99', + ], + meson_version: '>= 0.40.1') + +# Versioning +json_version = meson.project_version() +version_arr = json_version.split('.') +json_version_major = version_arr[0].to_int() +json_version_minor = version_arr[1].to_int() +json_version_micro = version_arr[2].to_int() + +json_interface_age = json_version_minor.is_even() ? json_version_micro : 0 +json_binary_age = 100 * json_version_minor + json_version_micro +json_api_version = '1.0' + +json_api_name = '@0@-@1@'.format(meson.project_name(), json_api_version) +json_gettext_domain = json_api_name + +# Maintain compatibility with the old soname versioning +soversion = 0 +libversion = '@0@.@1@.@2@'.format(soversion, json_binary_age - json_interface_age, json_interface_age) + +# Paths +json_includedir = join_paths(get_option('prefix'), get_option('includedir')) +json_datadir = join_paths(get_option('prefix'), get_option('datadir')) +json_mandir = join_paths(get_option('prefix'), get_option('mandir')) +json_localedir = join_paths(get_option('prefix'), get_option('localedir')) +json_libexecdir = join_paths(get_option('prefix'), get_option('libexecdir')) + +# Dependencies +glib_req_version = '>= 2.44.0' +gobject_dep = dependency('gobject-2.0', version: glib_req_version) +gio_dep = dependency('gio-2.0', version: glib_req_version) + +# Configurations +cc = meson.get_compiler('c') +host_system = host_machine.system() + +cdata = configuration_data() +check_headers = [ + ['unistd.h', 'HAVE_UNISTD_H'], +] + +foreach h: check_headers + if cc.has_header(h.get(0)) + cdata.set(h.get(1), 1) + endif +endforeach + +cdata.set_quoted('GETTEXT_PACKAGE', json_gettext_domain) + +if cc.get_id() == 'msvc' + # Compiler options taken from msvc_recommended_pragmas.h + # in GLib, based on _Win32_Programming_ by Rector and Newcomer + test_cflags = [ + '-we4002', # too many actual parameters for macro + '-we4003', # not enough actual parameters for macro + '-w14010', # single-line comment contains line-continuation character + '-we4013', # 'function' undefined; assuming extern returning int + '-w14016', # no function return type; using int as default + '-we4020', # too many actual parameters + '-we4021', # too few actual parameters + '-we4027', # function declared without formal parameter list + '-we4029', # declared formal parameter list different from definition + '-we4033', # 'function' must return a value + '-we4035', # 'function' : no return value + '-we4045', # array bounds overflow + '-we4047', # different levels of indirection + '-we4049', # terminating line number emission + '-we4053', # an expression of type void was used as an operand + '-we4071', # no function prototype given + '-we4819', # the file contains a character that cannot be represented in the current code page + ] +elif cc.get_id() == 'gcc' or cc.get_id() == 'clang' + test_cflags = [ + '-Wcast-align', + '-Wlogical-op', + '-Wmissing-declarations', + '-Wmissing-format-attribute', + '-Wmissing-prototypes', + '-Wmissing-noreturn', + '-Wold-style-definition', + '-Wpointer-arith', + '-Wshadow', + '-Wstrict-prototypes', + '-Wunused', + '-Wno-discarded-qualifiers', + '-Wno-int-conversion', + '-fno-strict-aliasing', + '-Wno-uninitialized', + '-Werror=address', + '-Werror=array-bounds', + '-Werror=empty-body', + '-Werror=format=2', + '-Werror=implicit', + '-Werror=init-self', + '-Werror=int-to-pointer-cast', + '-Werror=main', + '-Werror=missing-braces', + '-Werror=nested-externs', + '-Werror=nonnull', + '-Werror=pointer-to-int-cast', + '-Werror=return-type', + '-Werror=sequence-point', + '-Werror=trigraphs', + '-Werror=undef', + '-Werror=write-strings', + ] +else + test_cflags = [] +endif + +if get_option('default_library') != 'static' + if host_system == 'windows' + cdata.set('DLL_EXPORT', true) + cdata.set('_JSON_EXTERN', '__declspec(dllexport) extern') + if cc.get_id() != 'msvc' + test_cflags += '-fvisibility=hidden' + endif + else + cdata.set('_JSON_EXTERN', '__attribute__((visibility("default"))) extern') + test_cflags += '-fvisibility=hidden' + endif +endif + +common_cflags = [] +foreach cflag: test_cflags + if cc.has_argument(cflag) + common_cflags += cflag + endif +endforeach + +common_ldflags = [] + +if host_system == 'linux' + foreach ldflag: [ '-Wl,-Bsymbolic', '-Wl,-z,relro', '-Wl,-z,now', ] + if cc.has_argument(ldflag) + common_ldflags += ldflag + endif + endforeach +endif + +# Maintain compatibility with autotools +if host_system == 'darwin' + common_ldflags += [ + '-compatibility_version 1', + '-current_version @0@.@1@'.format(json_binary_age - json_interface_age, json_interface_age), + ] +endif + +root_dir = include_directories('.') + +gnome = import('gnome') + +python3 = import('python3').find_python() +gen_installed_test = files('build-aux/gen-installed-test.py') + +subdir('json-glib') +subdir('po') +subdir('doc') diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..237b725 --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,9 @@ +option('introspection', + type: 'boolean', value: true, + description: 'Build the introspection data (requires gobject-introspection)') +option('docs', + type: 'boolean', value: false, + description: 'Build the API reference and man pages (requires gtk-doc and xsltproc)') +option('man', + type: 'boolean', value: false, + description: 'Build the man pages (requires xsltproc)') diff --git a/po/.gitignore b/po/.gitignore new file mode 100644 index 0000000..9ac1987 --- /dev/null +++ b/po/.gitignore @@ -0,0 +1,14 @@ +/Makefile.in.in +/Makevars.template +/POTFILES +/Rules-quot +/boldquot.sed +/en@boldquot.header +/en@quot.header +/insert-header.sin +/quot.sed +/remove-potcdate.sed +/remove-potcdate.sin +/stamp-po +*.gmo +*.pot diff --git a/po/LINGUAS b/po/LINGUAS new file mode 100644 index 0000000..7213bf9 --- /dev/null +++ b/po/LINGUAS @@ -0,0 +1,55 @@ +as +bg +bn_IN +bs +ca +ca@valencia +cs +da +de +el +en_GB +eo +es +et +eu +fr +fur +gl +he +hi +hr +hu +id +it +ja +ko +ky +lt +lv +ml +nb +ne +nl +oc +or +pa +pl +pt_BR +pt +ro +ru +sk +sl +sr@latin +sr +sv +te +tg +tr +ug +uk +vi +zh_CN +zh_HK +zh_TW diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..8868a19 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,8 @@ +# keep sorted alphabetically! +json-glib/json-glib-format.c +json-glib/json-glib-validate.c +json-glib/json-gobject.c +json-glib/json-gvariant.c +json-glib/json-parser.c +json-glib/json-path.c +json-glib/json-reader.c diff --git a/po/as.po b/po/as.po new file mode 100644 index 0000000..a8bdb0d --- /dev/null +++ b/po/as.po @@ -0,0 +1,267 @@ +# Assamese translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# Nilamdyuti Goswami , 2012, 2014. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-08-19 21:19+0000\n" +"PO-Revision-Date: 2014-08-20 13:18+0530\n" +"Last-Translator: Nilamdyuti Goswami \n" +"Language-Team: Assamese \n" +"Language: as\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: ../json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "আউটপুট ধূনীয়া কৰক" + +#: ../json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "ইণ্ডেন্টেষণ স্থানসমূহ" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:77 ../json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: ফাইল খোলোতে ত্ৰুটি: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:89 ../json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: ফাইল বিশ্লেষণ কৰোতে ত্ৰুটি: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: ../json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: stdout লৈ লিখোতে ত্ৰুটি" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:128 ../json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: বন্ধ কৰোতে ত্ৰুটি: %s\n" + +#: ../json-glib/json-glib-format.c:157 ../json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "ফাইল" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-format.c:160 +msgid "Format JSON files." +msgstr "JSON ফাইলসমূহক ফৰমেট কৰক।" + +#: ../json-glib/json-glib-format.c:161 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format এ JSON সম্পদসমূহক ফৰমেট কৰে।" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:178 ../json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "কমান্ডশাৰী বিকল্পসমূহ বিশ্লেষণ কৰোতে ত্ৰুটি: %s\n" + +#: ../json-glib/json-glib-format.c:180 ../json-glib/json-glib-format.c:194 +#: ../json-glib/json-glib-validate.c:138 ../json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "অধিক তথ্যৰ বাবে \"%s --help\" চেষ্টা কৰক।" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:192 ../json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: সন্ধানহীন ফাইলসমূহ" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "JSON ফাইলসমূহ সত্যাপন কৰক।" + +#: ../json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate এ প্ৰদান কৰা URl ত JSON তথ্য সত্যাপন কৰে।" + +#: ../json-glib/json-gobject.c:915 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "এটা JSON আশা কৰা হৈছে, কিন্তু ৰুট ন'ডৰ ধৰণ '%s'" + +#: ../json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON অৱস্থাত অপ্ৰত্যাশিত ধৰণ '%s'" + +#: ../json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "এটা টিউপুলৰ সৈতে সংগত হবলে JSON এৰেত কিছুমান উপাদান সন্ধানহীন" + +#: ../json-glib/json-gvariant.c:621 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "GVariant টিউপুল ধৰণত বন্ধৰ চিহ্ন ')' সন্ধানহীন" + +#: ../json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON এৰেত অপ্ৰত্যাশিত অতিৰিক্ত উপাদান" + +#: ../json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant লে পৰিবৰ্তন কৰোতে অবৈধ স্ট্ৰিং মান" + +#: ../json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"এটা GVariant অভিধান প্ৰবিষ্টিয়ে কেৱল এটা সদস্যৰ সৈতে এটা JSON অবজেক্ট আশা কৰে" + +#: ../json-glib/json-gvariant.c:1244 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant শ্ৰেণী '%c' সমৰ্থিত নহয়" + +#: ../json-glib/json-gvariant.c:1292 +msgid "Invalid GVariant signature" +msgstr "অবৈধ GVariant স্বাক্ষৰ" + +#: ../json-glib/json-gvariant.c:1340 +msgid "JSON data is empty" +msgstr "JSON তথ্য ৰিক্ত" + +#: ../json-glib/json-parser.c:815 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: বিশ্লেষণ ত্ৰুটি: %s" + +#: ../json-glib/json-parser.c:883 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON তথ্য UTF-8 এনক'ডেড হব লাগিব" + +#: ../json-glib/json-path.c:388 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath অভিব্যক্তিত কেৱল এটা ৰুট ন'ডৰ অনুমতি আছে" + +#: ../json-glib/json-path.c:397 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "ৰুট ন'ড অবৈধ আখৰ '%c' দ্বাৰা অনুকৰণ কৰা হৈছে" + +#: ../json-glib/json-path.c:437 +msgid "Missing member name or wildcard after . character" +msgstr ". আখৰৰ পিছত সন্ধানহীন সদস্য নাম অথবা ৱাইল্ডকাৰ্ড" + +#: ../json-glib/json-path.c:511 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "স্খলিত স্লাইচ অভিব্যক্তি '%*s'" + +#: ../json-glib/json-path.c:555 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "অবৈধ সংহতি বিৱৰণ '%*s'" + +#: ../json-glib/json-path.c:608 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "অবৈধ স্লাইচ বিৱৰণ '%*s'" + +#: ../json-glib/json-path.c:636 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "অভৈধ এৰে সূচী বিৱৰণ '%*s'" + +#: ../json-glib/json-path.c:655 +#, c-format +msgid "Invalid first character '%c'" +msgstr "অবৈধ প্ৰথম আখৰ '%c'" + +#: ../json-glib/json-reader.c:456 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "বৰ্তমান ন'ডৰ ধৰণ '%s', কিন্তু এটা এৰে অথবা এটা অবজেক্ট আশা কৰা হৈছিল।" + +#: ../json-glib/json-reader.c:468 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "সূচী '%d' বৰ্তমান অৱস্থানত এৰেৰ আকাৰতকে অধিক।" + +#: ../json-glib/json-reader.c:485 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "সূচী '%d' বৰ্তমান অৱস্থানত অবজেক্টৰ আকাৰতকে ডাঙৰ।" + +#: ../json-glib/json-reader.c:570 ../json-glib/json-reader.c:724 +#: ../json-glib/json-reader.c:775 ../json-glib/json-reader.c:813 +#: ../json-glib/json-reader.c:851 ../json-glib/json-reader.c:889 +#: ../json-glib/json-reader.c:927 ../json-glib/json-reader.c:972 +#: ../json-glib/json-reader.c:1008 ../json-glib/json-reader.c:1034 +msgid "No node available at the current position" +msgstr "বৰ্তমান অৱস্থানত কোনো ন'ড উপলব্ধ নাই" + +#: ../json-glib/json-reader.c:577 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "বৰ্তমান অৱস্থানত এটা '%s' আছে কিন্তু এটা এৰে নাই" + +#: ../json-glib/json-reader.c:640 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "বৰ্তমান ন'ডৰ ধৰণ '%s', কিন্তু এটা অবজেক্ট আশা কৰা হৈছিল।" + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "সদস্য '%s' বৰ্তমান অৱস্থানৰ অবজেক্টত বিৱৰিত নহয়।" + +#: ../json-glib/json-reader.c:731 ../json-glib/json-reader.c:782 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "বৰ্তমান অৱস্থানত এটা '%s' আছে কিন্তু এটা অবজেক্ট নাই" + +#: ../json-glib/json-reader.c:822 ../json-glib/json-reader.c:860 +#: ../json-glib/json-reader.c:898 ../json-glib/json-reader.c:936 +#: ../json-glib/json-reader.c:981 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "বৰ্তমান অৱস্থানত এটা '%s' আছে কিন্তু এটা মান নাই" + +#: ../json-glib/json-reader.c:944 +msgid "The current position does not hold a string type" +msgstr "বৰ্তমান অৱস্থানত এটা স্ট্ৰিং ধৰণ নাই" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "বৰ্তমান অৱস্থানত এটা পূৰ্ণসংখ্যা ধৰণ নাই" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "বৰ্তমান অৱস্থানত এটা দশমিকযুক্ত ধৰণ নাই" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "বৰ্তমান অৱস্থানত এটা বুলিয়ান ধৰণ নাই" diff --git a/po/bg.po b/po/bg.po new file mode 100644 index 0000000..2d358d4 --- /dev/null +++ b/po/bg.po @@ -0,0 +1,157 @@ +# Bulgarian translation for json-glib po-file +# Copyright (C) 2012, 2013 Free Software Foundation, Inc. +# This file is distributed under the same license as the json-glib package. +# Ivaylo Valkov , 2012. +# Alexander Shopov , 2013. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib\n" +"POT-Creation-Date: 2013-01-08 21:45+0200\n" +"PO-Revision-Date: 2013-01-08 21:45+0200\n" +"Last-Translator: Ivaylo Valkov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: ../json-glib/json-gobject.c:925 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Очакваха се данни в JSON, но кореновият елемент е от вида „%s“" + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Неочакван вид „%s“ във възел на JSON" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "" +"Липсват елементи в масив на JSON. Това пречи на използването му и като " +"списък." + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Липсва затварящият символ „)“ в списъка на GVariant" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "Неочаквани допълнителни елементи в масив на JSON" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "Неправилно преобразуване от низ в GVariant" + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "Речникът на GVariant очаква данни в JSON само с един член" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "Класът на GVariant „%c“ не се поддържа" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "Грешен подпис за вида GVariant" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "Няма данни в JSON" + +#: ../json-glib/json-parser.c:825 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Грешка при анализиране: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Позволен е само един коренов възел в изрази от вида „JSONPath“" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Символът „%c“ след кореновия възел е грешен" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Неправилен израз за отрязък: „%*s“" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Неправилна дефиниция за множество „%*s“" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Неправилна дефиниция за отрязък: „%*s“" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Неправилна дефиниция за индекс на масив „%*s“" + +#: ../json-glib/json-reader.c:464 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "Възелът е от вида „%s“. Очакваше се масив или обект." + +#: ../json-glib/json-reader.c:476 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "Индексът „%d“ е по-голям от броя на елементите в масива." + +#: ../json-glib/json-reader.c:493 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "Индексът „%d“ е по-голям от броя на елементите в обекта." + +#: ../json-glib/json-reader.c:577 ../json-glib/json-reader.c:730 +#: ../json-glib/json-reader.c:781 ../json-glib/json-reader.c:819 +#: ../json-glib/json-reader.c:857 ../json-glib/json-reader.c:895 +#: ../json-glib/json-reader.c:933 ../json-glib/json-reader.c:978 +#: ../json-glib/json-reader.c:1014 ../json-glib/json-reader.c:1040 +msgid "No node available at the current position" +msgstr "Липсва възел на тази позиция" + +#: ../json-glib/json-reader.c:584 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "На тази позиция трябва да има масив, а не „%s“" + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "Възелът е от вида „%s“. Очакваше се обект." + +#: ../json-glib/json-reader.c:654 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "Членът „%s“ не е дефиниран на тази позиция в обекта." + +#: ../json-glib/json-reader.c:737 ../json-glib/json-reader.c:788 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "На тази позиция трябва да има обект, а не „%s“" + +#: ../json-glib/json-reader.c:828 ../json-glib/json-reader.c:866 +#: ../json-glib/json-reader.c:904 ../json-glib/json-reader.c:942 +#: ../json-glib/json-reader.c:987 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "На тази позиция трябва да има стойност, а не „%s“" + +#: ../json-glib/json-reader.c:950 +msgid "The current position does not hold a string type" +msgstr "На тази позиция няма низ" diff --git a/po/bn_IN.po b/po/bn_IN.po new file mode 100644 index 0000000..96597ad --- /dev/null +++ b/po/bn_IN.po @@ -0,0 +1,156 @@ +# Bengali (India) translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# Sayak Sarkar , 2012. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2012-09-22 19:40+0000\n" +"PO-Revision-Date: 2012-09-23 11:44+0530\n" +"Last-Translator: Sayak Sarkar \n" +"Language-Team: Bengali (India) \n" +"Language: bn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#: ../json-glib/json-gobject.c:934 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "একটি JSON বস্তুর প্রত্যাশা করা হচ্ছে, কিন্তু রুট নোড টাইপ হল `%s'" + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON নোডের মধ্যে অপ্রত্যাশিত টাইপ '%s'" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON অ্যারের মধ্যে অনুপস্থিত উপাদানের একটি tuple বর্নিত" + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "GVariant tuple টাইপে শেষ চিহ্ন ')' অনুপস্থিত" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON অ্যারের মধ্যে অপ্রত্যাশিত অতিরিক্ত উপাদানসমূহ" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant এর রূপান্তরিকরণে স্ট্রিং-এর মান অবৈধ" + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "একটি GVariant অভিধান এন্ট্রি এক সদস্যের সঙ্গে ঠিক একটি JSON বস্তুর আশা করে" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant ক্লাস '%c' সমর্থিত নয়" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "অবৈধ GVariant স্বাক্ষর" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "JSON তথ্য খালি" + +#: ../json-glib/json-parser.c:818 +#, c-format +msgid "%s:%d: Parse error: %s" +msgstr "%s:%d: পার্স ত্রুটি: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "কেবলমাত্র একটি রুট নোড একটি JSONPath অভিব্যক্তিতে অনুমোদিত করা হয়" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "রুট নোড অবৈধ অক্ষর '%c' দ্বারা অনুসরিত" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "ত্রুটিপূর্ণ স্লাইস্ অভিব্যক্তি '%*s'" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "অবৈধ সেট সংজ্ঞা '%*s'" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "অবৈধ স্লাইস্ সংজ্ঞা '%*s'" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "অবৈধ অ্যারের সূচক সংজ্ঞা '%*s'" + +#: ../json-glib/json-reader.c:463 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "বর্তমান নোড '%s' ধরনের, কিন্তু একটি অ্যারে অথবা কোনো বস্তু প্রত্যাশিত ছিল।" + +#: ../json-glib/json-reader.c:475 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "সূচক '%d' বর্তমান অবস্থান এ অ্যারের মাপের চেয়ে বেশী।" + +#: ../json-glib/json-reader.c:492 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "সূচক '% d' বর্তমান অবস্থানে বস্তুর আকারের চেয়ে বৃহত্তর।" + +#: ../json-glib/json-reader.c:576 ../json-glib/json-reader.c:729 +#: ../json-glib/json-reader.c:780 ../json-glib/json-reader.c:818 +#: ../json-glib/json-reader.c:856 ../json-glib/json-reader.c:894 +#: ../json-glib/json-reader.c:932 ../json-glib/json-reader.c:977 +#: ../json-glib/json-reader.c:1013 ../json-glib/json-reader.c:1039 +msgid "No node available at the current position" +msgstr "বর্তমান অবস্থানে কোন নোড উপলব্ধ নয়" + +#: ../json-glib/json-reader.c:583 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "বর্তমান অবস্থানে একটি অ্যারের জায়গায় '%s' উপস্থিত" + +#: ../json-glib/json-reader.c:646 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "বর্তমান নোড '%s' ধরনের, কিন্তু একটি বস্তু প্রত্যাশিত ছিল।" + +#: ../json-glib/json-reader.c:653 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "'%s' সদস্য বর্তমান অবস্থানে অবজেক্টে সংজ্ঞায়িত করা নেই।" + +#: ../json-glib/json-reader.c:736 ../json-glib/json-reader.c:787 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "বর্তমান অবস্থানে একটি বস্তুর জায়গায় '%s' উপস্থিত" + +#: ../json-glib/json-reader.c:827 ../json-glib/json-reader.c:865 +#: ../json-glib/json-reader.c:903 ../json-glib/json-reader.c:941 +#: ../json-glib/json-reader.c:986 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "বর্তমান অবস্থানে একটি মানের জায়গায় '%s' উপস্থিত" + +#: ../json-glib/json-reader.c:949 +msgid "The current position does not hold a string type" +msgstr "বর্তমান অবস্থানে কোন স্ট্রিং নেই" diff --git a/po/bs.po b/po/bs.po new file mode 100644 index 0000000..ef0bd61 --- /dev/null +++ b/po/bs.po @@ -0,0 +1,252 @@ +msgid "" +msgstr "" +"Project-Id-Version: json-glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2015-02-26 22:41+0000\n" +"PO-Revision-Date: 2015-02-04 15:19+0000\n" +"Last-Translator: Samir Ribić \n" +"Language-Team: Bosnian \n" +"Language: bs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2015-02-05 06:46+0000\n" +"X-Generator: Launchpad (build 17331)\n" + +#: ../json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Uljepšati izlaz" + +#: ../json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Mjesta indentacije" + +#. Translators: the first %s is the program nami, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:77 ../json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: greška pri otvaranju datoteke: %s\n" + +#. Translators: the first %s is the program nami, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:89 ../json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: greška pri analizi datopteke: %s\n" + +#. Translators: the first %s is the program nami, the +#. * second one is the URI of the file. +#. +#: ../json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: greška pri pisanju stdout" + +#. Translators: the first %s is the program nami, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:128 ../json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: greška pri zatvaranju: %s\n" + +#: ../json-glib/json-glib-format.c:157 ../json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "DATOTEKA" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-format.c:160 +msgid "Format JSON files." +msgstr "Formatirati JSON datoteke." + +#: ../json-glib/json-glib-format.c:161 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatira JSON resurse." + +#. Translators: the %s is the program nami. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:178 ../json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Greška u prosljeđivanju opcija komandne linije: %s\n" + +#: ../json-glib/json-glib-format.c:180 ../json-glib/json-glib-format.c:194 +#: ../json-glib/json-glib-validate.c:138 ../json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Pokušajte \"%s --help\" za više informacija." + +#. Translators: the %s is the program nami. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:192 ../json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: datoteke koje nedostaju" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Potvrditi JSON datoteke." + +#: ../json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate potvrđuje JSON podatke na zadatom URI-u." + +#: ../json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Očekivan JSON objekat, ali je korijenski čvor tipa `%s'" + +#: ../json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Neočekivani tip `%s' u JSON čvoru" + +#: ../json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Nedostaju elementi u JSON nizu kako bi formirali/činili n-torku" + +#: ../json-glib/json-gvariant.c:621 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Nedostaje simbol zatvaranja ')' u GVariant tipu n-torke" + +#: ../json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Neočekivani dodatni elementi u JSON nizu" + +#: ../json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Pogrešna stringovna vrijednost konvertira se u GVariant" + +#: ../json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant unos u rječnik očekuje JSON objekat sa tačno jednim članom" + +#: ../json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant klasa '%c' nije podržana" + +#: ../json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Pogrešan GVariant potpis" + +#: ../json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON podaci su prazni" + +#: ../json-glib/json-parser.c:815 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Greška u analizi: %s" + +#: ../json-glib/json-parser.c:883 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON podaci moraju biti UTF-8 kodirani" + +#: ../json-glib/json-path.c:388 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Samo jedan korijenski čvor je dozvoljen u JSONPath izrazu" + +#: ../json-glib/json-path.c:397 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Korijenski čvor prati pogrešan znak '%c'" + +#: ../json-glib/json-path.c:437 +msgid "Missing member name or wildcard after . character" +msgstr "NEdostaje člansko ime ili zamjenski znak . poslije" + +#: ../json-glib/json-path.c:511 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Deformirani izraz isječka '%*s'" + +#: ../json-glib/json-path.c:555 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Pogrešna definicija skupa '%*s'" + +#: ../json-glib/json-path.c:608 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Pogrešna definicija isječka '%*s'" + +#: ../json-glib/json-path.c:636 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Pogrešna definicija indeksa niza '%*s'" + +#: ../json-glib/json-path.c:655 +#, c-format +msgid "Invalid first character '%c'" +msgstr "Nevažeći prvi znak '%c'" + +#: ../json-glib/json-reader.c:459 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "Trenutni čvor je tipa '%s', ali je očekivan ili niz ili objekat." + +#: ../json-glib/json-reader.c:471 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "Indeks '%d' je veći od veličine niza na trenutnoj poziciji." + +#: ../json-glib/json-reader.c:488 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "Indeks '%d' je veći od veličine objekta na trenutnoj poziciji." + +#: ../json-glib/json-reader.c:572 ../json-glib/json-reader.c:723 +#: ../json-glib/json-reader.c:774 ../json-glib/json-reader.c:812 +#: ../json-glib/json-reader.c:850 ../json-glib/json-reader.c:888 +#: ../json-glib/json-reader.c:926 ../json-glib/json-reader.c:971 +#: ../json-glib/json-reader.c:1007 ../json-glib/json-reader.c:1033 +msgid "No node available at the current position" +msgstr "Nema raspoloživog čvora na trenutnoj poziciji." + +#: ../json-glib/json-reader.c:579 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "Trenutna pozicija sadrži '%s', a ne niz." + +#: ../json-glib/json-reader.c:642 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "Trenutni čvor je tipa '%s', a očekivan je objekt." + +#: ../json-glib/json-reader.c:649 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "Član '%s' nije definiran u objektu na trenutnoj poziciji." + +#: ../json-glib/json-reader.c:730 ../json-glib/json-reader.c:781 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "Trenutna pozicija sadrži '%s' a ne objekt." + +#: ../json-glib/json-reader.c:821 ../json-glib/json-reader.c:859 +#: ../json-glib/json-reader.c:897 ../json-glib/json-reader.c:935 +#: ../json-glib/json-reader.c:980 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "Trenutna pozicija sadrži '%s', a ne vrijednost" + +#: ../json-glib/json-reader.c:943 +msgid "The current position does not hold a string type" +msgstr "Trenutna pozicija ne sadrži stringovni tip vrijednosti" diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 0000000..032eabe --- /dev/null +++ b/po/ca.po @@ -0,0 +1,268 @@ +# Catalan translation for json-glib. +# Copyright (C) 2012 Free Software Foundation, Inc. +# This file is distributed under the same license as the json-glib package. +# Gil Forcada , 2012, 2013, 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-08-15 04:47+0000\n" +"PO-Revision-Date: 2017-08-21 21:06+0200\n" +"Last-Translator: Gil Forcada \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 1.8.11\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Formata la sortida" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Espais de sagnat" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: s'ha produït un error en obrir el fitxer: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: s'ha produït un error en analitzar el fitxer: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: s'ha produït un error en escriure a la sortida estàndard" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: s'ha produït un error en tancar: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FITXER" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formata fitxers JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "El json-glib-format formata recursos JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "" +"S'ha produït un error en analitzar les opcions de la línia d'ordres: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Per a més informació proveu «%s --help»." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: manquen els fitxers" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Valida fitxers JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "El json-glib-validate valida les dades JSON de l'URI donat." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "S'esperava un objecte JSON, però el node arrel és del tipus «%s»" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "No s'esperava el tipus «%s» en un node de JSON" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Manquen elements en la matriu de JSON perquè siguin una tupla" + +#: json-glib/json-gvariant.c:622 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Manca el símbol de tancament «)» pel tipus de tupla de GVariant" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "No s'esperaven elements extra en la matriu de JSON" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "La cadena no es pot convertir a GVariant, la conversió no és vàlida" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Un diccionari de GVariant requereix un objecte de JSON amb un sol membre" + +#: json-glib/json-gvariant.c:1242 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "La classe «%c» de GVariant no es pot utilitzar" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "La signatura de GVariant no és vàlida" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "No hi ha dades de JSON" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: error en l'anàlisi: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Les dades JSON han d'estar codificades amb UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Només es pot utilitzar un node arrel en una expressió JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "El caràcter «%c» que segueix el node arrel no és vàlid" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Manca el nom del membre o un comodí després del caràcter «.»" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "L'expressió de tallat «%*s» no està ben formatada" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "La definició del conjunt «%*s» no és vàlida" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "La definició del tallat «%*s» no és vàlida" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "La definició de l'índex de la matriu «%*s» no és vàlida" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "El primer caràcter «%c» no és vàlid" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"El node actual és de tipus «%s», però s'esperava una matriu, o bé, un " +"objecte." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "L'índex «%d» és més gran que la mida de la matriu a la posició actual." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "L'índex «%d» és més gran que la mida de l'objecte a la posició actual." + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "No hi ha cap node disponible a la posició actual" + +#: json-glib/json-reader.c:592 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "A la posició actual hi ha un «%s» i no una matriu" + +#: json-glib/json-reader.c:668 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "El node actual és de tipus «%s», però s'esperava un objecte." + +#: json-glib/json-reader.c:675 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "El membre «%s» no està definit a l'objecte de la posició actual." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "A la posició actual hi ha un «%s» i no un objecte" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "A la posició actual hi ha un «%s» i no un valor" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "A la posició actual no hi ha una cadena" diff --git a/po/ca@valencia.po b/po/ca@valencia.po new file mode 100644 index 0000000..9ee5819 --- /dev/null +++ b/po/ca@valencia.po @@ -0,0 +1,268 @@ +# Catalan translation for json-glib. +# Copyright (C) 2012 Free Software Foundation, Inc. +# This file is distributed under the same license as the json-glib package. +# Gil Forcada , 2012, 2013, 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-08-24 10:49+0000\n" +"PO-Revision-Date: 2017-08-21 21:06+0200\n" +"Last-Translator: Xavi Ivars \n" +"Language-Team: Catalan \n" +"Language: ca-valencia\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Poedit 1.8.11\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Formata l'eixida" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Espais de sagnat" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: s'ha produït un error en obrir el fitxer: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: s'ha produït un error en analitzar el fitxer: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: s'ha produït un error en escriure a l'eixida estàndard" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: s'ha produït un error en tancar: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FITXER" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formata fitxers JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "El json-glib-format formata recursos JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "" +"S'ha produït un error en analitzar les opcions de la línia d'ordes: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Per a més informació proveu «%s --help»." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: manquen els fitxers" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Valida fitxers JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "El json-glib-validate valida les dades JSON de l'URI donat." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "S'esperava un objecte JSON, però el node arrel és del tipus «%s»" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "No s'esperava el tipus «%s» en un node de JSON" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Manquen elements en la matriu de JSON perquè siguen una tupla" + +#: json-glib/json-gvariant.c:622 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Falta el símbol de tancament «)» pel tipus de tupla de GVariant" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "No s'esperaven elements extra en la matriu de JSON" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "La cadena no es pot convertir a GVariant, la conversió no és vàlida" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Un diccionari de GVariant requereix un objecte de JSON amb un sol membre" + +#: json-glib/json-gvariant.c:1242 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "La classe «%c» de GVariant no es pot utilitzar" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "La signatura de GVariant no és vàlida" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "No hi ha dades de JSON" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: error en l'anàlisi: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Les dades JSON han d'estar codificades amb UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Només es pot utilitzar un node arrel en una expressió JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "El caràcter «%c» que segueix el node arrel no és vàlid" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Falta el nom del membre o un comodí després del caràcter «.»" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "L'expressió de tallat «%*s» no està ben formatada" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "La definició del conjunt «%*s» no és vàlida" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "La definició del tallat «%*s» no és vàlida" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "La definició de l'índex de la matriu «%*s» no és vàlida" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "El primer caràcter «%c» no és vàlid" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"El node actual és de tipus «%s», però s'esperava una matriu, o bé, un " +"objecte." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "L'índex «%d» és més gran que la mida de la matriu a la posició actual." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "L'índex «%d» és més gran que la mida de l'objecte a la posició actual." + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "No hi ha cap node disponible a la posició actual" + +#: json-glib/json-reader.c:592 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "A la posició actual hi ha un «%s» i no una matriu" + +#: json-glib/json-reader.c:668 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "El node actual és de tipus «%s», però s'esperava un objecte." + +#: json-glib/json-reader.c:675 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "El membre «%s» no està definit a l'objecte de la posició actual." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "A la posició actual hi ha un «%s» i no un objecte" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "A la posició actual hi ha un «%s» i no un valor" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "A la posició actual no hi ha una cadena" diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000..84f7610 --- /dev/null +++ b/po/cs.po @@ -0,0 +1,264 @@ +# Czech translation for json-glib. +# Copyright (C) 2011 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Marek Černocký , 2011, 2012, 2014, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-08-02 07:17+0200\n" +"Last-Translator: Marek Černocký \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: Gtranslator 2.91.6\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Lépe upravit výstup" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Mezery pro odsazení" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: chyba při otevírání souboru: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: chyba při analýze souboru: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: chyba při zápisu do standardního výstupu" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: chyba při zavírání: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "SOUBOR" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formátovat soubory JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formátuje prostředky JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Chyba při zpracování přepínačů příkazového řádku: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Pro více informací zkuste použít „%s --help“." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: schází soubory" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Ověřit platnost souborů JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate ověřuje platnost dat JSON na zadané adrese URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Očekává se objekt JSON, ale kořenový uzel je typu „%s“" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Neočekávaný typ „%s“ v uzlu JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Schází prvky v poli JSON, aby to byla n-tice" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Schází uzavírací symbol „)“ v typu n-tice GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Neočekávané dodatečné prvky v poli JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Neplatná hodnota typu řetězec převáděná na GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "Záznam slovníku GVariant očekává objekt JSON s právě jedním členem" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Třída GVariant „%c“ není podporována" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Neplatná signatura GVariant" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Data JSON jsou prázdná" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Chyba zpracování: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Data JSON musí být kódována v UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Ve výrazu JSONPath je dovolen pouze jeden kořenový uzel" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Kořenový uzel následován neplatným znakem „%c“" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Schází název člena nebo divoký znak po znaku tečky." + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Chybný výraz dílu „%*s“" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Neplatná definice množiny „%*s“" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Neplatná definice dílu „%*s“" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Neplatná definice indexu pole „%*s“" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Neplatný první znak „%c“" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Aktuální uzel je typu „%s“, ale bylo očekáváno pole nebo objekt." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Index „%d“ je větší než velikost pole na aktuální pozici." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Index „%d“ je větší než velikost objektu na aktuální pozici." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Na aktuální pozici není k dispozici žádný uzel" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Aktuální pozice obsahuje „%s“ a ne pole" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Aktuální uzel je typu „%s“, ale byl očekáván objekt." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Člen „%s“ není na aktuálním pozici v objektu definován." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Aktuální pozice obsahuje „%s“ a ne objekt" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Aktuální pozice obsahuje „%s“ a ne hodnotu" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Aktuální pozice neobsahuje typ string (řetězec)" diff --git a/po/da.po b/po/da.po new file mode 100644 index 0000000..b6c6e90 --- /dev/null +++ b/po/da.po @@ -0,0 +1,264 @@ +# Danish translation for json-glib. +# Copyright (C) 2012-2013, 2017 json-glib's developers +# This file is distributed under the same license as the json-glib package. +# +# Ask Hjorth Larsen , 2012-2013, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-09-10 20:01+0200\n" +"Last-Translator: Ask Hjorth Larsen \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Gør udskrift pæn" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Indrykningsmellemrum" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: fejl ved åbning af fil: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: fejl ved fortolkning af fil: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: fejl ved skrivning til stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: fejl ved lukning: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FIL" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatér JSON-filer." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formaterer JSON-ressourcer." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Fejl ved fortolkning af kommandolinjetilvalg: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Prøv “%s --help” for at få yderligere oplysninger." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: manglende filer" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Kontrollér JSON-filer." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate kontrollerer JSON-data på den givne URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Forventer et JSON-objekt, men rodknuden er af typen “%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Uventet type “%s” i JSON-knude" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Manglende elementer i JSON-array for at kunne være en tuple" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Manglende lukkesymbol “)” i GVariant-tupletype" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Uventet ekstra elementer i JSON-array" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Ugyldig strengværdi ved konvertering til GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "En GVariant-ordbogspost forventer et JSON-objekt med nøjagtigt ét tal" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "GVariant-klassen “%c” understøttes ikke" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Ugyldig GVariant-underskrift" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON-data er tom" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Fortolkningsfejl: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON-data skal være UTF-8-kodet" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Kun en rodknude tillades i et JSONPath-udtryk" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Rodknuden efterfølges af et ugyldigt tegn, “%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Manglende medlemsnavn eller wildcard efter .-tegn" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Fejlformateret slice-udtryk “%*s”" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Ugyldig mængdedefinition “%*s”" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Ugyldig slice-definition “%*s”" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Ugyldig arrayindeksdefinition “%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Ugyldigt første tegn “%c”" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Den nuværende knude er af typen “%s”, men der blev forventet et array eller et objekt." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Indekset “%d” er større end størrelsen på arrayet ved den nuværende position." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Indekset “%d” er større end størrelsen på objektet ved den nuværende position." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Ingen tilgængelig knude på nuværende position" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Den nuværende position indeholder en “%s” og ikke et array" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Den nuværende knude er af typen “%s”, men der blev forventet et objekt." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Medlemmet “%s” er ikke defineret i objektet på den nuværende position." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Den nuværende position indeholder en “%s” og ikke et objekt" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Den nuværende position indeholder en “%s” og ikke en værdi" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Den nuværende position indeholder ikke en strengtype" diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..32f24de --- /dev/null +++ b/po/de.po @@ -0,0 +1,282 @@ +# German translation for json-glib. +# Copyright (C) 2011 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Mario Blättermann , 2011, 2017. +# Wolfgang Stöggl , 2012, 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-04-28 12:13+0200\n" +"Last-Translator: Mario Blättermann \n" +"Language-Team: Deutsch \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8.12\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Ausgabe hübsch gestalten" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Einrückungsleerzeichen" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: Fehler beim Öffnen der Datei: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: Fehler beim Verarbeiten der Datei: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: Fehler beim Schreiben auf die Standardausgabe" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: Fehler beim Schließen: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "DATEI" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "JSON-Datei formatieren." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatiert JSON-Ressourcen." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Fehler beim Verarbeiten der Befehlszeilenoptionen: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Versuchen Sie »%s --help« für mehr Informationen." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: Fehlende Dateien" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "JSON-Datei auf Gültigkeit prüfen." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate prüft JSON-Daten der angegebenen Adresse." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Ein JSON-Objekt wurde erwartet, aber der Root-Knoten hat den Typ »%s«" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Unerwarteter Typ »%s« im JSON-Knoten" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Elemente im JSON-Array fehlen, um konform zu einem Tupel zu sein" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Schließende Klammer »)« im Typ des GVariant-Tupels fehlt" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Unerwartete zusätzliche Elemente im JSON-Array" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Ungültiger Zeichenkettenwert zur GVariant-Umwandlung" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Ein GVariant-Verzeichniseintrag erwartet ein JSON-Objekt mit genau einem " +"Element" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "GVariant-Klasse »%c« wird nicht unterstützt" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Ungültige GVariant-Signatur" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON-Daten sind leer" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Verarbeitungsfehler: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON-Daten müssen in UTF-8 kodiert sein" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Im JSONPath-Ausdruck ist nur ein einziger Root-Knoten erlaubt" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Auf den Root-Knoten folgt das ungültige Zeichen »%c«" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Name des Elements oder Platzhalter nach dem . Zeichen fehlt" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Ungültiger Slice-Ausdruck »%*s«" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Ungültige »set«-Definition »%*s«" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Ungültige »slice«-Definition »%*s«" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Ungültige Array-Index-Definition »%*s«" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Ungültiges erstes Zeichen »%c«" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"Der Typ des aktuellen Knotens ist »%s«, aber ein Array oder Objekt wurde " +"erwartet." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"Der Index »%d« übersteigt die Größe des Arrays an der aktuellen Position." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"Der Index »%d« übersteigt die Größe des Objekts an der aktuellen Position." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "An der aktuellen Position ist kein Knoten verfügbar" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "An der aktuellen Position befindet sich ein »%s« und kein Array" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Der aktuelle Knoten hat den Typ »%s«, aber ein Objekt wurde erwartet." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "" +"Das Element »%s« ist im Objekt an der aktuellen Position nicht definiert." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "An der aktuellen Position befindet sich ein »%s« und kein Objekt" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "" +"An der aktuellen Position befindet sich ein »%s«, welches kein Wert ist" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "An der aktuellen Position befindet sich kein Zeichenketten-Typ" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "An der aktuellen Position befindet sich kein Ganzzahl-Typ" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "An der aktuellen Position befindet sich kein Gleitkomma-Typ" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "An der aktuellen Position befindet sich kein boolescher Typ" diff --git a/po/el.po b/po/el.po new file mode 100644 index 0000000..236337a --- /dev/null +++ b/po/el.po @@ -0,0 +1,307 @@ +# Greek translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Dimitris Spingos , 2012. +# Dimitris Spingos (Δημήτρης Σπίγγος) , 2012, 2013, 2014. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-09-10 11:33+0200\n" +"Last-Translator: Efstathios Iosifidis \n" +"Language-Team: team@lists.gnome.gr\n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.5.7\n" +"X-Project-Style: gnome\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Ωραιοποίηση εξόδου" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Διαστήματα εσοχών" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: σφάλμα ανοίγματος αρχείου: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: σφάλμα ανάλυσης αρχείου: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: σφάλμα εγγραφής στην τυπική έξοδο" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: σφάλμα κλεισίματος: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "ΑΡΧΕΙΟ" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Μορφή αρχείων JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "το json-glib-format μορφοποιεί τους πόρους JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Σφάλμα ανάλυσης επιλογών της γραμμής εντολών: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Δοκιμάστε «%s --help» για περισσότερες πληροφορίες." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: λείπουν αρχεία" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Επικυρώστε αρχεία JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "το json-glib-validate επικυρώνει δεδομένα JSON στο δοσμένο URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Αναμένεται αντικείμενο JSON, αλλά ο αρχικός κόμβος είναι τύπου «%s»" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Αναπάντεχος τύπος «%s» σε κόμβο JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Λείπουν στοιχεία σε πίνακα JSON για συμφωνία με πλειάδα" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Λείπει το σύμβολο κλεισίματος «)» στον τύπο πλειάδας GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Αναπάντεχα πρόσθετα στοιχεία σε πίνακα JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Άκυρη τιμή συμβολοσειράς μετατροπής σε GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Μια καταχώριση λεξικού GVariant περιμένει ένα αντικείμενο JSON με ακριβώς " +"ένα μέλος" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "Η κλάση GVariant «%c» δεν υποστηρίζεται" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Άκυρη υπογραφή GVariant" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Τα δεδομένα JSON είναι κενά" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Σφάλμα ανάλυσης: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Τα δεδομένα JSON πρέπει να είναι κωδικοποιημένα ως UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Μόνο ένας αρχικός κόμβος επιτρέπεται σε μια έκφραση JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Αρχικός κόμβος ακολουθούμενος από μη έγκυρο χαρακτήρα «%c»" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Λείπει όνομα μέλους ή συμβόλου υποκατάστασης μετά τον χαρακτήρα ." + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Κακοδιατυπωμένη έκφραση τεμαχισμού «%*s»" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Άκυρος ορισμός συνόλου «%*s»" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Άκυρος ορισμός τεμαχισμού «%*s»" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Μη έγκυρος ορισμός δείκτη πίνακα «%*s»" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Μή έγκυρος ο πρώτος χαρακτήρας «%c»" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"Ο τρέχων κόμβος είναι τύπου «%s», αλλά αναμενόταν ένας πίνακας ή ένα " +"αντικείμενο." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"Ο δείκτης «%d» είναι μεγαλύτερος από το μέγεθος του πίνακα στην τρέχουσα " +"θέση." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"Ο δείκτης «%d» είναι μεγαλύτερος από το μέγεθος του αντικειμένου στην " +"τρέχουσα θέση." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Κανένας διαθέσιμος κόμβος στην τρέχουσα θέση" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "Η τρέχουσα θέση περιέχει ένα «%s» και όχι ένα πίνακα" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Ο τρέχων κόμβος είναι του τύπου «%s», αλλά αναμενόταν ένα αντικείμενο." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Το μέλος «%s» δεν ορίζεται στο αντικείμενο στην τρέχουσα θέση." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "Η τρέχουσα θέση περιέχει ένα «%s» και όχι ένα αντικείμενο" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "Η τρέχουσα θέση περιέχει ένα «%s» και όχι μια τιμή" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Η τρέχουσα θέση δεν περιέχει τύπο συμβολοσειράς" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "Η τρέχουσα θέση δεν περιέχει ακέραιο τύπο" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "Η τρέχουσα θέση δεν περιέχει τύπο κινητής υποδιαστολής" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "Η τρέχουσα θέση δεν περιέχει τύπο boolean" diff --git a/po/en_GB.po b/po/en_GB.po new file mode 100644 index 0000000..7c69bd7 --- /dev/null +++ b/po/en_GB.po @@ -0,0 +1,261 @@ +# British English translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Abigail Brady , Bastien Nocera , 2016. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2016-09-12 18:19+0000\n" +"PO-Revision-Date: 2016-09-18 10:56+0200\n" +"Last-Translator: David King \n" +"Language-Team: British English \n" +"Language: en_GB\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);;\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Prettify output" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Indentation spaces" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: error opening file: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: error parsing file: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: error writing to stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: error closing: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FILE" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Format JSON files." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formats JSON resources." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Error parsing commandline options: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Try \"%s --help\" for more information." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: missing files" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validate JSON files." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate validates JSON data at the given URI." + +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Expecting a JSON object, but the root node is of type `%s'" + +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Unexpected type '%s' in JSON node" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Missing elements in JSON array to conform to a tuple" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Missing closing symbol ')' in the GVariant tuple type" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Unexpected extra elements in JSON array" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Invalid string value converting to GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"A GVariant dictionary entry expects a JSON object with exactly one member" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant class '%c' not supported" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Invalid GVariant signature" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON data is empty" + +#: json-glib/json-parser.c:914 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Parse error: %s" + +#: json-glib/json-parser.c:997 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON data must be UTF-8 encoded" + +#: json-glib/json-path.c:388 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Only one root node is allowed in a JSONPath expression" + +#: json-glib/json-path.c:397 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Root node followed by invalid character '%c'" + +#: json-glib/json-path.c:437 +msgid "Missing member name or wildcard after . character" +msgstr "Missing member name or wildcard after . character" + +#: json-glib/json-path.c:511 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Malformed slice expression '%*s'" + +#: json-glib/json-path.c:555 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Invalid set definition '%*s'" + +#: json-glib/json-path.c:608 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Invalid slice definition '%*s'" + +#: json-glib/json-path.c:636 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Invalid array index definition '%*s'" + +#: json-glib/json-path.c:655 +#, c-format +msgid "Invalid first character '%c'" +msgstr "Invalid first character '%c'" + +#: json-glib/json-reader.c:473 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "" +"The current node is of type '%s', but an array or an object was expected." + +#: json-glib/json-reader.c:485 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "" +"The index '%d' is greater than the size of the array at the current position." + +#: json-glib/json-reader.c:502 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "" +"The index '%d' is greater than the size of the object at the current " +"position." + +#: json-glib/json-reader.c:586 json-glib/json-reader.c:750 +#: json-glib/json-reader.c:801 json-glib/json-reader.c:839 +#: json-glib/json-reader.c:877 json-glib/json-reader.c:915 +#: json-glib/json-reader.c:953 json-glib/json-reader.c:998 +#: json-glib/json-reader.c:1034 json-glib/json-reader.c:1060 +msgid "No node available at the current position" +msgstr "No node available at the current position" + +#: json-glib/json-reader.c:593 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "The current position holds a '%s' and not an array" + +#: json-glib/json-reader.c:669 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "The current node is of type '%s', but an object was expected." + +#: json-glib/json-reader.c:676 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "The member '%s' is not defined in the object at the current position." + +#: json-glib/json-reader.c:757 json-glib/json-reader.c:808 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "The current position holds a '%s' and not an object" + +#: json-glib/json-reader.c:848 json-glib/json-reader.c:886 +#: json-glib/json-reader.c:924 json-glib/json-reader.c:962 +#: json-glib/json-reader.c:1007 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "The current position holds a '%s' and not a value" + +#: json-glib/json-reader.c:970 +msgid "The current position does not hold a string type" +msgstr "The current position does not hold a string type" diff --git a/po/eo.po b/po/eo.po new file mode 100644 index 0000000..b35a882 --- /dev/null +++ b/po/eo.po @@ -0,0 +1,302 @@ +# Esperanto translation for json-glib. +# Copyright (C) 2013 Free Software Foundation, Inc. +# This file is distributed under the same license as the json-glib package. +# Kristjan SCHMIDT , 2013, 2017. +msgid "" +msgstr "" +"Project-Id-Version: json-glib\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-03 11:44+0000\n" +"PO-Revision-Date: 2017-06-10 01:06+0200\n" +"Last-Translator: Kristjan SCHMIDT \n" +"Language-Team: gnome-eo-list@gnome.org\n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Virtaal 0.7.1\n" +"X-Project-Style: gnome\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: eraro dum malfermo de dosiero: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: eraro dum analizo de dosiero: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format, fuzzy +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: eraro dum skribado al stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: eraro dum fermo: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "DOSIERO" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "" + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "" + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "" + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Atendis JSON-objekton, sed la radika nodo havas la tipon “%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Neatendita tipo “%s” en JSON-nodo" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Elementoj mankas en la JSON-tabelo por esti konforma al tupelo" + +#: json-glib/json-gvariant.c:621 +#, fuzzy +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Fermanta signo “)” mankas en la GVariant-tupelo-tipo" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Neatenditaj pluaj elementoj en JSON-tabelo" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Nevalida signoĉena valoro por konverto al GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant-vortaro-enigo atendas JSON-objekton kun ekzakte unu membro" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "GVariant-klaso “%c” ne estas subtenata" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Nevalida GVariant-subskribo" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON-datumoj estas malplenaj" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Analiz-eraro: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Nur unu 'Root'-nodo estas permesata en JSONPath-esprimo" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, fuzzy, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Malantaŭ la radika nodo sekvas nevalida signo “%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "" + +#: json-glib/json-path.c:512 +#, fuzzy, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Nevalida segment-esprimo “%*s”" + +#: json-glib/json-path.c:556 +#, fuzzy, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Nevalida \"set\"-difino “%*s”" + +#: json-glib/json-path.c:609 +#, fuzzy, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Nevalida segment-difino “%*s”" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Nevalida tabel-indeks-difino “%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Nevalida unua signo “%c”" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"La tipo de la nuna nodo estas “%s“, sed tabelo aŭ objekto estis atendita." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"La indekso “%d” estas pli grande ol la grando de la tabelo ĉe la aktuala " +"pozicio." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"La indekso “%d” estas pli grande ol la grando de la objekto ĉe la aktuala " +"pozicio." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Neniu nodo estas ĉe la aktuala pozicio" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "La aktuala pozicio havas na “%s“ kaj ne tabelon" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "La aktuala nodo havas la tipon “%s“, sed objekto estis atendita." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "La membro “%s” ne estas definita en la objekto ĉe la aktuala pozicio." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "La aktuala pozicio havas na “%s” kaj ne objekton" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "La aktuala pozicio havas na “%s” kaj ne valoron" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "La aktuala pozicio ne havas signoĉenan tipon" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "La aktuala pozicio ne havas entjeran tipon" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "La aktuala pozicio ne havas glitkoman tipon" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "La aktuala pozicio ne havas bulean tipon" diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..5268e88 --- /dev/null +++ b/po/es.po @@ -0,0 +1,304 @@ +# Spanish translation for json-glib. +# Copyright (C) 2011 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# FIRST AUTHOR , YEAR. +# Daniel Mustieles , 2011, 2012, 2013, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-04-24 16:43+0200\n" +"Last-Translator: Daniel Mustieles \n" +"Language-Team: es \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Gtranslator 2.91.6\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Embellecer la salida" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Espacios de sangrado" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: error al abrir el archivo: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: error al analizar: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: error al escribir en la salida estándar" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: error al cerrar: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "ARCHIVO" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatear archivos JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatea recursos JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Error al analizar las opciones de la línea de comandos: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Pruebe «%s --help» para obtener más información." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: faltan archivos" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validar archivos JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate valida los datos JSON del URI dado." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Se esperaba un objeto JSON, pero el nodo raíz es de tipo «%s»" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Tipo «%s» no esperado en un nodo JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Faltan elementos en el vector JSON para conformar una tupla" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Falta el símbolo de cierre «)» en la tupla de GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Elementos adicionales no esperados en el vector JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Valor de cadena no válido al convertir a GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Una entrada del diccionario de GVariant espera un objeto JSON con sólo un " +"miembro" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "Clase «%c» de GVariant no soportada" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Firma de GVariant no válida" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Datos de JSON vacíos" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Error al analizr: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Los datos JSON deben estar codificados en UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Sólo se permite un nodo raíz en una expresión JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Nodo raíz seguido de un carácter «%c» no válido" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Falta el nombre del miembro o el comodín después del «.»." + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Expresión de particionado «%*s» mal formada" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Definición de conjunto no válida «%*s»" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Definición de particionado no válida «%*s»" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Definición de índice de vector no válida «%*s»" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Primer carácter «%c» no válido" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"El nodo actual es de tipo «%s», pero se esperaba un objeto o un vector." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"El índice «%d» es mayor que el tamaño del vector en la posición actual." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"El índice «%d» es mayor que el tamaño del objeto en la posición actual." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "No hay ningún nodo disponible en la posición actual" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "La posición actual tiene un «%s» y no un vector" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "El nodo actual es de tipo «%s», pero se esperaba un objeto." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "El miembro «%s» no está definido en el objeto en la posición actual." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "La posición actual tiene un «%s» y no un objeto" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "La posición actual tiene un «%s» y no un valor" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "La posición actual no tiene un tipo de cadena" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "La posición actual no tiene un tipo entero" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "La posición actual no tiene un tipo de coma flotante" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "La posición actual no tiene un tipo booleano" diff --git a/po/et.po b/po/et.po new file mode 100644 index 0000000..b7141c7 --- /dev/null +++ b/po/et.po @@ -0,0 +1,123 @@ +# Estonian translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Mattias Põldaru , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2012-10-28 12:31+0000\n" +"PO-Revision-Date: 2012-10-29 20:51+0300\n" +"Last-Translator: Mattias Põldaru \n" +"Language-Team: Estonian \n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Oodati JSON objekti, kuid juursõlme liik on '%s'" + +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON sõlmes esines ootamatu liik '%s'" + +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON massiivis puuduvad tuple'i moodustamiseks vajalikud elemendid" + +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Puuduv sulgev ')' sümbol GVariant tuple'is" + +msgid "Unexpected extra elements in JSON array" +msgstr "Ootamatud lisaelemendid JSON massiivis" + +msgid "Invalid string value converting to GVariant" +msgstr "Sobimatu sõne väärtus GVariandiks teisendamisel" + +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"GVariant dictionary kirje eeldab JSON objekti, milles on täpselt üks liige" + +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant klass '%c' pole toetatud" + +msgid "Invalid GVariant signature" +msgstr "Sobimatu GVariant-i allkiri" + +msgid "JSON data is empty" +msgstr "JSON ei sisalda andmeid" + +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: parsimise viga: %s" + +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Ainult juursõlm on lubatud JSONPath expression lauses" + +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Juursõlmele järgneb sobimatu märk '%c'" + +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Sobimatu tüki väljendus (slice expression) '%*s'" + +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Sobimatu kogu (set) definitsioon '%*s'" + +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Sobimatu tüki (slice) definitsioon '%*s'" + +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Sobimatu massiivi indeksi definitsioon '%*s'" + +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "Praeguse sõlme liik on '%s', aga oodati massiivi või objekti." + +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "Indeks '%d' on suurem kui massivi suurus praeguses asukohas." + +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "Indeks '%d' on suurem kui objekti suurus praeguses asukohas." + +msgid "No node available at the current position" +msgstr "Praeguses asukohas pole saadaval ühtegi sõlme" + +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "Praegune asukoht sisaldab '%s' ning see pole massiiv" + +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "Praeguse sõlme liik on '%s', aga oodati objekti." + +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "Liige '%s' ei ole defineeritud praeguses asukohas asuvas objektis." + +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "Praegune asukoht sisaldab '%s', mitte objekti" + +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "Praegune asukoht sisaldab '%s' ning mitte väärtust" + +msgid "The current position does not hold a string type" +msgstr "Praegune asukoht ei sisalda sõne liiki" diff --git a/po/eu.po b/po/eu.po new file mode 100644 index 0000000..5892bd9 --- /dev/null +++ b/po/eu.po @@ -0,0 +1,294 @@ +# Basque translation of jon-glib. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Iñaki Larrañaga Murgoitio , 2013, 2014, 2017. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-08-27 19:11+0200\n" +"Last-Translator: Iñaki Larrañaga Murgoitio \n" +"Language-Team: Basque \n" +"Language: eu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Lokalize 1.5\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Koskatu irteera" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Koskaren zuriuneak" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: errorea fitxategia irekitzean: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: errorea fitxategia analizatzean: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: errorea irteera estandarrean idaztean" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: errorea ixtean: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FITXATEGIA" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "JSON fitxategien formatua." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "“json-glib-format“-ek JSON baliabideei formatu ematen die." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Errorea komando-lerroaren aukerak analizatzean: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Saiatu “%s --help“ erabiltzen informazio gehiagorako." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: fitxategiak falta dira" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "JSON fitxategien balidazioa." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "" +"“json-glib-validate“-ek JSON datuen balidazioa egiten du emandako URIan." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "JSON objektu bat espero zen, baina erroaren nodoa “%s“ motakoa da" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Ustekabeko “%s“ mota JSON nodoan" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON matrizean elementuak falta dira tupla bat osatzeko" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Itxierako “)“ ikurra falta da GVariant tupla motan" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Ustekabeko elementu gehigarriak JSON nodoan" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Baliogabeko kate-balioa GVariant-era bihurtzean" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"GVariant hiztegiaren sarrera batek JSON objektu bat espero du kide bakar " +"batekin soilik" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "“%c“ GVariant klasea ez dago onartuta" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Baliogabeko GVariant sinadura" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSONen datuak hutsik daude" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: analisi-errorea: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON datuak UTF-8 kodeketan egon behar dute" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "" +"Soilik erroko nodo bakar bat dago baimenduta JSONPath adierazpen batean" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Erroko nodoaren ondoren baliogabeko “%c“ karakterea dago" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Kidearen izena edo “.“ karakterearen ondorengo izartxoa falta da" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Gaizki osatutako “%*s“ adierazpen zatia" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Baliogabeko “%*s“ multzoaren definizioa" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Baliogabeko “%*s“ definizio zatia" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Baliogabeko “%*s“ matrizearen indizearen definizioa" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Aurreneko “%c“ karakterea baliogabea" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Uneko nodoa “%s“ motakoa da, baina matrize edo objektu bat espero zen." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "“%d“ indizea uneko posizioko matrizearen tamaina baino handiagoa da." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "“%d“ indizea uneko posizioko objektuaren tamaina baino handiagoa da ." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Ez dago nodorik erabilgarri uneko posizioan" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "Uneko posizioak “%s“ dauka, eta ez matrize bat" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Uneko nodoa “%s“ motakoa da, baina objektu bat espero zen." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "“%s“ kidea ez dago uneko posizioko objektuan definituta." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "Uneko posizioak “%s“ dauka, baina ez objektu bat" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "Uneko posizioak “%s“ dauka, baina ez balio bat" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Uneko posizioak ez dauka kate motakorik" + diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..228d9d1 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,274 @@ +# French translation of jon-glib. +# Copyright (C) 2012-2017 json-glib COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Josselin TILLAY-DOLEDEC , 2012 +# Claude Paroz , 2014-2017 +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-05-19 16:51+0200\n" +"Last-Translator: Claude Paroz \n" +"Language-Team: GNOME French Team \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Formatage indenté" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Espaces d'indentation" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s : %s : erreur d'ouverture du fichier : %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s : %s : erreur d'analyse du fichier : %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s : %s : erreur d'écriture vers stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s : %s : erreur de fermeture : %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FICHIER" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Mise en forme de fichiers JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format met en forme des ressources JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Erreur d'analyse des options de la ligne de commande : %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Essayez « %s --help » pour plus d'informations." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s : fichiers manquants" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validation de fichiers JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate valide des données JSON à l'URI indiquée." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Objet de type JSON attendu mais le nœud racine est de type « %s »" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Type « %s » inattendu dans le nœud JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Éléments manquants dans le tableau JSON pour être conforme à un tuple" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Symbole fermant « ) » manquant dans le tuple GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Éléments supplémentaires inattendus dans le tableau JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Chaîne de caractères invalide pour la conversion en GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Une entrée de dictionnaire GVariant requiert un objet JSON contenant un seul " +"membre" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Classe GVariant « %c » non prise en charge" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Signature GVariant non valide" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Les données JSON sont vides" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Erreur d'analyse : %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Les données JSON doivent être codées en UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Un seul nœud racine autorisé dans une expression JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Nœud racine suivi d'un caractère invalide « %c »" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Nom de membre ou caractère joker manquant après un caractère « . »" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Expression de segmentation malformée « %*s »" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Définition d'ensemble invalide « %*s »" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Définition de segmentation invalide « %*s »" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Définition d'indice de tableau invalide « %*s »" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Premier caractère « %c » non valide" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"Le nœud courant est de type « %s » mais un tableau ou un objet était attendu." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"L'indice « %d » est plus grand que la taille du tableau à la position " +"actuelle." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"L'indice « %d » est plus grand que la taille de l'objet indiqué à la " +"position actuelle." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Aucun nœud disponible à cette position." + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "" +"La position actuelle contient un élément de type « %s » et non un tableau" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Le nœud actuel est de type « %s » mais un objet était attendu." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "" +"Le membre « %s » n'est pas défini dans l'objet à la position actuelle." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "" +"La position actuelle contient un élément de type « %s » et non un objet" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "" +"La position actuelle contient un élément de type « %s » et non une valeur" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "La position actuelle ne contient pas une chaîne de caractères" diff --git a/po/fur.po b/po/fur.po new file mode 100644 index 0000000..dd356fa --- /dev/null +++ b/po/fur.po @@ -0,0 +1,264 @@ +# Friulian translation for json-glib. +# Copyright (C) 2013 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Fabio Tomat , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-04-21 23:19+0200\n" +"Last-Translator: Fabio Tomat \n" +"Language-Team: Friulian \n" +"Language: fur\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.8.12\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Bilisie l'output" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Spazis di rientri" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: erôr tal vierzi il file: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: erôr tal analizâ il file: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: erôr tal scrivi sul stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: erôr tal sierâ: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FILE" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formate file JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format al formate lis risorsis JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Erôr tal analizâ lis opzions a rie di comant: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Prove “%s --help” par vê plui informazions." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: a mancjin dai file" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Convalide file JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate al convalide dâts JSON cjatâts al URI furnît." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Si spiete un ogjet JSON, ma il grop lidrîs al è dal gjenar “%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Gjenar “%s” no spietât tal grop JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "A mancjin ogjets tal array JSON par conformitât a une tuple" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Al mancje il simbul di sieradure “)” tal gjenar tuple GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Elements di plui no spietâts tal array JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Valôrs di stringhe no valits te conversion a JSON" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Une vôs di dizionari GVariant a domandave un ogjet JSON cun precîs un membri" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Classe GVariant “%c” no supuartade" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Firme GVariant no valide" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "I dâts JSON a son vueits" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: erôr di analisi: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "I dâts JSON a scugnin jessi codificâts in UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Si amet dome un grop lidrîs intune espression JSON" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Grop lidrîs seguît dal caratar no valit “%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Al mancje il non dal membri o un caratar speciâl dopo il caratar \".\"" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Espression slice “%*s” malformade" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Definizion di set “%*s” no valide" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Definizion di slice “%*s” no valide" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Definizion di indiç di array “%*s” no valide" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Prin caratar “%c” no valit" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Il gjenar di grop atuâl al è “%s”, ma si spietave un array o un ogjet." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "L'indiç “%d” al è plui grant de dimension dal array ae posizion atuâl." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "L'indiç “%d” al è plui grant de dimension dal ogjet ae posizion atuâl." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Nissun grop disponibil ae posizion atuâl." + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "La posizion atuâl e ten un “%s” e no un array" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Il grop atuâl al è di gjenar “%s”, ma si spietave un ogjet." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Il membri “%s” nol è definît intal ogjet ae posizion atuâl." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "La posizion atuâl e ten un “%s” e no un ogjet" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "La posizion atuâl e ten un “%s” e no un valôr" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "La posizion atuâl no ten un tipo stringhe" diff --git a/po/gl.po b/po/gl.po new file mode 100644 index 0000000..6eb0983 --- /dev/null +++ b/po/gl.po @@ -0,0 +1,299 @@ +# Galician translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Fran Dieguez , 2012, 2013, 2017. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-08-08 00:49+0200\n" +"Last-Translator: Fran Dieguez \n" +"Language-Team: Galician\n" +"Language: gl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Virtaal 0.7.1\n" +"X-Project-Style: gnome\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Mellorar saída" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Espazos de sangrado" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: erro ao abrir o ficheiro: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: error ao analizar o ficheiro: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: erro ao escribir na saída estándar" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: erro ao pechar: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FICHEIRO" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatea de ficheiros JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "Os recursos de JSON de json-glib-format." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Produciuse un erro ao analizar as opcións de liña de ordes: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Tente «%s --help» para máis información." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: ficheiros omitidos" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validar ficheiros JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate valida os datos JSON dunha URI fornecida." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Agardábase un obxecto JSON, pero o nodo raíz é de tipo «%s»" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Tipo «%s» non agardado nun nodo JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Faltan elementos no vector JSON para conformar unha tupla" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Falta o símbolo de peche «)» na tupla de GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Elementos adicionais non agardados no vector JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Valor de cadea non válido ao converter a GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Unha entrada do dicionario e GVariant agarda un obxecto JSON con só un membro" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "Clase «%c» de GVariant non admitida" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Firma de GVariant non válida" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Datos de JSON baleiros" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: erro de análise: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Os datos JSON deben ter a codificación UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Só se permite un nodo raíz nunha expresión JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Nodo raíz seguido dun carácter «%c» non válido" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Falta o nome do membro ou comodín logo do caracter «.»" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Expresión de particionado «%*s» mal formada" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Definición de conxunto non válida «%*s»" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Definición de particionado non válida «%*s»" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Definición de índice de vector non válida «%*s»" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Primeiro caracter «%c» non válido" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "O nodo actual é de tipo «%s», pero agardábase un obxecto ou un vector." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "O índice «%d» é maior que o tamaño do vector na posición actual." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "O índice «%d» é maior que o tamaño do obxecto na posición actual." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Non hai ningún nodo dipoñíbel na posición actual" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "A posición actual ten un «%s» e non un vector" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "O nodo actual é de tipo «%s», pero agardábase un obxecto." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "O membro «%s» non está definido no obxecto na posición actual." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "A posición actual ten un «%s» e non un obxecto" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "A posición actual ten un «%s» e non un valor" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "A posición actual non ten un tipo de cadea" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "A posición actual non ten un tipo enteiro" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "A posición actual non ten un tipo de coma flotante" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "A posición actual non ten un tipo booleano" diff --git a/po/he.po b/po/he.po new file mode 100644 index 0000000..fe885be --- /dev/null +++ b/po/he.po @@ -0,0 +1,263 @@ +# Hebrew translations for json-glib package. +# Copyright (C) 2014 THE json-glib'S COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# יוסף אור בוצ׳קו , 2014. +# Yosef Or Boczko , 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib 0.17.1\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib\n" +"POT-Creation-Date: 2014-01-26 05:31+0200\n" +"PO-Revision-Date: 2014-01-26 05:32+0200\n" +"Last-Translator: Yosef Or Boczko \n" +"Language-Team: עברית <>\n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Gtranslator 2.91.6\n" + +#: ../json-glib/json-glib-format.c:41 +msgid "Prettify output" +msgstr "Prettify output" + +#: ../json-glib/json-glib-format.c:42 +msgid "Indentation spaces" +msgstr "Indentation spaces" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:68 ../json-glib/json-glib-validate.c:61 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: error opening file: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:80 ../json-glib/json-glib-validate.c:73 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: error parsing file: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: ../json-glib/json-glib-format.c:99 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: error writing to stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:119 ../json-glib/json-glib-validate.c:85 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: error closing: %s\n" + +#: ../json-glib/json-glib-format.c:148 ../json-glib/json-glib-validate.c:113 +msgid "FILE" +msgstr "FILE" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-format.c:151 +msgid "Format JSON files." +msgstr "Format JSON files." + +#: ../json-glib/json-glib-format.c:152 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formats JSON resources." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:169 ../json-glib/json-glib-validate.c:134 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Error parsing commandline options: %s\n" + +#: ../json-glib/json-glib-format.c:171 ../json-glib/json-glib-format.c:185 +#: ../json-glib/json-glib-validate.c:136 ../json-glib/json-glib-validate.c:150 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Try \"%s --help\" for more information." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:183 ../json-glib/json-glib-validate.c:148 +#, c-format +msgid "%s: missing files" +msgstr "%s: missing files" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-validate.c:116 +msgid "Validate JSON files." +msgstr "Validate JSON files." + +#: ../json-glib/json-glib-validate.c:117 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate validates JSON data at the given URI." + +#: ../json-glib/json-gobject.c:917 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Expecting a JSON object, but the root node is of type `%s'" + +#: ../json-glib/json-gvariant.c:545 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Unexpected type '%s' in JSON node" + +#: ../json-glib/json-gvariant.c:615 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Missing elements in JSON array to conform to a tuple" + +#: ../json-glib/json-gvariant.c:643 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Missing closing symbol ')' in the GVariant tuple type" + +#: ../json-glib/json-gvariant.c:651 +msgid "Unexpected extra elements in JSON array" +msgstr "Unexpected extra elements in JSON array" + +#: ../json-glib/json-gvariant.c:930 +msgid "Invalid string value converting to GVariant" +msgstr "Invalid string value converting to GVariant" + +#: ../json-glib/json-gvariant.c:986 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"A GVariant dictionary entry expects a JSON object with exactly one member" + +#: ../json-glib/json-gvariant.c:1266 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant class '%c' not supported" + +#: ../json-glib/json-gvariant.c:1314 +msgid "Invalid GVariant signature" +msgstr "Invalid GVariant signature" + +#: ../json-glib/json-gvariant.c:1362 +msgid "JSON data is empty" +msgstr "JSON data is empty" + +#: ../json-glib/json-parser.c:817 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Parse error: %s" + +#: ../json-glib/json-parser.c:885 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON data must be UTF-8 encoded" + +#: ../json-glib/json-path.c:438 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Only one root node is allowed in a JSONPath expression" + +#: ../json-glib/json-path.c:447 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Root node followed by invalid character '%c'" + +#: ../json-glib/json-path.c:487 +msgid "Missing member name or wildcard after . character" +msgstr "Missing member name or wildcard after . character" + +#: ../json-glib/json-path.c:561 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Malformed slice expression '%*s'" + +#: ../json-glib/json-path.c:605 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Invalid set definition '%*s'" + +#: ../json-glib/json-path.c:658 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Invalid slice definition '%*s'" + +#: ../json-glib/json-path.c:686 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Invalid array index definition '%*s'" + +#: ../json-glib/json-path.c:705 +#, c-format +msgid "Invalid first character '%c'" +msgstr "Invalid first character '%c'" + +#: ../json-glib/json-reader.c:457 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "" +"The current node is of type '%s', but an array or an object was expected." + +#: ../json-glib/json-reader.c:469 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "" +"The index '%d' is greater than the size of the array at the current position." + +#: ../json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "" +"The index '%d' is greater than the size of the object at the current " +"position." + +#: ../json-glib/json-reader.c:570 ../json-glib/json-reader.c:723 +#: ../json-glib/json-reader.c:774 ../json-glib/json-reader.c:812 +#: ../json-glib/json-reader.c:850 ../json-glib/json-reader.c:888 +#: ../json-glib/json-reader.c:926 ../json-glib/json-reader.c:971 +#: ../json-glib/json-reader.c:1007 ../json-glib/json-reader.c:1033 +msgid "No node available at the current position" +msgstr "No node available at the current position" + +#: ../json-glib/json-reader.c:577 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "The current position holds a '%s' and not an array" + +#: ../json-glib/json-reader.c:640 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "The current node is of type '%s', but an object was expected." + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "The member '%s' is not defined in the object at the current position." + +#: ../json-glib/json-reader.c:730 ../json-glib/json-reader.c:781 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "The current position holds a '%s' and not an object" + +#: ../json-glib/json-reader.c:821 ../json-glib/json-reader.c:859 +#: ../json-glib/json-reader.c:897 ../json-glib/json-reader.c:935 +#: ../json-glib/json-reader.c:980 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "The current position holds a '%s' and not a value" + +#: ../json-glib/json-reader.c:943 +msgid "The current position does not hold a string type" +msgstr "The current position does not hold a string type" diff --git a/po/hi.po b/po/hi.po new file mode 100644 index 0000000..40c5114 --- /dev/null +++ b/po/hi.po @@ -0,0 +1,160 @@ +# Hindi translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# chandankumar , 2012. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2012-09-18 16:29+0000\n" +"PO-Revision-Date: 2012-09-20 10:33+0530\n" +"Last-Translator: chandankumar \n" +"Language-Team: Hindi \n" +"Language: hi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#: ../json-glib/json-gobject.c:934 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "एक JSON वस्तु की उम्मीद है, लेकिन रूट नोड प्रकार `%s' हैं " + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "अनपेक्षित प्रकार '%s' JSON नोड में" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "एक टपल अनुरूप करने के लिए JSON सरणी में गुम तत्वों " + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr " GVariant टपल प्रकार में समापन प्रतीक ')' गुम" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON सरणी में अप्रत्याशित अतिरिक्त तत्वों" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant को करने के लिए परिवर्तित अवैध स्ट्रिंग मान " + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"GVariant शब्दकोश प्रविष्टि को वास्तव में एक सदस्य के साथ एक JSON वस्तु की " +"उम्मीद है" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant वर्ग '%c' समर्थित नहीं है" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "अवैध GVariant हस्ताक्षर" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "JSON डेटा खाली है" + +#: ../json-glib/json-parser.c:818 +#, c-format +msgid "%s:%d: Parse error: %s" +msgstr "%s:%d: व्याख्या त्रुटि: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "एक JSONPath अभिव्यक्ति में केवल एक रूट नोड की अनुमति दी है" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "अवैध अक्षर '%c' के बाद रूट नोड " + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "विकृत स्लाइस अभिव्यक्ति '%*s'" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "अमान्य सेट परिभाषा '%*s'" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "अवैध स्लाइस परिभाषा '%*s'" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "अवैध सरणी सूचकांक परिभाषा '%*s'" + +#: ../json-glib/json-reader.c:463 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "" +"वर्तमान नोड प्रकार '%s' में से एक है, लेकिन एक सरणी या एक वस्तु की उम्मीद थी." + +#: ../json-glib/json-reader.c:475 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "सूचकांक '%d' वर्तमान स्थिति में सरणी के आकार की तुलना में अधिक है." + +#: ../json-glib/json-reader.c:492 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "सूचकांक '%d' वर्तमान स्थिति में वस्तु के आकार की तुलना में अधिक है." + +#: ../json-glib/json-reader.c:576 ../json-glib/json-reader.c:729 +#: ../json-glib/json-reader.c:780 ../json-glib/json-reader.c:818 +#: ../json-glib/json-reader.c:856 ../json-glib/json-reader.c:894 +#: ../json-glib/json-reader.c:932 ../json-glib/json-reader.c:977 +#: ../json-glib/json-reader.c:1013 ../json-glib/json-reader.c:1039 +msgid "No node available at the current position" +msgstr "वर्तमान स्थिति में कोई नोड उपलब्ध नहीं " + +#: ../json-glib/json-reader.c:583 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "मौजूदा स्थिति के पास '%s' हैं और सरणी नहीं है." + +#: ../json-glib/json-reader.c:646 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "वर्तमान नोड प्रकार '%s' में से एक है, लेकिन एक वस्तु की उम्मीद थी." + +#: ../json-glib/json-reader.c:653 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "सदस्य '%s' वर्तमान स्थिति में वस्तु में परिभाषित नहीं है." + +#: ../json-glib/json-reader.c:736 ../json-glib/json-reader.c:787 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "वर्तमान स्थिति के लिए '%s' और कोई ऑब्जेक्ट आयोजित नहीं है" + +#: ../json-glib/json-reader.c:827 ../json-glib/json-reader.c:865 +#: ../json-glib/json-reader.c:903 ../json-glib/json-reader.c:941 +#: ../json-glib/json-reader.c:986 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "वर्तमान स्थिति के लिए '%s' और कोई मान आयोजित नहीं है" + +#: ../json-glib/json-reader.c:949 +msgid "The current position does not hold a string type" +msgstr "वर्तमान स्थिति के लिए स्ट्रिंग प्रकार नहीं है" + diff --git a/po/hr.po b/po/hr.po new file mode 100644 index 0000000..7f3b584 --- /dev/null +++ b/po/hr.po @@ -0,0 +1,264 @@ +# Croatian translation for json-glib. +# Copyright (C) 2018 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib json-glib-1-4\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/json-glib/issues\n" +"POT-Creation-Date: 2018-03-13 14:47+0000\n" +"PO-Revision-Date: 2018-03-16 21:48+0100\n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"Last-Translator: \n" +"X-Generator: Poedit 2.0.6\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Uljepšani izlaz" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Poravnanje razmaka" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: greška otvaranja datoteke: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: greška obrade datoteke: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: greška zapisivanja u stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: greška zatvaranja: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "DATOTEKA" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Format JSON datoteka." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formati JSON resursa." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Greška obrade mogućnosti naredbenog redka: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Pokušajte “%s --help” za više informacija." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: nedostaju datoteke" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Provjera JSON datoteka." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate provjerava JSON podatke na danom URI-ju." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Očekivani je JSON objekt li korijenski čvor je “%s” vrste" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Neočekivana vrsta “%s” u JSON čvoru" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Nedostaju elementu u JSON polju za porvrdu tuple" + +#: json-glib/json-gvariant.c:622 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Nedostaje simbol zatvaranja “)” u vrsti GVariant tuple" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "Neočekivani dodatni elementi u JSON polju" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "Neispravna vrijednost izraza pretvorbe u GVariantu" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant unos rječnika očekuje JSON objekt s točno jednim članom" + +#: json-glib/json-gvariant.c:1242 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "GVariant klasa “%c” nije podržana" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "Neispravan potpis GVariante" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "JSON podatak je prazan" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:909 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Greška obrade: %s" + +#: json-glib/json-parser.c:992 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON podatak mora biti UTF-8 kôdiran" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Samo jedan korijenski čvor je dopušten u JSONPath izrazu" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Korijenski čvor je slijeđen neispravnim znakom “%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Nedostaje naziv člana ili zamjenski znak nakon . character" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Krivo oblikovan dio izraza “%*s”" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Neispravna postavka definicije “%*s”" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Neispravan dio definicije “%*s”" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Neispravno polje sadržaja definicije “%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Neispravan prvi znak “%c”" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Trenutni čvor je “%s” vrste, ali polje ili objekt je očekivan." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Sadržaj “%d” je veći od veličine polja na trenutnom položaju." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Sadržaj “%d” je veći od veličine objekta na trenutnom položaju." + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "Nema dostupnih čvorova na trenutnom položaju" + +#: json-glib/json-reader.c:592 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Trenutni položaj zauzima “%s” a ne polje" + +#: json-glib/json-reader.c:668 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Trenutni čvor je “%s” vrste, ali objekt je očekivan." + +#: json-glib/json-reader.c:675 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Član “%s” nije definiran u objektu na trenutnom položaju." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Trenutni položaj zauzima “%s” a ne objekt" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Trenutni položaj zauzima “%s” a ne vrijednost" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "Trenutni položaj ne zauzima vrsta izraza" diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 0000000..1d8d0a9 --- /dev/null +++ b/po/hu.po @@ -0,0 +1,294 @@ +# Hungarian translation for json-glib. +# Copyright (C) 2012, 2014, 2017 Free Software Foundation, Inc. +# This file is distributed under the same license as the json-glib package. +# +# Gabor Kelemen , 2012, 2014. +# Balázs Úr , 2012, 2017. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-03-19 01:21+0100\n" +"Last-Translator: Balázs Úr \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Lokalize 1.2\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Kimenet csinosítása" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Behúzási szóközök" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: hiba a fájl megnyitásakor: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: hiba a fájl feldolgozásakor: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: hiba a szabványos kimenetre íráskor" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: hiba a következő lezárásakor: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FÁJL" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "JSON fájlok formázása." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "A json-glib-format JSON erőforrásokat formáz." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Hiba a parancssori kapcsolók feldolgozásakor: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "További információkért adja ki a következő parancsot: „%s --help”." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: hiányzó fájlok" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "JSON fájlok ellenőrzése." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "" +"A json-glib-validate a megadott URI-n található JSON adatokat ellenőrzi." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "A várt JSON objektum helyett a gyökérobjektum „%s” típusú" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Váratlan „%s” típus a JSON csomópontban" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "A JSON tömbből hiányzó elemek miatt a tuple nem teljes" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Hiányzó „)” szimbólum a GVariant tuple típusban" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Váratlan extra elemek a JSON tömbben" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Érvénytelen karakterláncérték a GVariant-tá alakítás közben" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "Egy GVariant szótárbejegyzés pontosan egy tagú JSON objektumot vár" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "A(z) „%c” GVariant osztály nem támogatott" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Érvénytelen GVariant aláírás" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "A JSON adatok üresek" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: feldolgozási hiba: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "A JSON adatoknak UTF-8 kódolásúnak kell lenniük" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Csak egy gyökércsomópont engedélyezett a JSONPath kifejezésben" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "A gyökércsomópontot érvénytelen karakter követi: „%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Hiányzó tagnév vagy helyettesítő karakter a . után" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Hibás szeletkifejezés: „%*s”" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Érvénytelen halmazdefiníció: „%*s”" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Érvénytelen szeletdefiníció: „%*s”" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Érvénytelen tömbindex-definíció: „%*s”" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Érvénytelen első karakter: „%c”" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "A jelenlegi csomópont „%s” típusú a várt tömb vagy objektum helyett." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "A(z) „%d” index nagyobb az aktuális pozícióban lévő tömb méreténél." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"A(z) „%d” index nagyobb az aktuális pozícióban lévő objektum méreténél." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Nem érhető el csomópont az aktuális pozícióban" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "Az aktuális pozícióban „%s” található tömb helyett" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "A jelenlegi csomópont „%s” típusú a várt objektum helyett." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "" +"A(z) „%s” tag nincs definiálva az aktuális pozícióban lévő objektumban." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "Az aktuális pozícióban „%s” található objektum helyett" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "Az aktuális pozícióban „%s” található érték helyett" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Az aktuális pozícióban nem karakterlánc típus található" + diff --git a/po/id.po b/po/id.po new file mode 100644 index 0000000..82b0f63 --- /dev/null +++ b/po/id.po @@ -0,0 +1,266 @@ +# Indonesian translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Andika Triwidada , 2012, 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-05-02 13:13+0700\n" +"Last-Translator: Kukuh Syafaat \n" +"Language-Team: Indonesian \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-SourceCharset: UTF-8\n" +"X-Generator: Poedit 1.8.11\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Percantik keluaran" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Spasi indentasi" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: galat saat membuka berkas: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: galat saat mengurai berkas: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: galat saat menulis ke stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: galat saat menutup: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "BERKAS" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Memformat berkas JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format memformat sumber daya JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Galat saat mengurai opsi baris perintah: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Coba \"%s --help\" untuk informasi lebih lanjut." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: kurang berkas" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validasikan berkas JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate memvalidasi data JSON pada URI yang diberikan." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Mengharapkan objek JSON, tapi node akar bertipe \"%s\"" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Tipe \"%s\" yang tak diharapkan dalam node JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Kehilangan elemen dalam larik JSON untuk memenuhi syarat sebagai tuple" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Kehilangan simbol penutup \")\" dalam tipe tuple GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Elemen ekstra yang tak diharapkan dalam larik JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Nilai string tak valid saat mengonversi ke GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Suatu entri kamus GVariant mengharapkan objek JSON dengan tepat satu anggota" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Kelas \"%c\" GVariant tak didukung" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Tanda tangan GVariant tak valid" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Data JSON kosong" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Galat mengurai: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Data JSON mesti ter-enkode UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Hanya satu node akar yang diijinkan dalam ekspresi JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Node akar diikuti oleh karakter tak valid \"%c\"" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Kurang nama anggota atau wildcard setelah karakter . (titik)" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Ekspresi slice \"%*s\" salah bentuk" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Definisi set \"%*s\" tak valid" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Definisi slice \"%*s\" tak valid" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Definisi indeks larik \"%*s\" tak valid" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Karakter pertama \"%c\" tak valid" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Node kini bertipe \"%s\", tapi larik atau objek yang diharapkan." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Indeks \"%d\" lebih besar daripada ukuran larik pada posisi kini." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Indeks \"%d\" lebih besar daripada ukuran objek pada posisi kini." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Node tak tersedia pada posisi kini" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Posisi kini menampung \"%s\" dan bukan suatu larik" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Node kini bertipe \"%s\", tapi yang diharapkan adalah objek." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Anggota \"%s\" tak didefinisikan dalam objek pada posisi kini." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Posisi kini menampung \"%s\" dan bukan suatu objek" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Posisi kini menampung \"%s\" dan bukan suatu nilai" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Posisi kini tak menampung suatu tipe string" diff --git a/po/it.po b/po/it.po new file mode 100644 index 0000000..4381237 --- /dev/null +++ b/po/it.po @@ -0,0 +1,270 @@ +# Italian translation for json-glib. +# Copyright (C) 2012, 2013 json-glib's copyright holder +# This file is distributed under the same license as the json-glib package. +# Luca Ferretti , 2012. +# Milo Casagrande , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-08-25 09:29+0200\n" +"Last-Translator: Milo Casagrande \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Poedit 1.8.12\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Output abbellito" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Spazi di rientro" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: errore nell'aprire il file: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: errore nell'analizzare il file: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: errore nello scrivere su stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: errore nel chiudere: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FILE" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatta i file JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatta le risorse JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Errore nell'analizzare le opzioni a riga di comando: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Per maggiori informazioni, usare «%s --help»." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: mancano dei file" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Convalida i file JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate convalida i dati JSON trovati all'URI fornito." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Atteso un oggetto JSON, ma il nodo radice è del tipo «%s»" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Tipo «%s» inatteso nel nodo JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Elementi mancanti nell'array JSON per conformità a una tupla" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Simbolo «)» di chiusura mancante nel tipo tupla GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Elementi aggiuntivi inattesi nell'array JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Valore di stringa non valido nella conversione a JSON" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Una voce di dizionario GVariant richiese un oggetto JSON con esattamente un " +"membro" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Classe GVariant «%c» non supportata" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Firma GVariant non valida" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "I dati JSON sono vuoti" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: errore di analisi: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "I dati JSON devono essere codificati in UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "È consentito un solo nodo radice in una espressione JSON" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Nodo radice seguito dal carattere non valido «%c»" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Manca il nome del membro o un carattere speciale dopo il carattere «.»" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Espressione slice «%*s» malformata" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Definizione di set «%*s» non valida" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Definizione di slice «%*s» non valida" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Definizione di indice array «%*s» non valida" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Primo carattere «%c» non valido" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Il tipo del nodo corrente è «%s», ma era atteso un array o un oggetto." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"L'indice «%d» è maggiore della dimensione dell'array alla posizione corrente." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"L'indice «%d» è maggiore della dimensione dell'oggetto alla posizione " +"corrente." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Nessun nodo disponibile alla posizione corrente" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "La posizione corrente contiene un «%s» e non un array" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Il tipo del nodo corrente è «%s», ma era atteso un oggetto." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Non è definito il membro «%s» nell'oggetto alla posizione corrente." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "La posizione corrente contiene un «%s» e non un oggetto" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "La posizione corrente contiene un «%s» e non un valore" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "La posizione corrente non contiene un tipo stringa" diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000..51cc38d --- /dev/null +++ b/po/ja.po @@ -0,0 +1,158 @@ +# json-glib ja.po +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Takayuki KUSANO , 2012. +# Jiro Matsuzawa , 2012, 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-glib\n" +"POT-Creation-Date: 2013-09-18 22:27+0900\n" +"PO-Revision-Date: 2013-09-18 22:29+0900\n" +"Last-Translator: Jiro Matsuzawa \n" +"Language-Team: Japanese \n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../json-glib/json-gobject.c:917 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "JSON オブジェクトであるべきところ、ルートノードが `%s' 型です" + +#: ../json-glib/json-gvariant.c:540 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON ノードが `%s' 型になってしまってます" + +#: ../json-glib/json-gvariant.c:610 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON の配列にタプルを構成する要素が足りません" + +#: ../json-glib/json-gvariant.c:638 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "GVariant タプル型に閉じ記号 ')' がありません" + +#: ../json-glib/json-gvariant.c:646 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON 配列に余計な要素があります" + +#: ../json-glib/json-gvariant.c:925 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant に変換するのに無効な文字列です" + +#: ../json-glib/json-gvariant.c:981 +msgid "A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant の辞書エントリはメンバーを一つだけ含んだ JSON オブジェクトでなくてはなりません" + +#: ../json-glib/json-gvariant.c:1237 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant のクラス '%c' はサポートされていません" + +#: ../json-glib/json-gvariant.c:1285 +msgid "Invalid GVariant signature" +msgstr "無効な GVariant シグネチャです" + +#: ../json-glib/json-gvariant.c:1333 +msgid "JSON data is empty" +msgstr "JSON データが空です" + +#: ../json-glib/json-parser.c:817 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: パースエラー: %s" + +#: ../json-glib/json-path.c:436 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath 式ではルートノード一つだけが許可されています" + +#: ../json-glib/json-path.c:445 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "ルートノードの後に無効な文字 '%c' があります" + +#: ../json-glib/json-path.c:551 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "不正なスライス式 '%*s'" + +#: ../json-glib/json-path.c:595 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "無効な集合定義 '%*s'" + +#: ../json-glib/json-path.c:648 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "無効なスライス定義: '%*s'" + +#: ../json-glib/json-path.c:676 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "無効な配列インデックス定義 '%*s'" + +#: ../json-glib/json-reader.c:457 +#, c-format +msgid "The current node is of type '%s', but an array or an object was expected." +msgstr "現在のノードは '%s' 型ですが、配列あるいはオブジェクトである必要があります。" + +#: ../json-glib/json-reader.c:469 +#, c-format +msgid "The index '%d' is greater than the size of the array at the current position." +msgstr "インデックス '%d' は現在位置にある配列の長さよりも大きいです。" + +#: ../json-glib/json-reader.c:486 +#, c-format +msgid "The index '%d' is greater than the size of the object at the current position." +msgstr "インデックス '%d' は現在位置のオブジェクトの大きさよりも大きいです。" + +#: ../json-glib/json-reader.c:570 ../json-glib/json-reader.c:723 +#: ../json-glib/json-reader.c:774 ../json-glib/json-reader.c:812 +#: ../json-glib/json-reader.c:850 ../json-glib/json-reader.c:888 +#: ../json-glib/json-reader.c:926 ../json-glib/json-reader.c:971 +#: ../json-glib/json-reader.c:1007 ../json-glib/json-reader.c:1033 +msgid "No node available at the current position" +msgstr "現在位置にノードがありません" + +#: ../json-glib/json-reader.c:577 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "現在位置は '%s' で、配列ではありません" + +#: ../json-glib/json-reader.c:640 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "現在のノードは '%s' 型ですが、オブジェクトである必要があります。" + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "現在位置のオブジェクトで '%s' メンバーは定義されていません" + +#: ../json-glib/json-reader.c:730 ../json-glib/json-reader.c:781 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "現在位置は '%s' で、オブジェクトではありません" + +#: ../json-glib/json-reader.c:821 ../json-glib/json-reader.c:859 +#: ../json-glib/json-reader.c:897 ../json-glib/json-reader.c:935 +#: ../json-glib/json-reader.c:980 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "現在位置は '%s' で値ではありません" + +#: ../json-glib/json-reader.c:943 +msgid "The current position does not hold a string type" +msgstr "現在位置が文字列型ではありません" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "現在位置が整数型ではありません" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "現在位置が浮動小数点型ではありません" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "現在位置が論理値型ではありません" diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000..ffda138 --- /dev/null +++ b/po/ko.po @@ -0,0 +1,265 @@ +# Korean translation for json-glib. +# Copyright (C) 2012 Seong-ho Cho et al. +# This file is distributed under the same license as the json-glib package. +# Seong-ho Cho , 2012-2014, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-09-02 11:50+0900\n" +"Last-Translator: Seong-ho Cho \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 1.8.7\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "출력 정돈" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "들여쓰기 공백" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: 파일 여는 중 오류: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: 파일 해석 중 오류: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: 표준 출력 쓰는 중 오류" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: 닫는 중 오류: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "<파일>" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "JSON 파일의 코드를 정렬합니다." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format이 JSON 자료 코드를 정렬합니다." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "명령줄 옵션 해석 중 오류: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "더 많은 내용은 “%s --help”를 실행하십시오." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: 파일이 빠졌습니다" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "JSON 파일을 검증합니다." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate는 주어진 URI의 JSON 데이터를 검증합니다." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "JSON 객체를 예상했지만 최상위 노드는 “%s” 형식입니다" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "JSON 노드에 예상치 못한 “%s” 형식이 있습니다" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "튜플에 따르기 위한 JSON 배열의 요소가 빠졌습니다" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "GVariant 튜플 형식에서 ')' 닫기 심볼이 빠졌습니다" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON 배열에 예상치 못한 추가 요소가 있습니다" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant로 변환하려는 문자열 값이 잘못되었습니다" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"GVariant 딕셔너리 항목은 정확히 하나의 요소를 가진 JSON 객체를 요구합니다" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "GVariant “%c” 클래스를 지원하지 않습니다" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "잘못된 GVariant 서명입니다" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON 데이터가 비었습니다" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: 해석 오류: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON 데이터는 UTF-8로 인코딩해야 합니다" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath 표현식에서는 단 하나만의 최상위 노드를 허용합니다" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "최상위 노드에 잘못된 “%c” 문자가 따라옵니다" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "멤버 이름 또는 구두점 문자 다음 와일드카드가 빠졌습니다" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "잘못된 분배 표현식 “%*s”" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "잘못된 세트 정의 “%*s”" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "잘못된 분배 정의 “%*s”" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "잘못된 배열 인덱스 정의 “%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "잘못된 첫번째 문자 “%c”" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "현재 노드는 “%s” 형식 이지만, 배열 또는 객체를 요구합니다." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "현재 위치 인덱스 “%d”번은 배열의 크기보다 큽니다." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "현재 위치 인덱스“%d”번은 객체의 크기보다 큽니다." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "현재 위치에 노드가 없습니다" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "현재 위치에 배열이 아닌 “%s”이(가) 있습니다" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "현재 노드는 “%s” 형식이지만 객체를 요구합니다." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "현재 위치 객체에 “%s” 구성원을 정의하지 않았습니다." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "현재 위치에 객체가 아닌 “%s”이(가) 있습니다" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "현재 위치에 값이 아닌 “%s”이(가) 있습니다" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "현재 위치에 문자열 값이 없습니다" diff --git a/po/ky.po b/po/ky.po new file mode 100644 index 0000000..02cb3a0 --- /dev/null +++ b/po/ky.po @@ -0,0 +1,161 @@ +# Kirghiz translation for json-glib. +# Kyrgyz translation of json-glib +# Copyright (C) 2012 json-glib authors +# This file is distributed under the same license as the json-glib package. +# +# Timur Zhamakeev , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2012-09-24 08:27+0000\n" +"PO-Revision-Date: 2013-01-05 18:22+0600\n" +"Last-Translator: Timur Zhamakeev \n" +"Language-Team: Kirghiz \n" +"Language: ky\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Lokalize 1.4\n" + +#: ../json-glib/json-gobject.c:934 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "JSON объекти күтүлүүдө, бирок башкы түйүн `%s' тибинде" + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON түйүнүндө күтүлбөгөн тип: '%s' " + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON массивинде кортежге ылайык келүүчү элементтер жок" + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "GVariant кортеж тибинде жабылуучу ')' тамгасы жок" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON массивинде күтүлбөгөн кошумча элементтер" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant тибине которуу үчүн берилген саптын мааниси туура эмес" + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant сөздүк элементи, бир гана мүчөлүү JSON объекти болушу керек" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "'%c' GVariant классы колдоого ээ эмес" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "GVariant сигнатурасы туура эмес" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "JSON маалыматы жок" + +#: ../json-glib/json-parser.c:818 +#, c-format +msgid "%s:%d: Parse error: %s" +msgstr "%s:%d: Ажыратып окуу катасы: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath туюнтмасында бир гана башкы түйүн болушу мүмкүн" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Башкы түйүн туура эмес тамга менен аяктаган: '%c'" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Туура эмес кесүү (slice) туюнтмасы '%*s'" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Туура эмес ыйгаруу (set) аныктамасы '%*s'" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Туура эмес кесүү (slice) аныктамасы '%*s'" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Массив индексинин туура эмес аныктамасы '%*s'" + +#: ../json-glib/json-reader.c:463 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "Учурдагы түйүн '%s' тибинде; массив же объект күтүлгөн." + +#: ../json-glib/json-reader.c:475 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "Учурдагы позициянын индекси:'%d' массивдин узундугунан чоң." + +#: ../json-glib/json-reader.c:492 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "" +"Учурдагы позициянын индекси:'%d'; объектин узундугунан " +"чоң." + +#: ../json-glib/json-reader.c:576 ../json-glib/json-reader.c:729 +#: ../json-glib/json-reader.c:780 ../json-glib/json-reader.c:818 +#: ../json-glib/json-reader.c:856 ../json-glib/json-reader.c:894 +#: ../json-glib/json-reader.c:932 ../json-glib/json-reader.c:977 +#: ../json-glib/json-reader.c:1013 ../json-glib/json-reader.c:1039 +msgid "No node available at the current position" +msgstr "Учурдагы позицияда түйүн жок" + +#: ../json-glib/json-reader.c:583 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "Учурдагы позицияда:'%s'; ал массив эмес" + +#: ../json-glib/json-reader.c:646 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "Учурдагы түйүн '%s' тибинде; объект күтүлгөн." + +#: ../json-glib/json-reader.c:653 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "Учурку позициядагы объекте '%s' аттуу мүчө аныкталган эмес." + +#: ../json-glib/json-reader.c:736 ../json-glib/json-reader.c:787 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "Учурдагы позицияда:'%s'; ал объект эмес" + +#: ../json-glib/json-reader.c:827 ../json-glib/json-reader.c:865 +#: ../json-glib/json-reader.c:903 ../json-glib/json-reader.c:941 +#: ../json-glib/json-reader.c:986 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "Учурдагы позицияда:'%s'; ал маани эмес" + +#: ../json-glib/json-reader.c:949 +msgid "The current position does not hold a string type" +msgstr "Учурдагы позициянын тиби, саптык тип эмес" + + diff --git a/po/lt.po b/po/lt.po new file mode 100644 index 0000000..8ff152a --- /dev/null +++ b/po/lt.po @@ -0,0 +1,290 @@ +# Lithuanian translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Aurimas Černius , 2012, 2013, 2014, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-04-24 23:07+0300\n" +"Last-Translator: Aurimas Černius \n" +"Language-Team: Lietuvių \n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" +"%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Gtranslator 2.91.7\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Graži išvestis" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Įtrauka tarpais" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: klaida atveriant failą: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: klaida skaitant failą: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: klaida rašant į standartinę išvestį" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: klaida užveriant: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FAILAS" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatuoti JSON failus." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatuoja JSON resursus." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Klaida skaitant komandų eilutės parametrus: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Daugiau informacijos gausite įvykdę „%s --help“." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: trūksta failų" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Tikrinti JSON failus." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate patikrina JSON duomenis ties pateiktu URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Tikimasi JSON objekto, bet šakninė viršūnė yra „%s“ tipo" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Netikėtas tipas „%s“ JSON viršūnėje" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Trūksta elementų JSON masyve junginiui sudaryti" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Trūksta uždarančio simbolio „)“ GVariant junginio tipe" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Netikėti papildomi elementai JSON masyve" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Netinkama eilutės reikšmė konvertavimui į GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant žodyno įrašas tikisi JSON objekto su vieninteliu nariu" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "GVariant klasė „%c“ nepalaikoma" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Netinkamas GVariant aprašas" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON duomenys yra tušti" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: skaitymo klaida: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON duomenys turi būti koduoti UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath išraiškoje leidžiamas vienintelė šakninė viršūnė" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Po šakninės viršūnės yra netinkamas simbolis „%c“" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Trūksta nario pavadinimo arba pakaitos simbolio po . simbolio" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Blogai suformuota dalinimo išraiška „%*s“" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Netinkamas aibės apibrėžimas „%*s“" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Netinkamas dalinimo apibrėžimas „%*s“" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Netinkamas masyvo apibrėžimas „%*s“" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Netinkamas pirmasis simbolis „%c“" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Dabartinė viršūnė yra „%s“ tipo, bet tikėtasi masyvo arba objekto." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Indeksas „%d“ yra didesnis nei masyvo dydis dabartinėje pozicijoje." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Indeksas „%d“ yra didesnis nei objekto dydis dabartinėje pozicijoje." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Nėra viršūnės dabartinėje pozicijoje" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "Dabartinėje pozicijoje yra „%s“, o ne masyvas" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Dabartinė viršūnė yra „%s“ tipo, bet tikėtasi objekto." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Narys „%s“ neapibrėžtas dabartinėje pozicijoje esančiame objekte." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "Dabartinė pozicija turi „%s“, o ne objektą" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "Dabartinė pozicija turi „%s“, o ne reikšmę" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Dabartinė pozicija turi „%s“, o ne eilutės tipą" diff --git a/po/lv.po b/po/lv.po new file mode 100644 index 0000000..f8004f6 --- /dev/null +++ b/po/lv.po @@ -0,0 +1,292 @@ +# Latvian translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# Rūdolfs Mazurs , 2012, 2013, 2014, 2017. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-gl" +"ib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-08-28 12:17+0200\n" +"Last-Translator: Rūdolfs Mazurs \n" +"Language-Team: Latvian \n" +"Language: lv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 :" +" 2);\n" +"X-Generator: Lokalize 2.0\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Izskaistināt izvadi" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Atkāpes atstarpes" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: kļūda, atverot datni: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: kļūda, parsējot datni: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s, kļūda, rakstot uz stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: kļūda aizverot: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "DATNE" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatēt JSON datnes." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatē JSON resursus." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Kļūda, parsējot komandrindas opcijas — %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Lietojiet “%s --help”, lai uzzinātu vairāk." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: iztrūkstošas datnes" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Pārbaudīt JSON datnes." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate pārbauda JSON datus dotajā URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Gaidīja JSON objektu, bet saknes mezglam ir tips “%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Negaidīts tips “%s” JSON mezglā" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON masīvā trūkst elementu, lai tas atbilstu kortežam" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "GVariant korteža tipā trūkst aizverošā simbola “)”" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON masīvā ir negaidīti papildu elementi" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Pārveidojot uz GVariant, nederīga virknes vērtība" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"GVariant vārdnīcas ieraksts gaidīja JSON objektu ar tieši vienu locekli" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "GVariant klase “%c” nav atbalstīta" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Nederīgs GVariant paraksts" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON dati ir tukši" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: parsēšanas kļūda — %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON datiem ir jābūt UTF-8 kodējumā" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath izteiksmē ir atļauta tikai viens saknes mezgls" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Pēc saknes mezgla seko nederīga rakstzīme “%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Trūkst locekļa nosaukums vai aizstājējzīme pēc . rakstzīmes" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Slikti formēta gabala izteiksme “%*s”" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Nederīga kopas definīcija “%*s”" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Nederīga gabala definīcija “%*s”" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Nederīga masīva indeksa definīcija “%*s”" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Nederīga pirmā rakstzīme “%c”" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Pašreizējam mezglam ir tips “%s”, bet tika gaidīts masīvs vai objekts." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Indekss “%d” dotajā pozīcijā ir lielāks kā masīva izmērs." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Indekss “%d” dotajā pozīcijā ir lielāks kā objekta izmērs." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Šajā pozīcija nav pieejams neviens mezgls" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "Šajā pozīcijā ir “%s”, nevis masīvs" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Pašreizējam mezglam ir tips “%s”, bet tika gaidīts objekts." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Šajā pozīcijā objektā loceklis “%s” nav definēts." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "Šajā pozīcijā ir “%s”, nevis objekts" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "Šajā pozīcijā ir “%s”, nevis vērtība" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Šajā pozīcijā nav virknes tipa" + diff --git a/po/meson.build b/po/meson.build new file mode 100644 index 0000000..f674ffa --- /dev/null +++ b/po/meson.build @@ -0,0 +1,3 @@ +i18n = import('i18n') + +i18n.gettext(json_gettext_domain, preset: 'glib') diff --git a/po/ml.po b/po/ml.po new file mode 100644 index 0000000..3a5bb47 --- /dev/null +++ b/po/ml.po @@ -0,0 +1,155 @@ +# Malayalam translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Anish A , 2012. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-02-11 20:00+0000\n" +"PO-Revision-Date: 2013-02-14 21:57+0530\n" +"Last-Translator: Jishnu Mohan \n" +"Language-Team: Swatantra Malayalam Computing\n" +"Language: ml\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../json-glib/json-gobject.c:925 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "`%s' അണ് റൂട്ട് നോഡിന്റെ തരം, പക്ഷേ JSON ഒബ്ജക്ട് ആണ് പ്രതീക്ഷിച്ചത്" + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON node ല്‍ '%s'എന്ന പ്രതീക്ഷിക്കാത്ത തരം" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON അറേയില്‍ ടപ്പിള്‍ ആകാനായുള്ള കാര്യങ്ങള്‍ കാണുന്നില്ല" + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "GVariant ടപ്പിള്‍ തരത്തില്‍ തീരുന്ന ചിഹ്നം ')' കാണുന്നില്ല" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON അറേയില്‍ വിചാരിക്കാത്ത അധികം കാര്യങ്ങള്‍" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant ലേക്ക് മാറ്റുന്ന അസാധുവായ വാചകം" + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "ഒരേ ഒരു അംഗമുള്ള JSON ഒബ്ജക്റ്റിനെ GVariant നിഘണ്ടു എന്ട്രി പ്രതീക്ഷിക്കുന്നു" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "'%c' എന്ന GVariant തരം പിന്‍തുണയ്ക്കുന്നില്ല" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "അസാധുവായ GVariant ഒപ്പ്" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "JSON ഡാറ്റ ശൂന്യം" + +#: ../json-glib/json-parser.c:825 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: പാഴ്സ് പിഴവ്: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath എക്സ്പ്രഷനില്‍ ഒരു റൂട്ടേ അനുവദിനീയമായിട്ടുള്ളു" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "റൂട്ട് നോഡിന് ശേഷം തെറ്റായ അക്ഷരം '%c'" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "തെറ്റായ സ്ലൈസ് എക്സ്പ്രഷന്‍ '%*s'" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "'%*s' എന്നത് തെറ്റായ കൂട്ടം നിര്‍വചനമാണ്" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "'%*s' എന്നത് തെറ്റായ സ്ലൈസ് നിര്‍വചനമാണ്" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "'%*s' എന്നത് തെറ്റായ അറേ ഇന്റെക്സ് നിര്‍വചനമാണ്" + +#: ../json-glib/json-reader.c:464 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "ഇപ്പോഴത്തെ നോഡിന്റെ തരം '%s' ആണ്, പക്ഷേ ഒരു അറേയോ ഒബ്ജക്റ്റോ ആണ് പ്രതീക്ഷിച്ചത്." + +#: ../json-glib/json-reader.c:476 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "ഇപ്പോഴത്തെ സ്ഥാനത്തുള്ള അറേയുടെ വലിപ്പത്തെക്കാള്‍ വലുതാണ് ഇന്‍ഡെക്സ് '%d'" + +#: ../json-glib/json-reader.c:493 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "ഇപ്പോഴത്തെ സ്ഥാനത്തുള്ള ഒബ്ജക്റ്റിന്റെ വലിപ്പത്തെക്കാള്‍ വലുതാണ് ഇന്‍ഡെക്സ് '%d'" + +#: ../json-glib/json-reader.c:577 ../json-glib/json-reader.c:730 +#: ../json-glib/json-reader.c:781 ../json-glib/json-reader.c:819 +#: ../json-glib/json-reader.c:857 ../json-glib/json-reader.c:895 +#: ../json-glib/json-reader.c:933 ../json-glib/json-reader.c:978 +#: ../json-glib/json-reader.c:1014 ../json-glib/json-reader.c:1040 +msgid "No node available at the current position" +msgstr "ഈ സ്ഥാനത്ത് ഒരു നോഡുമില്ല" + +#: ../json-glib/json-reader.c:584 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "അപ്പോഴത്തെ സ്ഥാനത്ത് '%s' ആണ് ഒരു അറേ അല്ല" + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "ഇപ്പോഴത്തെ നോഡിന്റെ തരം '%s' ആണ്, പക്ഷേ ഒരു ഒബ്ജക്റ്റ് ആണ് പ്രതീക്ഷിച്ചത്." + +#: ../json-glib/json-reader.c:654 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "ഇപ്പോഴത്തെ സ്ഥാനത്തെ ഒബ്ജക്റ്റില്‍ '%s' എന്ന അംഗം നിര്‍വ്വചിച്ചിട്ടില്ല." + +#: ../json-glib/json-reader.c:737 ../json-glib/json-reader.c:788 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "അപ്പോഴത്തെ സ്ഥാനത്ത് '%s' ആണ് ഒരു ഒബ്ജക്ട്ട് അല്ല" + +#: ../json-glib/json-reader.c:828 ../json-glib/json-reader.c:866 +#: ../json-glib/json-reader.c:904 ../json-glib/json-reader.c:942 +#: ../json-glib/json-reader.c:987 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "അപ്പോഴത്തെ സ്ഥാനത്ത് '%s' ആണ് ഒരു മൂല്യം അല്ല" + +#: ../json-glib/json-reader.c:950 +msgid "The current position does not hold a string type" +msgstr "അപ്പോഴത്തെ സ്ഥാനത്ത് ഒരു വാചകം അല്ല" diff --git a/po/nb.po b/po/nb.po new file mode 100644 index 0000000..a52b84f --- /dev/null +++ b/po/nb.po @@ -0,0 +1,254 @@ +# Norwegian bokmål translation of json-glib. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Kjartan Maraas , 2011-2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib 1.2.3\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2016-09-12 18:19+0000\n" +"PO-Revision-Date: 2017-02-18 11:32+0100\n" +"Last-Translator: Kjartan Maraas \n" +"Language-Team: Kjartan Maraas \n" +"Language: nb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: feil ved åpning av fil: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: feil ved lesing av fil: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: feil ved skriving til standard utdata" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: feil ved lukking: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FIL" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formater JSON-filer." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatterer JSON-ressurser." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: mangler filer" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Valider JSON-filer." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "" + +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Forventet et JSON-objekt, men rotnoden er av type «%s»" + +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Uventet type «%s» i JSON-node" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Uventede ekstra elementer i JSON-tabell" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Ugyldig strengverdi ved konvertering til GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant-klasse «%c» er ikke støttet" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Ugyldig signatur for GVariant" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON-datastruktur er tom" + +#: json-glib/json-parser.c:914 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Tolkefeil: %s" + +#: json-glib/json-parser.c:997 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON-data må være kodet i UTF-8" + +#: json-glib/json-path.c:388 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Kun en rotnode tillates i et JSONPath-uttrykk" + +#: json-glib/json-path.c:397 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Rotnode etterfulgt av ugyldig tegn «%c»" + +#: json-glib/json-path.c:437 +msgid "Missing member name or wildcard after . character" +msgstr "" + +#: json-glib/json-path.c:511 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "" + +#: json-glib/json-path.c:555 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Ugyldig definisjon av sett «%*s»" + +#: json-glib/json-path.c:608 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "" + +#: json-glib/json-path.c:636 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "" + +#: json-glib/json-path.c:655 +#, c-format +msgid "Invalid first character '%c'" +msgstr "" + +#: json-glib/json-reader.c:473 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "" + +#: json-glib/json-reader.c:485 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "" + +#: json-glib/json-reader.c:502 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "" + +#: json-glib/json-reader.c:586 json-glib/json-reader.c:750 +#: json-glib/json-reader.c:801 json-glib/json-reader.c:839 +#: json-glib/json-reader.c:877 json-glib/json-reader.c:915 +#: json-glib/json-reader.c:953 json-glib/json-reader.c:998 +#: json-glib/json-reader.c:1034 json-glib/json-reader.c:1060 +msgid "No node available at the current position" +msgstr "Ingen node tilgjengelig i denne posisjonen" + +#: json-glib/json-reader.c:593 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "" + +#: json-glib/json-reader.c:669 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "" + +#: json-glib/json-reader.c:676 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "Medlem «%s» er ikke definert i objekt ved nåværende posisjon." + +#: json-glib/json-reader.c:757 json-glib/json-reader.c:808 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "Nåværende posisjon innholder en «%s» og ikke et objekt" + +#: json-glib/json-reader.c:848 json-glib/json-reader.c:886 +#: json-glib/json-reader.c:924 json-glib/json-reader.c:962 +#: json-glib/json-reader.c:1007 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "Nåværende posisjon inneholder en «%s» og ikke en verdi" + +#: json-glib/json-reader.c:970 +msgid "The current position does not hold a string type" +msgstr "Nåværende posisjon inneholder ikke en streng-type" diff --git a/po/ne.po b/po/ne.po new file mode 100644 index 0000000..e8ccd26 --- /dev/null +++ b/po/ne.po @@ -0,0 +1,264 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Gnome Nepali Translation Project\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-08-07 22:50+0000\n" +"PO-Revision-Date: 2017-08-24 16:32+0545\n" +"Language-Team: Nepali Translation Team \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.3\n" +"Last-Translator: Pawan Chitrakar \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"Language: ne\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "निर्गत राम्रो बनाउने" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "इन्डेन्टेसनस्थान " + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: फाइल खोल्दा त्रुटि: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: फाइल पार्स गर्दा त्रुटि: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: स्टडआउटमा लेख्दा त्रुटि" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: बन्द गर्दा त्रुटि: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "फाइल" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "JSON फाइल ढाँचा" + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "Json-glib-format ढाँचा JSON स्रोतहरू।" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "आदेश रेखा विकल्प पार्स गर्दा त्रुटि: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "थप जानकारीको लागि '%s --help' प्रयास गर्नुहोस्।" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: हराइरहेको फाइल" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "JSON फाईलहरू प्रमाणित गर्नुहोस्।" + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate दिएको URI मा JSON डेटा मान्य" + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "JSON वस्तु अपेक्षा गर्दै, तर मूल नोड प्रकार \"%s\" को हो" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, fuzzy, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "<%s> नोडका लागि कुनै \"type\" को विशेषता छैन" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "" + +#: json-glib/json-gvariant.c:622 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "GVariant tuple प्रकारमा समापन प्रतीक \"(\" छुटेको छ" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON array मा अप्रत्याशित अतिरिक्त तत्वहरू" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant मा रूपान्तर गर्दा अवैध स्ट्रिंग मान" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "एक GVariant शब्दकोश प्रविष्टिले एक JSON वस्तु सङ्ग एक मात्र सदस्य अपेक्षा गर्छ" + +#: json-glib/json-gvariant.c:1242 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "GVariant हस्ताक्षर अवैध छ" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "JSON डाटा खाली छ" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: पार्समा त्रुटि: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON डेटा UTF-8 सङ्केतन गरिएको हुनुपर्छ" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "एक मुल नोडलाई मात्र JSONPath अभिव्यक्तिमा अनुमति दिइएको छ" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "मुल नोड पछि अवैध वर्ण “%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr ". पछि सदस्य नाम वा वाइल्ड कार्ड हराइरहेको छ।" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "विकृत अभिव्यक्ति “%*s”" + +#: json-glib/json-path.c:556 +#, fuzzy, c-format +msgid "Invalid set definition “%*s”" +msgstr "शैली परिभाषा समूहमा अवैध प्रविष्टि: \"%s\"" + +#: json-glib/json-path.c:609 +#, fuzzy, c-format +msgid "Invalid slice definition “%*s”" +msgstr "शैली परिभाषा समूहमा अवैध प्रविष्टि: \"%s\"" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "अवैध array अनुक्रमणिका परिभाषा: “%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "अमान्य पहिलो वर्ण \"%c\"" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "हालको नोड \"%s\" प्रकारको छ, तर array वा वस्तु आशा गरिएको थियो।" + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "हालको स्थितिमा अनुक्रमणिका \"%d\" array को आकार भन्दा ठूलो छ।" + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "हालको स्थितिमा अनुक्रमणिका \"%d\" वस्तुको आकार भन्दा ठूलो छ।" + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "वर्तमान स्थितिमा कुनै नोड उपलब्ध छैन" + +#: json-glib/json-reader.c:592 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "" + +#: json-glib/json-reader.c:668 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "" + +#: json-glib/json-reader.c:675 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "" + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "हालको स्थितिले \"%s\" राख्छ र कुनै वस्तु होइन" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "हालको स्थितिले \"%s\" राख्छ र मान होइन" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "हालको स्थितिले स्ट्रिङ प्रकार समाविष्ट गर्दैन" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000..af7b88d --- /dev/null +++ b/po/nl.po @@ -0,0 +1,270 @@ +# Dutch translation for json-glib. +# Copyright (C) 2016 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Justin van Steijn , 2016. +# Nathan Follens , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-09-09 15:59+0000\n" +"PO-Revision-Date: 2017-09-09 20:12+0200\n" +"Last-Translator: Nathan Follens \n" +"Language-Team: Dutch \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 2.0.3\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Uitvoer mooi maken" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Inspringingspaties" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: fout bij het openen van bestand: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: fout bij het ontleden van bestand: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: fout bij het schrijven naar stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: fout bij het sluiten: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "BESTAND" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "JSON-bestanden formatteren." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatteert JSON-hulpbronnen." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Fout bij het ontleden van commandolijn-opties: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Probeer ‘%s --help’ voor meer informatie." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: ontbrekende bestanden" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "JSON-bestanden valideren." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate valideert JSON-gegevens op de opgegeven URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Verwacht een JSON-object, maar de root node is van het type ‘%s’" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Onverwacht type ‘%s’ in JSON-node" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Ontbrekende elementen in JSON-array om tupel te bevestigen" + +#: json-glib/json-gvariant.c:622 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Ontbrekend sluitsymbool ‘)’ in het GVariant-tupel-type" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "Onverwachte extra elementen in JSON-array" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "Ongeldige tekenreekswaarde omzetten naar GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Een GVariant-woordenboekelement verwacht een JSON-object met precies één lid" + +#: json-glib/json-gvariant.c:1242 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "GVariant-klasse ‘%c’ niet ondersteund" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "Ongeldige GVariant-handtekening" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "JSON-gegevens is leeg" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Ontleedfout: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON-gegevens moeten gecodeerd zijn als UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Er mag slechts één root node zijn in een JSONPath-uitdrukking" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Root node gevolgd door ongeldig teken ‘%c’" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Ontbrekende naam van lid of wildcard na .-teken" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Misvormde slice-uitdrukking ‘%*s’" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Ongeldige set-definitie ‘%*s’" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Ongeldige slice-definitie ‘%*s’" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Ongeldige array-index-definitie ‘%*s’" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Ongeldig eerste teken ‘%c’" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"De huidige node is van het type ‘%s’, maar een array of een object was " +"verwacht." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"De index ‘%d’ is hoger dan de grootte van de array op de huidige positie." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"De index ‘%d’ is hoger dan de grootte van het object op de huidige positie." + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "Geen node beschikbaar op de huidige positie" + +#: json-glib/json-reader.c:592 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "De huidige positie bevat een ‘%s’ en is geen array" + +#: json-glib/json-reader.c:668 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "De huidige node is van het type ‘%s’, maar een object was verwacht." + +#: json-glib/json-reader.c:675 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Het lid ‘%s’ is niet gedefinieerd in het object op de huidige positie." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "De huidige positie bevat een ‘%s’ en is geen object" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "De huidige positie bevat een ‘%s’ en is geen waarde" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "De huidige positie bevat geen tekenreekstype" diff --git a/po/oc.po b/po/oc.po new file mode 100644 index 0000000..5ea882c --- /dev/null +++ b/po/oc.po @@ -0,0 +1,300 @@ +# Occitan translation of jon-glib. +# Copyright (C) 2012 json-glib COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Cédric Valmary , 2015. +# Cédric Valmary (Tot en òc) , 2015. +# Cédric Valmary (totenoc.eu) , 2016, 2018. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/json-glib/issues\n" +"POT-Creation-Date: 2018-04-09 05:53+0000\n" +"PO-Revision-Date: 2018-04-19 09:56+0200\n" +"Last-Translator: Cédric Valmary (totenoc.eu) \n" +"Language-Team: Tot En Òc\n" +"Language: oc\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Virtaal 0.7.1\n" +"X-Launchpad-Export-Date: 2015-05-20 16:56+0000\n" +"X-Project-Style: gnome\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Formatatge indentat" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Espacis d'indentacion" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s : %s : error de dobertura del fichièr : %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s : %s : error d'analisi del fichièr : %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s : %s : error d'escritura cap a stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s : %s : error de tampadura : %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FICHIÈR" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Mesa en forma de fichièrs JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format met en forma de ressorsas JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Error d'analisi de las opcions de la linha de comanda : %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Ensajatz « %s --help » per mai d'informacions." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s : fichièrs mancants" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validacion de fichièrs JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate valida de donadas JSON a l'URI indicada." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Objècte de tipe JSON esperat mas lo nosèl raiç es de tipe « %s »" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, c-format, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Tipe « %s » inesperat dins lo nosèl JSON" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Elements mancants dins lo tablèu JSON per èsser confòrme a un tuple" + +#: json-glib/json-gvariant.c:622 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Simbòl tampant « ) » mancant dins lo tuple GVariant" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "Elements suplementaris inesperats dins lo tablèu JSON" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "Cadena de caractèrs invalida per la conversion en GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Una entrada de diccionari GVariant requerís un objècte JSON que conten un " +"sol membre" + +#: json-glib/json-gvariant.c:1242 +#, c-format, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "Classa GVariant « %c » pas presa en carga" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "Signatura GVariant invalida" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "Las donadas JSON son voidas" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:909 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Error d'analisi : %s" + +#: json-glib/json-parser.c:992 +msgid "JSON data must be UTF-8 encoded" +msgstr "Las donadas JSON devon èsser encodadas en UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Un sol nosèl raiç d'autorizat dins una expression JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Nosèl raiç seguit d'un caractèr invalid « %c »" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Nom de membre o caractèr joker mancant aprèp un caractèr « . »" + +#: json-glib/json-path.c:512 +#, c-format, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Expression de segmentacion malformada « %*s »" + +#: json-glib/json-path.c:556 +#, c-format, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Definicion d'ensemble invalida « %*s »" + +#: json-glib/json-path.c:609 +#, c-format, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Definicion de segmentacion invalida « %*s »" + +#: json-glib/json-path.c:637 +#, c-format, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Definicion d'indici de tablèu invalida « %*s »" + +#: json-glib/json-path.c:656 +#, c-format, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Primièr caractèr « %c » invalid" + +#: json-glib/json-reader.c:474 +#, c-format, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"Lo nosèl corrent es de tipe « %s » mas un tablèu o un objècte èra esperat." + +#: json-glib/json-reader.c:486 +#, c-format, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"L'indici « %d » es mai grand que la talha del tablèu a la posicion " +"actuala." + +#: json-glib/json-reader.c:503 +#, c-format, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"L'indici « %d » es mai grand que la talha de l'objècte indicat a la " +"posicion actuala." + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "Cap de nosèl pas disponible a aquesta posicion." + +#: json-glib/json-reader.c:592 +#, c-format, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "" +"La posicion actuala conten un element de tipe « %s » e non pas un tablèu" + +#: json-glib/json-reader.c:668 +#, c-format, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Lo nosèl actual es de tipe « %s » mas un objècte èra esperat." + +#: json-glib/json-reader.c:675 +#, c-format, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Lo membre « %s » es pas definit dins l'objècte a la posicion actuala." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "La posicion actuala conten un element de tipe « %s » e non pas un objècte" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "" +"La posicion actuala conten un element de tipe « %s » e non pas una valor" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "La posicion actuala conten pas una cadena de caractèrs" diff --git a/po/or.po b/po/or.po new file mode 100644 index 0000000..e7252df --- /dev/null +++ b/po/or.po @@ -0,0 +1,160 @@ +# Oriya translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# Manoj Kumar Giri , 2012. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2012-08-06 14:04+0000\n" +"PO-Revision-Date: 2012-08-09 18:26+0530\n" +"Last-Translator: Manoj Kumar Giri \n" +"Language-Team: Oriya \n" +"Language: or\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.4\n" + +#: ../json-glib/json-gobject.c:934 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "ଏକ JSON ବସ୍ତୁକୁ ଆଶାକରୁଅଛି, କିନ୍ତୁ ରୁଟର ନୋଡ `%s' ପ୍ରକାରର ଅଟେ" + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON ନୋଡରେ ଆଶାକରାଯାଇନଥିବା ପ୍ରକାର '%s'" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "ଏକ tuple କୁ ନିଶ୍ଚିତ କରିବା ପାଇଁ JSON ଆରେରେ ଅନୁପସ୍ଥିତ ଉପାଦାନ" + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "GVariant tuple ପ୍ରକାରରେ ବନ୍ଦ କରିବା ଚିହ୍ନ ')' ନାହିଁ" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON ଆରେର ଆଶାକରାଯାଇନଥିବା ଅତିରିକ୍ତ ଉପାଦାନ" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant କୁ ପରିବର୍ତ୍ତନ କରୁଥିବା ଅବୈଧ ବାକ୍ୟ ଖଣ୍ଡ ମୂଲ୍ୟ" + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "ଏକ GVariant ଅଭିଧାନ ନିବେଶ ଗୋଟିଏ JSON ବସ୍ତୁକୁ ଗୋଟିଏ ସଦସ୍ୟ ସହିତ ଆଶାକରିଥାଏ" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant ଶ୍ରେଣୀ '%c' ସମର୍ଥିତ ନୁହଁ" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "ଅବୈଧ GVariant ହସ୍ତାକ୍ଷର" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "JSON ତଥ୍ୟ ନାହିଁ" + +#: ../json-glib/json-parser.c:818 +#, c-format +msgid "%s:%d: Parse error: %s" +msgstr "%s:%d: ବିଶ୍ଳେଷଣ ତ୍ରୁଟି: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "କେବଳ ଗୋଟିଏ ମୂଖ୍ୟ ଚାଳକ ନୋଡ JSONPath ଅଭିବ୍ୟକ୍ତିରେ ଅନୁମତି ପ୍ରାପ୍ତ" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "ଅବୈଧ ଅକ୍ଷର '%c' ଦ୍ୱାରା ମୂଖ୍ୟ ଚାଳକ ନୋଡ" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "ତ୍ରୁଟିଯୁକ୍ତ ଖଣ୍ଡ ଅଭିବ୍ୟକ୍ତି '%*s'" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "ଅବୈଧ ସେଟ ସଂଜ୍ଞା '%*s'" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "ଅବୈଧ ଖଣ୍ଡ ସଂଜ୍ଞା '%*s'" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "ଅବୈଧ ଆରେ ଅନୁକ୍ରମଣିକା ସଂଜ୍ଞା '%*s'" + +#: ../json-glib/json-reader.c:463 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "" +"ପ୍ରଚଳିତ ନୋଡଟି '%s' ପ୍ରକାରର ଅଟେ, କିନ୍ତୁ ଏକ ଆରେ ଅଥବା ବସ୍ତୁ ଆଶାକରାଯାଇଥିଲା।" + +#: ../json-glib/json-reader.c:475 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "ଅନୁକ୍ରମଣିକା '%d' ଟି ପ୍ରଚଳିତ ଅବସ୍ଥାନରେ ଆରେ ଆକାର ଠାରୁ ବଡ଼ ଅଟେ।" + +#: ../json-glib/json-reader.c:492 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "ଅନୁକ୍ରମଣିକା '%d' ଟି ପ୍ରଚଳିତ ଅବସ୍ଥାନରେ ବସ୍ତୁ ଆକାର ଠାରୁ ବଡ଼ ଅଟେ।" + +#: ../json-glib/json-reader.c:576 ../json-glib/json-reader.c:729 +#: ../json-glib/json-reader.c:780 ../json-glib/json-reader.c:818 +#: ../json-glib/json-reader.c:856 ../json-glib/json-reader.c:894 +#: ../json-glib/json-reader.c:932 ../json-glib/json-reader.c:977 +#: ../json-glib/json-reader.c:1013 ../json-glib/json-reader.c:1039 +msgid "No node available at the current position" +msgstr "ପ୍ରଚଳିତ ଅବସ୍ଥାନରେ କୌଣସି ନୋଡ ଉପଲବ୍ଧ ନାହିଁ।" + +#: ../json-glib/json-reader.c:583 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "ପ୍ରଚଳିତ ଅବସ୍ଥାନ ଏକ '%s' କୁ ଧାରଣ କରିଥାଏ ଏବଂ କୌଣସି ଆରେକୁ ଧାରଣ କରିନଥାଏ" + +#: ../json-glib/json-reader.c:646 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "ପ୍ରଚଳିତ ନୋଡଟି '%s' ପ୍ରକାରର ଅଟେ, କିନ୍ତୁ ଏକ ବସ୍ତୁକୁ ଆଶାକରୁଥିଲା।" + +#: ../json-glib/json-reader.c:653 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "'%s' ସଦସ୍ୟଟି ପ୍ରଚଳିତ ଅବସ୍ଥାନରେ ବସ୍ତୁ ପାଖରେ ବ୍ୟାଖ୍ୟା କରିନାହିଁ।" + +#: ../json-glib/json-reader.c:736 ../json-glib/json-reader.c:787 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "" +"ପ୍ରଚଳିତ ଅବସ୍ଥାନ ଏକ '%s' କୁ ଧାରଣ କରିଥାଏ କିନ୍ତୁ କୌଣସି ବସ୍ତୁକୁ ଧାରଣ କରିନଥାଏ" + +#: ../json-glib/json-reader.c:827 ../json-glib/json-reader.c:865 +#: ../json-glib/json-reader.c:903 ../json-glib/json-reader.c:941 +#: ../json-glib/json-reader.c:986 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "ପ୍ରଚଳିତ ଅବସ୍ଥାନ ଏକ '%s' ଧାରଣ କରିଥାଏ କିନ୍ତୁ କୌଣସି ମୂଲ୍ୟ ଧାରଣ କରିନଥାଏ" + +#: ../json-glib/json-reader.c:949 +msgid "The current position does not hold a string type" +msgstr "ପ୍ରଚଳିତ ଅବସ୍ଥାନ କୌଣସି ବାକ୍ୟଖଣ୍ଡ ପ୍ରକାର ଧାରଣ କରିନଥାଏ" + + diff --git a/po/pa.po b/po/pa.po new file mode 100644 index 0000000..1d8321a --- /dev/null +++ b/po/pa.po @@ -0,0 +1,158 @@ +# Punjabi translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# A S Alam , 2012, 2013. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-02-11 20:00+0000\n" +"PO-Revision-Date: 2013-02-26 07:26+0530\n" +"Last-Translator: A S Alam \n" +"Language-Team: Punjabi/Panjabi \n" +"Language: pa\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Lokalize 1.5\n" + +#: ../json-glib/json-gobject.c:925 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "JSON ਆਬਜੈਕਟ ਦੀ ਮੰਗ ਸੀ, ਪਰ ਰੂਟ ਨੋਡ ਦੀ ਕਿਸਮ `%s' ਹੈ" + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON ਨੋਡ ਵਿੱਚ ਅਣਜਾਣ ਕਿਸਮ '%s'" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON ਅਰੇ ਵਿੱਚ ਟਪਲ ਦੇਣ ਵਾਲੇ ਐਲੀਮੈਂਟ ਗੁੰਮ ਹਨ" + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "GVariant ਟਪਲ ਕਿਸਮ ਵਿੱਚ ')' ਬੰਦ ਕਰਨ ਨਿਸ਼ਾਨ ਗੁੁੰਮ ਹੈ" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON ਅਰੇ ਵਿੱਚ ਵਾਧੂ ਐਲੀਮੈਂਟ ਦੀ ਮੰਗ ਸੀ" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant ਲਈ ਬਦਲਣ ਲਈ ਗਲਤ ਸਤਰ ਮੁੱਲ" + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant ਡਿਕਸ਼ਨਰੀ ਐਂਟਰਈ ਲਈ ਇੱਕ ਮੈਂਬਰ ਲਈ ਠੀਕ JSON ਆਬਜੈਕਟ ਦੀ ਮੰਗ ਸੀ" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant ਕਲਾਸ '%c' ਸਹਾਇਕ ਨਹੀਂ" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "ਅਢੁੱਕਵਾਂ GVariant ਦਸਤਖਤ" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "JSON ਡਾਟਾ ਖਾਲੀ ਹੈ।" + +#: ../json-glib/json-parser.c:825 +#, c-format +#| msgid "%s:%d: Parse error: %s" +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: ਪਾਰਸ ਗਲਤੀ: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath ਸਮੀਕਰਨ ਵਿੱਚ ਇੱਕ ਰੂਟ ਨੋਡ ਹੀ ਮਨਜ਼ੂਰ ਸੀ" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "ਗਲਤ ਅੱਖਰ '%c' ਦੇ ਬਾਅਦ ਰੂਟ ਨੋਡ" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "ਨਿਕਾਰਾ ਭਾਗ ਸਮੀਕਰਨ '%*s'" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "ਗਲਤ ਸੈੱਟ ਪ੍ਰੀਭਾਸ਼ਾ '%*s'" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "ਗਲਤ ਭਾਗ ਪ੍ਰੀਭਾਸ਼ਾ '%*s'" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "ਗਲਤ ਅਰੇ ਇੰਡੈਕਸ ਪ੍ਰੀਭਾਸ਼ਾ '%*s'" + +#: ../json-glib/json-reader.c:464 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "ਮੌਜੂਦਾ ਨੋਡ ਦੀ '%s' ਕਿਸਮ ਹੈ, ਪਰ ਅਰੇ ਜਾਂ ਆਬਜੈਕਟ ਦੀ ਮੰਗ ਸੀ।" + +#: ../json-glib/json-reader.c:476 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "ਇੰਡੈਕਸ '%d' ਮੌਜੂਦਾ ਸਥਿਤੀ ਉੱਤੇ ਅਰੇ ਦੇ ਆਕਾਰ ਤੋਂ ਵੱਧ ਹੈ।" + +#: ../json-glib/json-reader.c:493 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "ਇੰਡੈਕਸ '%d' ਮੌਜੂਦਾ ਸਥਿਤੀ ਉੱਤੇ ਆਬਜੈਕਟ ਦੇ ਆਕਾਰ ਤੋਂ ਵੱਧ ਹੈ।" + +#: ../json-glib/json-reader.c:577 ../json-glib/json-reader.c:730 +#: ../json-glib/json-reader.c:781 ../json-glib/json-reader.c:819 +#: ../json-glib/json-reader.c:857 ../json-glib/json-reader.c:895 +#: ../json-glib/json-reader.c:933 ../json-glib/json-reader.c:978 +#: ../json-glib/json-reader.c:1014 ../json-glib/json-reader.c:1040 +msgid "No node available at the current position" +msgstr "ਮੌਜੂਦਾ ਸਥਿਤੀ ਉੱਤੇ ਕੋਈ ਵੀ ਨੋਡ ਉਪਲੱਬਧ ਨਹੀਂ" + +#: ../json-glib/json-reader.c:584 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "ਮੌਜੂਦਾ ਸਥਿਤੀ '%s' ਰੱਖਦੀ ਹੈ ਨਾ ਕਿ ਅਰੇ" + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "ਮੌਜੂਦਾ ਨੋਡ ਦੀ '%s' ਕਿਸਮ ਹੈ, ਪਰ ਆਬਜੈਕਟ ਦੀ ਮੰਗ ਸੀ।" + +#: ../json-glib/json-reader.c:654 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "ਮੈਂਬਰ '%s' ਨੂੰ ਮੌਜੂਦਾ ਸਥਿਤੀ ਉੱਤੇ ਆਬਜੈਕਟ ਵਿੱਚ ਪ੍ਰਭਾਸ਼ਿਤ ਹੈ।" + +#: ../json-glib/json-reader.c:737 ../json-glib/json-reader.c:788 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "ਮੌਜੂਦਾ ਸਥਿਤੀ '%s' ਰੱਖਦੀ ਹੈ ਨਾ ਕਿ ਆਬਜੈਕਟ" + +#: ../json-glib/json-reader.c:828 ../json-glib/json-reader.c:866 +#: ../json-glib/json-reader.c:904 ../json-glib/json-reader.c:942 +#: ../json-glib/json-reader.c:987 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "ਮੌਜੂਦਾ ਸਥਿਤੀ '%s' ਰੱਖਦੀ ਹੈ, ਮੁੱਲ ਨਹੀਂ" + +#: ../json-glib/json-reader.c:950 +msgid "The current position does not hold a string type" +msgstr "ਮੌਜੂਦਾ ਸਥਿਤੀ ਸਤਰ ਕਿਸਮ ਨਹੀਂ ਰੱਖਦਾ ਹੈ" + diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 0000000..b053e36 --- /dev/null +++ b/po/pl.po @@ -0,0 +1,266 @@ +# Polish translation for json-glib. +# Copyright © 2011-2017 the json-glib authors. +# This file is distributed under the same license as the json-glib package. +# Piotr Drąg , 2011-2017. +# Aviary.pl , 2011-2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-03-18 17:08+0100\n" +"Last-Translator: Piotr Drąg \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Ładniejsze wyjście" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Spacje wcięcia" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: błąd podczas otwierania pliku: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: błąd podczas przetwarzania pliku: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: błąd podczas zapisywania do standardowego wyjścia" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: błąd podczas zamykania: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "PLIK" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatuje pliki JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatuje zasoby JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Błąd podczas przetwarzania opcji wiesza poleceń: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Polecenie „%s --help” wyświetli więcej informacji." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: brak plików" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Sprawdza pliki JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate sprawdza dane JSON na podanym adresie URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Oczekiwano obiektu JSON, ale typ głównego węzła to „%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Nieoczekiwany typ „%s” w węźle JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Brak elementów w tablicy JSON, aby zgadzało się z krotką" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Brak zamykającego symbolu „)” w typie krotki GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Nieoczekiwane dodatkowe elementy w tablicy JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Nieprawidłowa wartość ciągu konwertowanego do GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Wpis słownika GVariant oczekuje obiektu JSON z dokładnie jednym elementem" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Klasa GVariant „%c” jest nieobsługiwana" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Nieprawidłowy podpis GVariant" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Dane JSON są puste" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: błąd przetwarzania: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Dane JSON muszą być zakodowane w UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Dozwolony jest tylko jeden węzeł główny w wyrażeniu JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Po węźle głównym występuje nieprawidłowy znak „%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Brak nazwy elementu lub wieloznacznika po znaku ." + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Błędnie sformatowane wyrażenie plasterka „%*s”" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Nieprawidłowe określenie zestawu „%*s”" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Nieprawidłowe określenie plasterka „%*s”" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Nieprawidłowe określenie indeksu tablicy „%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Nieprawidłowy pierwszy znak „%c”" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Bieżący węzeł jest typu „%s”, a oczekiwano tablicy lub obiektu." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Indeks „%d” jest większy niż rozmiar tablicy w bieżącym położeniu." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Indeks „%d” jest większy niż rozmiar obiektu w bieżącym położeniu." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Brak węzłów dostępnych w bieżącym położeniu" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Bieżące położenie przechowuje „%s”, a nie tablicę" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Bieżący węzeł jest typu „%s”, a oczekiwano obiektu." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Element „%s” nie jest określony w obiekcie w bieżącym położeniu." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Bieżące położenie przechowuje „%s”, a nie obiekt" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Bieżące położenie przechowuje „%s”, a nie wartość" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Bieżące położenie nie przechowuje typu ciągu" diff --git a/po/pt.po b/po/pt.po new file mode 100644 index 0000000..aba2d47 --- /dev/null +++ b/po/pt.po @@ -0,0 +1,261 @@ +# json-glib's Portuguese translation. +# Copyright © 2012, 2013, 2014 json-glib +# This file is distributed under the same license as the json-glib package. +# Duarte Loreto , 2012, 2013, 2014. +# +# Pedro Albuquerque , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: 3.12\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2015-06-07 22:10+0000\n" +"PO-Revision-Date: 2015-06-25 09:43+0100\n" +"Last-Translator: Pedro Albuquerque \n" +"Language-Team: Português \n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Gtranslator 2.91.6\n" + +#: ../json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Embelezar resultado" + +#: ../json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Espaços da indentação" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:77 ../json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: erro ao abrir ficheiro: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:89 ../json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: erro ao processar ficheiro: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: ../json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: erro ao escrever para stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:128 ../json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: erro ao fechar: %s\n" + +#: ../json-glib/json-glib-format.c:157 ../json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FICHEIRO" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-format.c:160 +msgid "Format JSON files." +msgstr "Formatar ficheiros JSON." + +#: ../json-glib/json-glib-format.c:161 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formata recursos JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:178 ../json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Erro ao processar opções de linha de comandos: %s\n" + +#: ../json-glib/json-glib-format.c:180 ../json-glib/json-glib-format.c:194 +#: ../json-glib/json-glib-validate.c:138 ../json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Tente \"%s --help\" para mais informações." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:192 ../json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: faltam ficheiros" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validar ficheiros JSON." + +#: ../json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate valida dados JSON no URI indicado." + +#: ../json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Esperado um objeto JSON, mas o nó raiz é do tipo \"%s\"" + +#: ../json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Tipo \"%s\" inesperado no nó JSON" + +#: ../json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Elementos em falta na matriz JSON para respeitar um conjunto" + +#: ../json-glib/json-gvariant.c:621 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Falta o símbolo de fecho \")\" no tipo de conjunto GVariant" + +#: ../json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Elementos extra inesperados na matriz JSON" + +#: ../json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Valor inválido de cadeia ao converter em GVariant" + +#: ../json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Uma entrada de dicionário GVariant espera um objeto JSON com exatamente um " +"membro" + +#: ../json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "Classe GVariant \"%c\" não suportada" + +#: ../json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Assinatura GVariant inválida" + +#: ../json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Dados JSON estão vazios" + +#: ../json-glib/json-parser.c:815 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: erro de processamento: %s" + +#: ../json-glib/json-parser.c:883 +msgid "JSON data must be UTF-8 encoded" +msgstr "Dados JSON têm de estar codificados em UTF-8" + +#: ../json-glib/json-path.c:388 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Só um nó raiz é permitido numa expressão JSONPath" + +#: ../json-glib/json-path.c:397 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Nó raiz seguido do carácter inválido \"%c\"" + +#: ../json-glib/json-path.c:437 +msgid "Missing member name or wildcard after . character" +msgstr "Falta nome de membro ou caráter global após caráter \".\"" + +#: ../json-glib/json-path.c:511 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Expressão \"%*s\" de fatia mal formada" + +#: ../json-glib/json-path.c:555 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Definição inválida de conjunto \"%*s\"" + +#: ../json-glib/json-path.c:608 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Definição inválida de fatia \"%*s\"" + +#: ../json-glib/json-path.c:636 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Definição inválida de índice de matriz \"%*s\"" + +#: ../json-glib/json-path.c:655 +#, c-format +msgid "Invalid first character '%c'" +msgstr "Primeiro carácter \"%c\" inválido" + +#: ../json-glib/json-reader.c:459 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "O nó atual é do tipo \"%s\", mas era esperada uma matriz ou um objeto." + +#: ../json-glib/json-reader.c:471 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "O índice \"%d\" é maior do que o tamanho da matriz na posição atual." + +#: ../json-glib/json-reader.c:488 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "O índice \"%d\" é maior do que o tamanho do objeto na posição atual." + +#: ../json-glib/json-reader.c:572 ../json-glib/json-reader.c:723 +#: ../json-glib/json-reader.c:774 ../json-glib/json-reader.c:812 +#: ../json-glib/json-reader.c:850 ../json-glib/json-reader.c:888 +#: ../json-glib/json-reader.c:926 ../json-glib/json-reader.c:971 +#: ../json-glib/json-reader.c:1007 ../json-glib/json-reader.c:1033 +msgid "No node available at the current position" +msgstr "Nenhum nó disponível na posição atual" + +#: ../json-glib/json-reader.c:579 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "A posição atual contém um \"%s\" e não uma matriz" + +#: ../json-glib/json-reader.c:642 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "O nó atual é do tipo \"%s\", mas era esperado um objeto." + +#: ../json-glib/json-reader.c:649 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "O membro \"%s\" não está definido no objeto da posição atual." + +#: ../json-glib/json-reader.c:730 ../json-glib/json-reader.c:781 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "A posição atual contém um \"%s\" e não um objeto" + +#: ../json-glib/json-reader.c:821 ../json-glib/json-reader.c:859 +#: ../json-glib/json-reader.c:897 ../json-glib/json-reader.c:935 +#: ../json-glib/json-reader.c:980 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "A posição atual contém um \"%s\" e não um valor" + +#: ../json-glib/json-reader.c:943 +msgid "The current position does not hold a string type" +msgstr "A posição atual não contém um tipo cadeia" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 0000000..d1205b5 --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,302 @@ +# Brazilian Portuguese translation for json-glib. +# Copyright (C) 2017 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Gabriel Speckhahn , 2012. +# Enrico Nicoletto , 2013. +# Rafael Fontenelle , 2013, 2017. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-08-30 10:50-0200\n" +"Last-Translator: Rafael Fontenelle \n" +"Language-Team: Brazilian Portuguese \n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" +"X-Generator: Virtaal 1.0.0-beta1\n" +"X-Project-Style: gnome\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Saída formatada" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Espaços de recuo" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: erro ao abrir arquivo: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: erro ao analisar arquivo: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: erro ao gravar na saída padrão" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: erro ao fechar: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "ARQUIVO" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatar arquivos JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formata recursos JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Ocorreu erro ao analisar as opções de linha de comando: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Tente “%s --help” para mais informações." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: arquivos em falta" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validar arquivos JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate valida dados JSON no URI fornecido." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Objeto JSON esperado, porém o nó raiz é do tipo “%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Tipo inesperado “%s” no nó JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Faltam elementos no vetor JSON para que se forme uma tupla" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Símbolo de fechamento “)” ausente no tipo de tupla GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Elementos adicionais inesperados no vetor JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Valor inválido de string ao converter para GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Uma entrada de dicionário GVariant espera um objeto JSON com exatamente um " +"membro" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "Não há suporte para a classe GVariant “%c”" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Assinatura GVariant inválida" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Dados JSON vazios" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d%d: Erro na análise: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Os dados JSON devem possuir codificação UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Apenas um nó raiz é permitido em uma expressão JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Nó raiz seguido de caractere inválido “%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Faltando nome de membro ou coringa após o caractere “.”" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Expressão de corte “%*s” má formada" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Definição de conjunto “%*s” inválida" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Definição de corte “%*s” inválida" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Definição de índice de vetor “%*s” inválida" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Primeiro caractere “%c” inválido" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "O nó atual é do tipo “%s”, mas um vetor ou objeto era esperado." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "O índice “%d” é maior do que o tamanho do vetor na posição atual." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "O índice “%d” é maior do que o tamanho do objeto na posição atual." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Nenhum nó disponível na posição atual" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "A posição atual detém um “%s” e não um vetor" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "O nó atual é do tipo “%s”, mas um objeto era esperado." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "O membro “%s” não está definido no objeto na posição atual." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "A posição atual detém um “%s” e não um objeto" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "A posição atual detém um “%s” e não um valor" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "A posição atual não detém um tipo string" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "A posição atual não detém um tipo inteiro" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "A posição atual não detém um tipo de ponto flutuante" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "A posição atual não detém um tipo booleano" diff --git a/po/ro.po b/po/ro.po new file mode 100644 index 0000000..a61fbb4 --- /dev/null +++ b/po/ro.po @@ -0,0 +1,270 @@ +# Romanian translation for json-glib. +# Copyright (C) 2015 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Daniel Șerbănescu , 2015. +# Daniel Șerbănescu , 2015. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/json-glib/issues\n" +"POT-Creation-Date: 2018-03-13 14:47+0000\n" +"PO-Revision-Date: 2018-04-06 00:42+0300\n" +"Last-Translator: Florentina Mușat \n" +"Language-Team: Gnome Romanian Translation Team\n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < " +"20)) ? 1 : 2);;\n" +"X-Generator: Poedit 2.0.6\n" +"X-Project-Style: gnome\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Înfrumusețează rezultatul" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Spații de indentare" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: eroare la deschiderea fișierului: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: eroare la parsarea fișierului: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: eroare la scrierea în stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: eroare la închidere: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FIȘIER" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatează fișiere JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formatează resurse JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Eroare la parsarea opțiunilor din linia de comandă: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Încercați „%s --help” pentru mai multe informații." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: lipsesc fișiere" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validează fișiere JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate validează date JSON la URI-ul dat." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Se așteaptă un obiect JSON, dar nodul rădăcină este de tipul „%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Tip neașteptat „%s” în nodul JSON" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Lipsesc elemente în matricea JSON pentru a fi în acord cu un tuplu" + +#: json-glib/json-gvariant.c:622 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Lipsește simbolul de închidere „)” în tipul de tuplu GVariant" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "Elemente adiționale neașteptate în matricea JSON" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "Valoare de șir nevalidă în timpul convertirii la GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"O înregistrate de dicționar GVariant presupune un obiect JSON cu exact un " +"membru" + +#: json-glib/json-gvariant.c:1242 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Clasa GVariant „%c” nu este suportată" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "Semnătură GVariant nevalidă" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "Datele JSON sunt goale" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:909 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Eroare la parsare: %s" + +#: json-glib/json-parser.c:992 +msgid "JSON data must be UTF-8 encoded" +msgstr "Datele JSON trebuie să fie codate UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Doar un nod rădăcină este permis într-o expresie JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Nodul rădăcină urmat de caracterul nevalid „%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Lipsește un nume de membru sau metacaracter după caracterul „.”" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Expresie de slice eronată „%*s”" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Definiție de set nevalidă „%*s”" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Definiție de slice nevalidă „%*s”" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Definiția indexului de matrice nevalidă „%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Primul caracter nevalid „%c”" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"Nodul curent este de tipul „%s”, dar o matrice sau un obiect a fost așteptat." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"Indexul „%d” este mai mare decât dimensiunea matricei la poziția curentă." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"Indexul „%d” este mai mare decât dimensiunea obiectului la poziția curentă." + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "Niciun nod disponibil la poziția curentă" + +#: json-glib/json-reader.c:592 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Poziția curentă ține un „%s” și nu o matrice" + +#: json-glib/json-reader.c:668 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Nodul curent este de tipul „%s”, dar s-a așteptat un obiect." + +#: json-glib/json-reader.c:675 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Membrul „%s” nu este definit în obiectul de la poziția curentă." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Poziția curentă ține un „%s” și nu un obiect" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Poziția curentă ține un „%s” și nu o valoare" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "Poziția curentă nu ține un șir" diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 0000000..5b60ba7 --- /dev/null +++ b/po/ru.po @@ -0,0 +1,271 @@ +# Russian translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# Юрий Козлов , 2012. +# Yuri Myasoedov , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-03-10 22:18+0000\n" +"PO-Revision-Date: 2014-03-11 12:23+0300\n" +"Last-Translator: Yuri Myasoedov \n" +"Language-Team: русский \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Poedit 1.5.4\n" + +#: ../json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Выводить в удобочитаемой форме" + +#: ../json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Отступы" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:77 ../json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: не удалось открыть файл: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:89 ../json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: не удалось разобрать файл: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: ../json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: не удалось записать в стандартный вывод" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:128 ../json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: не удалось закрыть: %s\n" + +#: ../json-glib/json-glib-format.c:157 ../json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "ФАЙЛ" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-format.c:160 +msgid "Format JSON files." +msgstr "Форматирование файлов JSON." + +#: ../json-glib/json-glib-format.c:161 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format форматирует ресурсы JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:178 ../json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Не удалось разобрать параметры командной строки: %s\n" + +#: ../json-glib/json-glib-format.c:180 ../json-glib/json-glib-format.c:194 +#: ../json-glib/json-glib-validate.c:138 ../json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Используйте «%s --help» для получения подробной информации." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:192 ../json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: отсутствуют файлы" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Проверка корректности файлов JSON." + +#: ../json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "" +"json-glib-validate проверяет корректность данных JSON по заданному URI." + +#: ../json-glib/json-gobject.c:917 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Ожидается объект JSON, но корневой узел имеет тип «%s»" + +#: ../json-glib/json-gvariant.c:545 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Неожиданный тип «%s» в узле JSON" + +#: ../json-glib/json-gvariant.c:615 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Отсутствуют элементы в массиве JSON для соответствия кортежу" + +#: ../json-glib/json-gvariant.c:643 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Отсутствует закрывающий символ «)» в кортеже типа GVariant" + +#: ../json-glib/json-gvariant.c:651 +msgid "Unexpected extra elements in JSON array" +msgstr "Неожиданные дополнительные символы в массиве JSON" + +#: ../json-glib/json-gvariant.c:930 +msgid "Invalid string value converting to GVariant" +msgstr "Некорректное строковое значение для преобразования к GVariant" + +#: ../json-glib/json-gvariant.c:986 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Элемент словаря GVariant должен быть объектом JSON с единственным членом" + +#: ../json-glib/json-gvariant.c:1266 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "Класс GVariant «%c» не поддерживается" + +#: ../json-glib/json-gvariant.c:1314 +msgid "Invalid GVariant signature" +msgstr "Недопустимая подпись GVariant" + +#: ../json-glib/json-gvariant.c:1362 +msgid "JSON data is empty" +msgstr "Данные JSON отсутствуют" + +#: ../json-glib/json-parser.c:817 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: ошибка разбора: %s" + +#: ../json-glib/json-parser.c:885 +msgid "JSON data must be UTF-8 encoded" +msgstr "Данные JSON должны быть в кодировке UTF-8" + +#: ../json-glib/json-path.c:438 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "В выражении JSONPath может быть только один корневой узел" + +#: ../json-glib/json-path.c:447 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Корневой узел заканчивается некорректным символом «%c»" + +#: ../json-glib/json-path.c:487 +msgid "Missing member name or wildcard after . character" +msgstr "Отсутствует имя члена или шаблон после символа «.»" + +#: ../json-glib/json-path.c:561 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Неправильное выражение среза «%*s»" + +#: ../json-glib/json-path.c:605 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Неверное определение присвоения «%*s»" + +#: ../json-glib/json-path.c:658 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Неверное определение среза «%*s»" + +#: ../json-glib/json-path.c:686 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Неверное определение индекса массива «%*s»" + +#: ../json-glib/json-path.c:705 +#, c-format +msgid "Invalid first character '%c'" +msgstr "Неверный первый символ «%c»" + +#: ../json-glib/json-reader.c:463 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "Текущий узел имеет тип «%s», но ожидается массив или объект." + +#: ../json-glib/json-reader.c:475 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "В текущей позиции индекс «%d» больше размера массива." + +#: ../json-glib/json-reader.c:492 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "В текущей позиции индекс «%d» больше размера объекта." + +#: ../json-glib/json-reader.c:577 ../json-glib/json-reader.c:731 +#: ../json-glib/json-reader.c:782 ../json-glib/json-reader.c:820 +#: ../json-glib/json-reader.c:858 ../json-glib/json-reader.c:896 +#: ../json-glib/json-reader.c:934 ../json-glib/json-reader.c:979 +#: ../json-glib/json-reader.c:1015 ../json-glib/json-reader.c:1041 +msgid "No node available at the current position" +msgstr "В текущей позиции отсутствует узел" + +#: ../json-glib/json-reader.c:584 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "В текущей позиции содержится «%s», а не массив" + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "Текущий узел имеет тип «%s», но ожидается объект." + +#: ../json-glib/json-reader.c:654 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "В текущей позиции член «%s» не определён в объекте." + +#: ../json-glib/json-reader.c:738 ../json-glib/json-reader.c:789 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "В текущей позиции содержится «%s», а не объект" + +#: ../json-glib/json-reader.c:829 ../json-glib/json-reader.c:867 +#: ../json-glib/json-reader.c:905 ../json-glib/json-reader.c:943 +#: ../json-glib/json-reader.c:988 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "В текущей позиции содержится «%s», а не значение" + +#: ../json-glib/json-reader.c:951 +msgid "The current position does not hold a string type" +msgstr "В текущей позиции не содержится строковое значение" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "В текущей позиции не содержится значения целого" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "В текущей позиции не содержится значения с плавающей точкой" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "В текущей позиции не содержится логического значения" diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 0000000..bfde1be --- /dev/null +++ b/po/sk.po @@ -0,0 +1,268 @@ +# Slovak translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Pavol Klačanský , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-09-02 10:16+0200\n" +"Last-Translator: Dušan Kazik \n" +"Language-Team: Slovak \n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n" +"X-Generator: Poedit 2.0.3\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Skrášliť výstup" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Odsadenie v medzerách" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: chyba pri otváraní súboru: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: chyba pri analyzovaní súboru: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: chyba pri zápise do štandardného výstupu" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: chyba pri zatváraní: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "SÚBOR" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formátovať súbory JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format sformátuje zdroje JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Chyba pri analýze volieb príkazového riadka: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Viac informácií získate po zadaní príkazu „%s --help“." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: chýbajúce súbory" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Overovať súbory JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate overí údaje JSON na danej URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Očakáva sa objekt JSON, ale koreňový uzol je typu „%s“" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Neočakávaný typ „%s“ v uzle JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Chýbajú prvky v poli JSON na zmenu n-tice" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Chýba uzatvárací symbol „)“ v type n-tica pre GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Neočakávané nadbytočné prvky v poli JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Neplatná hodnota reťazca, ktorý sa má konvertovať na typ GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Položka typu slovník pre GVariant očakáva objekt JSON s presne jedným členom" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Trieda pre GVariant „%c“ nie je podporovaná" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Neplatný podpis pre GVariant" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Dáta JSON sú prázdne" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Chyba analýzy: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Údaje JSON musia byť v kódovaní UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Vo výraze JSONPath môže byť len jeden koreňový uzol" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Za koreňovým uzlom je neplatný znak „%c“" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Chýba názov člena alebo zástupný znak po znaku „.“" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Chybný výraz „%*s“ pre výsek" + +# MČ: set sa zväčša prekladá ako množina, vyhovoval by tento výraz? +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Neplatná definícia množiny „%*s“" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Neplatná definícia výseku „%*s“" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Neplatná definícia indexu poľa „%*s“" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Neplatný prvý znak „%c“" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Bolo očakávané pole alebo objekt, ale aktuálny uzol je typu „%s“." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"Index s hodnotou „%d“ poľa na aktuálnej pozícii je väčší ako jeho veľkosť." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"Index s hodnotou „%d“ objektu na aktuálnej pozícii je väčší ako jeho veľkosť." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Na aktuálnej pozícii nie je dostupný žiadny uzol" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Na aktuálnej pozícii je „%s“ a nie pole" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Bol očakávaný objekt, ale aktuálny uzol je typu „%s“." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Člen „%s“ nie je definovaný v objekte na aktuálnej pozícii." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Na aktuálnej pozícii je „%s“ a nie objekt" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Na aktuálnej pozícii je „%s“ a nie hodnota" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Na aktuálnej pozícii je „%s“ a nie reťazec" diff --git a/po/sl.po b/po/sl.po new file mode 100644 index 0000000..08a6b8e --- /dev/null +++ b/po/sl.po @@ -0,0 +1,276 @@ +# Slovenian translation for json-glib. +# Copyright (C) 2011 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# Matej Urbančič , 2011–2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-09-19 23:20+0200\n" +"Last-Translator: Matej Urbančič \n" +"Language-Team: Slovenian GNOME Translation Team \n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" +"%100==4 ? 3 : 0);\n" +"X-Poedit-SourceCharset: utf-8\n" +"X-Generator: Poedit 2.0.1\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Olepšaj odvod" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Presledki zamika" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: napaka odpiranja datoteke: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: napaka razčlenjevanja datoteke: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: napaka pisanja na standardni odvod" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: napaka zapiranja: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "DATOTEKA" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Oblikuj datoteke JSON." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "Možnost json-glib-format oblikuje zapis virov JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Napaka med razčlenjevanjem možnosti ukazne vrstice: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Poskusite zagnati ukaz »%s --help« za več podrobnosti." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: manjkajoče datoteke" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Overi datoteke JSON." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "Možnost json-glib-validate overi podatke JSON za podani naslov URI." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Pričakovan je predmet JSON, vendar pa je korensko vozlišče vrste »%s«" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Nepričakovana vrsta »%s« v vozlišču JSON" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Manjkajo predmeti v polju JSON za skladnost z n-terico." + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Manjka zaključni znak » ) « v vrsti n-terice GVariant" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Nepričakovan dodatni predmet polja JSON" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Neveljavna vrednost niza med pretvarjanjem v GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "Slovar GVariant pričakuje predmet JSON z natanko enim določilom" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "Razred GVariant »%c« ni podprt." + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Neveljaven podpis GVariant" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "Podatki JSON so prazni" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: napaka razčlenjevanje: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "Podatki JSON morajo biti kodirani v naboru UTF-8" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Le eno korensko vozlišče je dovoljeno v izrazu JSONPath" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Korensko vozlišče se konča z neveljavnim znakom »%c«" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Manjka ime člana ali pa nadomestni znak po znaku . (pika)" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Napačno oblikovan izraz rezine »%*s«" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Neveljavno določilo »%*s«" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Neveljavno določilo rezine »%*s«" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Neveljavno določilo kazala polja »%*s«" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Neveljaven prvi znak »%c«" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Trenutno vozlišče je vrste »%s«, pričakovano pa je polje ali predmet." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Kazalo »%d« je večje od velikosti polja na trenutnem položaju." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Kazalo »%d« je večje od velikosti predmeta na trenutnem položaju." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Na trenutnem položaju ni razpoložljivega vozlišča." + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Trenutni položaj vsebuje »%s« in ne polja" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Trenutno vozlišče je vrste »%s«, pričakovan pa je predmet." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Določilo »%s« ni določan v predmetu na trenutnem položaju." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Trenutni položaj vsebuje »%s« in ne predmeta" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Trenutni položaj vsebuje »%s« in ne vrednosti" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Trenutni položaj ne vsebuje niza" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "Trenutni položaj ne vsebuje celega števila" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "Trenutni položaj ne vsebuje plavajoče vejice" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "Trenutni položaj ne vsebuje logične izraza" diff --git a/po/sr.po b/po/sr.po new file mode 100644 index 0000000..9e3fc26 --- /dev/null +++ b/po/sr.po @@ -0,0 +1,289 @@ +# Serbian translation for json-glib. +# Copyright © 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Мирослав Николић , 2011—2017. +msgid "" +msgstr "" +"Project-Id-Version: json-glib json-glib-0-14\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-08-15 06:45+0200\n" +"Last-Translator: Мирослав Николић \n" +"Language-Team: српски \n" +"Language: sr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " +"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Project-Style: gnome\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Излаз улепшавања" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Размаци за увлачење" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: грешка отварања датотеке: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: грешка обраде датотеке: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: грешка писања на стандардни излаз" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: грешка затварања: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "ДАТОТЕКА" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Обликујте ЈСОН датотеке." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "„json-glib-format“ обликује ЈСОН изворишта." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Грешка обраде опција линије наредби: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Пробајте „%s --help“ за више података." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: недостају датотеке" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Потврдите ЈСОН датотеке." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "„json-glib-validate“ потврђује ЈСОН податке и дату путању." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Очекујем ЈСОН објекат, али корени чвор је врсте „%s“" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Неочекивана врста „%s“ у ЈСОН чвору" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Недостају елементи у ЈСОН низу да би био у складу са n-торком" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Недостаје симбол затварања „)“ у врсти n-торке Гваријанта" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Неочекивани додатни елементи у ЈСОН низу" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Неисправна вредност ниске претварајући у Гваријант" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "Унос речника Гваријанта очекује ЈСОН објекат са тачно једним чланом" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "Разред Гваријанта „%c“ није подржан" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Неисправан потпис Гваријанта" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "ЈСОН подаци су празни" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Грешка обраде: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "ЈСОН подаци морају бити у УТФ-8 кодирању" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Само један корени чвор је допуштен у изразу ЈСОНПутање" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "За кореним чвором следи неисправан знак „%c“" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Недостаје назив члана или џокер након знака тачке (.)" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Неисправан израз исечка „%*s“" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Неисправна одредница скупа „%*s“" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Неисправна одредница исечка „%*s“" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Неисправна одредница регистра низа „%*s“" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Неисправан први знак „%c“" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Тренутни чвор је врсте „%s“, али је очекиван низ или објекат." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Регистар „%d“ је већи од величине низа на тренутном положају." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Регистар „%d“ је већи од величине објекта на тренутном положају." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Ниједан чвор није доступан на тренутном положају" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "Тренутни положај садржи „%s“ а не низ" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Тренутни чвор је врсте „%s“, али је очекиван објекат." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Члан „%s“ није одређен у објекту на тренутном положају." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "Тренутни положај садржи „%s“ а не објекат" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "Тренутни положај садржи „%s“ а не вредност" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Тренутни положај не садржи врсту ниске" diff --git a/po/sr@latin.po b/po/sr@latin.po new file mode 100644 index 0000000..eca40ef --- /dev/null +++ b/po/sr@latin.po @@ -0,0 +1,289 @@ +# Serbian translation for json-glib. +# Copyright © 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Miroslav Nikolić , 2011—2017. +msgid "" +msgstr "" +"Project-Id-Version: json-glib json-glib-0-14\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-08-15 06:45+0200\n" +"Last-Translator: Miroslav Nikolić \n" +"Language-Team: srpski \n" +"Language: sr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : " +"n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Project-Style: gnome\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Izlaz ulepšavanja" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Razmaci za uvlačenje" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: greška otvaranja datoteke: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: greška obrade datoteke: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: greška pisanja na standardni izlaz" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: greška zatvaranja: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "DATOTEKA" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Oblikujte JSON datoteke." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "„json-glib-format“ oblikuje JSON izvorišta." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Greška obrade opcija linije naredbi: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Probajte „%s --help“ za više podataka." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: nedostaju datoteke" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Potvrdite JSON datoteke." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "„json-glib-validate“ potvrđuje JSON podatke i datu putanju." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Očekujem JSON objekat, ali koreni čvor je vrste „%s“" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "Neočekivana vrsta „%s“ u JSON čvoru" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Nedostaju elementi u JSON nizu da bi bio u skladu sa n-torkom" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Nedostaje simbol zatvaranja „)“ u vrsti n-torke Gvarijanta" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Neočekivani dodatni elementi u JSON nizu" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Neispravna vrednost niske pretvarajući u Gvarijant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "Unos rečnika Gvarijanta očekuje JSON objekat sa tačno jednim članom" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "Razred Gvarijanta „%c“ nije podržan" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Neispravan potpis Gvarijanta" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON podaci su prazni" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Greška obrade: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON podaci moraju biti u UTF-8 kodiranju" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Samo jedan koreni čvor je dopušten u izrazu JSONPutanje" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Za korenim čvorom sledi neispravan znak „%c“" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Nedostaje naziv člana ili džoker nakon znaka tačke (.)" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Neispravan izraz isečka „%*s“" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Neispravna odrednica skupa „%*s“" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Neispravna odrednica isečka „%*s“" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Neispravna odrednica registra niza „%*s“" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Neispravan prvi znak „%c“" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Trenutni čvor je vrste „%s“, ali je očekivan niz ili objekat." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "Registar „%d“ je veći od veličine niza na trenutnom položaju." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "Registar „%d“ je veći od veličine objekta na trenutnom položaju." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Nijedan čvor nije dostupan na trenutnom položaju" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "Trenutni položaj sadrži „%s“ a ne niz" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Trenutni čvor je vrste „%s“, ali je očekivan objekat." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Član „%s“ nije određen u objektu na trenutnom položaju." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "Trenutni položaj sadrži „%s“ a ne objekat" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "Trenutni položaj sadrži „%s“ a ne vrednost" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Trenutni položaj ne sadrži vrstu niske" diff --git a/po/sv.po b/po/sv.po new file mode 100644 index 0000000..dbd127e --- /dev/null +++ b/po/sv.po @@ -0,0 +1,271 @@ +# Swedish translation for json-glib. +# Copyright © 2012-2017 Free Software Foundation, Inc. +# This file is distributed under the same license as the json-glib package. +# Daniel Nylander , 2012. +# Sebastian Rasmussen , 2014. +# Anders Jonsson , 2015, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-03-18 16:05+0000\n" +"PO-Revision-Date: 2017-04-24 18:28+0200\n" +"Last-Translator: Anders Jonsson \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 1.8.11\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Snygga till utmatning" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Indenteringsblanksteg" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: misslyckades att öppna fil: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: misslyckades att tolka fil: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: misslyckades att skriva till stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: misslyckades att stänga: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "FIL" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "Formatera JSON-filer." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format formaterar JSON-resurser." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Misslyckades att tolka kommandoradsflaggor: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "Prova ”%s --help” för mer information." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: saknar fil" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Validera JSON-filer." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate validerar JSON-data vid den givna URI:n." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Förväntar sig ett JSON-objekt, men rotnoden är av typen ”%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "Oväntad typ ”%s” i JSON-nod" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Saknar element i JSON-vektor för att överensstämma med en tupel" + +#: json-glib/json-gvariant.c:621 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "Saknar avslutande symbol ”)” i GVariant-tupeltypen" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Oväntade extra-element i JSON-vektor" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Ogiltig strängvärdeskonvertering till GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"En post i en GVariant-ordbok förväntar sig ett JSON-objekt med exakt en " +"medlem" + +#: json-glib/json-gvariant.c:1248 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "GVariant-klassen ”%c” stöds inte" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Ogiltig GVariant-signatur" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON-datan är tom" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Tolkningsfel: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON-data måste vara UTF-8-kodad" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Bara en rotnod är tillåten i ett JSONPath-uttryck" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "Rotnod efterföljd av otillåtet tecken ”%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Saknar medlemsnamn eller jokertecken efter .-tecken" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "Missbildat skivuttryck ”%*s”" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "Ogiltig mängddefinition ”%*s”" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "Ogiltig skivdefinition ”%*s”" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "Ogiltig vektorindexdefinition ”%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "Ogiltigt första tecken ”%c”" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "" +"Aktuell nod är av typen ”%s”, men en vektor eller ett objekt förväntades." + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "" +"Indexet ”%d” är större än storleken på vektorn på den aktuella positionen." + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "" +"Indexet ”%d” är större än storleken på objektet på den aktuella positionen." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Ingen nod tillgänglig på aktuell position" + +#: json-glib/json-reader.c:594 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "Aktuell position innehåller en ”%s” och inte en vektor" + +#: json-glib/json-reader.c:670 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Aktuell nod är av typen ”%s”, men ett objekt förväntades." + +#: json-glib/json-reader.c:677 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "Medlemmen ”%s” är inte definierad i objektet på aktuell position." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "Aktuell position innehåller en ”%s” och inte ett objekt" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "Aktuell position innehåller en ”%s” och inte ett värde" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Aktuell position innehåller inte en strängtyp" diff --git a/po/te.po b/po/te.po new file mode 100644 index 0000000..e13e3c7 --- /dev/null +++ b/po/te.po @@ -0,0 +1,158 @@ +# Telugu translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# Copyright (C) 2012, Swecha Localisation Team +# This file is distributed under the same license as the json-glib package. +# +# sasi , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2012-09-27 05:54+0000\n" +"PO-Revision-Date: 2012-10-09 16:48+0530\n" +"Last-Translator: sasi \n" +"Language-Team: telugu \n" +"Language: te\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n!=1);\n" +"X-Generator: Gtranslator 2.91.5\n" + +#: ../json-glib/json-gobject.c:934 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "ఒక JSON అంశంకు అవకాశం ఉంది, కానీ రూట్ నోడ్`% s' రకంగా ఉంటుంది " + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "ఊహించని రకం '% s' JSON నోడ్ లో" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "ఒక క్రమానుగుణ శ్రేణి కోసం JSON శ్రేణిలో తప్పిన అంశాలు " + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "GVariant tuple రకంలో ముగింపు చిహ్నం ')' లేదు" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON శ్రేణి లో ఊహించని అదనపు అంశాలు " + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant మారిన చెల్లని స్ట్రింగ్ విలువ " + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "ఒక GVariant నిఘంటువు ఎంట్రీ సరిగ్గా ఒక సభ్యుడుగా ఉంటుందని ఒక JSON అంశం అంచనా " + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant తరగతి '%c'మద్దతు లేదు" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "చెల్లని GVariant సంతకం" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "JSON డేటా ఖాళీగా ఉంది" + +#: ../json-glib/json-parser.c:818 +#, c-format +msgid "%s:%d: Parse error: %s" +msgstr "% s:% d: అన్వయ దోషం:% s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "కేవలం ఒక రూట్ నోడ్కు ఒక JSONPath వ్యక్తీకరణ లో అనుమతి ఉంది" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "చెల్లని అక్షరం '%c' తర్వాత రూట్ నోడ్" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "తప్పుడు ముక్క వ్యక్తీకరణ '%*s'" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "చెల్లని వరు నిర్వచనం '%*s'" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "చెల్లని ముక్క నిర్వచనం '%*s'" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "చెల్లని వరు సూచిక నిర్వచనం '%*s'" + +#: ../json-glib/json-reader.c:463 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "ప్రస్తుత నోడ్ రకం '%s' యొక్క, కానీ ఒక విన్యాసం లేదా ఒక వస్తువు భావించారు." + +#: ../json-glib/json-reader.c:475 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "ఇండెక్స్ '%d' ప్రస్తుత స్థితి వద్ద శ్రేణి యొక్క పరిమాణం కంటే ఎక్కువగా ఉంటుంది." + +#: ../json-glib/json-reader.c:492 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "ఇండెక్స్ '%d' ప్రస్తుత స్థితి వద్ద వస్తువు యొక్క పరిమాణం కంటే ఎక్కువగా ఉంటుంది." + +#: ../json-glib/json-reader.c:576 ../json-glib/json-reader.c:729 +#: ../json-glib/json-reader.c:780 ../json-glib/json-reader.c:818 +#: ../json-glib/json-reader.c:856 ../json-glib/json-reader.c:894 +#: ../json-glib/json-reader.c:932 ../json-glib/json-reader.c:977 +#: ../json-glib/json-reader.c:1013 ../json-glib/json-reader.c:1039 +msgid "No node available at the current position" +msgstr "ప్రస్తుత స్థానంలో అందుబాటులో లేదు నోడ్ " + +#: ../json-glib/json-reader.c:583 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "ప్రస్తుత స్థితి ఒక '%s'కలిగి ఉంది మరియు వరుస కాదు " + +#: ../json-glib/json-reader.c:646 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "ప్రస్తుత నోడ్ '%s' యొక్క రకం, కానీ ఒక వస్తువుని భావించారు." + +#: ../json-glib/json-reader.c:653 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "సభ్యుడు '%s', ప్రస్తుత స్థితి వద్ద అంశం వివరించబడలేదు." + +#: ../json-glib/json-reader.c:736 ../json-glib/json-reader.c:787 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "ప్రస్తుత స్థితి ఒక '%s' కలిగి ఉంది మరియు ఒక వస్తువు కాదు " + +#: ../json-glib/json-reader.c:827 ../json-glib/json-reader.c:865 +#: ../json-glib/json-reader.c:903 ../json-glib/json-reader.c:941 +#: ../json-glib/json-reader.c:986 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "ప్రస్తుత స్థితి ఒక '%s'కలిగి ఉంది మరియు ఒక విలువ కాదు " + +#: ../json-glib/json-reader.c:949 +msgid "The current position does not hold a string type" +msgstr "ప్రస్తుత స్థితి పదాల రకం కలిగి లేదు" diff --git a/po/tg.po b/po/tg.po new file mode 100644 index 0000000..3b3246d --- /dev/null +++ b/po/tg.po @@ -0,0 +1,260 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Victor Ibragimov , 2013. +# +msgid "" +msgstr "" +"Project-Id-Version: Tajik Gnome\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-12-19 14:30+0000\n" +"PO-Revision-Date: 2013-12-20 14:32+0500\n" +"Last-Translator: Victor Ibragimov \n" +"Language-Team: \n" +"Language: tg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.6.3\n" + +#: ../json-glib/json-glib-format.c:41 +msgid "Prettify output" +msgstr "Ҳамворкунии барориш" + +#: ../json-glib/json-glib-format.c:42 +msgid "Indentation spaces" +msgstr "Фазоҳои фосилагузорӣ" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:68 ../json-glib/json-glib-validate.c:61 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: хатои кушодани файли: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:80 ../json-glib/json-glib-validate.c:73 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: хатои таҷзияи файли: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: ../json-glib/json-glib-format.c:99 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: хатои сабт ба stdout" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:119 ../json-glib/json-glib-validate.c:85 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: хатои пӯшидани: %s\n" + +#: ../json-glib/json-glib-format.c:148 ../json-glib/json-glib-validate.c:113 +msgid "FILE" +msgstr "ФАЙЛ" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-format.c:151 +msgid "Format JSON files." +msgstr "Формати файли JSON." + +#: ../json-glib/json-glib-format.c:152 +msgid "json-glib-format formats JSON resources." +msgstr "Формати json-glib-format манбаҳои JSON-ро формат мекунад." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:169 ../json-glib/json-glib-validate.c:134 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Хатои таҷзияи имконоти хати фармонӣ: %s\n" + +#: ../json-glib/json-glib-format.c:171 ../json-glib/json-glib-format.c:185 +#: ../json-glib/json-glib-validate.c:136 ../json-glib/json-glib-validate.c:150 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Барои иттилооти бештар фармони \"%s --help\"-ро иҷро намоед." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:183 ../json-glib/json-glib-validate.c:148 +#, c-format +msgid "%s: missing files" +msgstr "%s: дорои файлҳои намерасидагӣ мебошад" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-validate.c:116 +msgid "Validate JSON files." +msgstr "Санҷидани эътибори файли JSON." + +#: ../json-glib/json-glib-validate.c:117 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "" +"Қимати json-glib-validate иттилооти JSON-ро дар суроғаи URI додашуда тафтиш " +"мекунад." + +#: ../json-glib/json-gobject.c:917 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "" +"Дар ҳоли мунтазири объекти JSON, вале гиреҳи root дорои намуди `%s' мебошад" + +#: ../json-glib/json-gvariant.c:545 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Навъи пешбининашудаи '%s' дар гиреҳи JSON" + +#: ../json-glib/json-gvariant.c:615 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Унсурҳои ғоиб дар қатори JSON барои мутобиқат ба чандтогӣ" + +#: ../json-glib/json-gvariant.c:643 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Аломати пӯшонидани ')' ғоиб дар навъи чандтогии GVariant" + +#: ../json-glib/json-gvariant.c:651 +msgid "Unexpected extra elements in JSON array" +msgstr "Унсурҳои иловагии пешбининашуда дар қатори JSON" + +#: ../json-glib/json-gvariant.c:930 +msgid "Invalid string value converting to GVariant" +msgstr "Қимати табдилдиҳии сатр ба GVariant нодуруст аст" + +#: ../json-glib/json-gvariant.c:986 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Вуруди луғати GVariant дар ҳоли мунтазири объекти JSON бо як рақам мебошад" + +#: ../json-glib/json-gvariant.c:1266 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "Синфи GVariant-и '%c' дастгирӣ намешавад" + +#: ../json-glib/json-gvariant.c:1314 +msgid "Invalid GVariant signature" +msgstr "Имзои нодурусти GVariant" + +#: ../json-glib/json-gvariant.c:1362 +msgid "JSON data is empty" +msgstr "Иттилооти JSON холӣ аст" + +#: ../json-glib/json-parser.c:817 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Хатои таҷзия: %s" + +#: ../json-glib/json-parser.c:885 +msgid "JSON data must be UTF-8 encoded" +msgstr "Иттилооти JSON бояд ба формати UTF-8 рамзгузорӣ шавад" + +#: ../json-glib/json-path.c:438 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Танҳо як гиреҳи решагӣ дар ифодаи JSONPath иҷозат дода шудааст" + +#: ../json-glib/json-path.c:447 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Гиреҳи решагӣ, ки бо аломати беэътибори '%c' пайгирӣ шуд" + +#: ../json-glib/json-path.c:487 +msgid "Missing member name or wildcard after . character" +msgstr "Баъд аз аломати \".\" номи узв ё номи алоқаманд вуҷуд надорад" + +#: ../json-glib/json-path.c:561 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Ифодаи бадшакл: '%*s'" + +#: ../json-glib/json-path.c:605 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Таърифи маҷмӯи \"%*s\" беэътибор аст" + +#: ../json-glib/json-path.c:658 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Таърифи нодуруст: '%*s'" + +#: ../json-glib/json-path.c:686 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Таърифи индекси қатори \"%*s\" беэътибор аст" + +#: ../json-glib/json-path.c:705 +#, c-format +msgid "Invalid first character '%c'" +msgstr "Аломати аввалини нодуруст: '%c'" + +#: ../json-glib/json-reader.c:457 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "Гиреҳи ҷорӣ аз навъи '%s' аст, вале қатор ё объект пешбинӣ шуда буд." + +#: ../json-glib/json-reader.c:469 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "Индекси '%d' калонтар аз андозаи қатор дар вазъияти ҷорӣ мебошад." + +#: ../json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "Индекси '%d' калонтар аз андозаи объект дар вазъияти ҷорӣ аст." + +#: ../json-glib/json-reader.c:570 ../json-glib/json-reader.c:723 +#: ../json-glib/json-reader.c:774 ../json-glib/json-reader.c:812 +#: ../json-glib/json-reader.c:850 ../json-glib/json-reader.c:888 +#: ../json-glib/json-reader.c:926 ../json-glib/json-reader.c:971 +#: ../json-glib/json-reader.c:1007 ../json-glib/json-reader.c:1033 +msgid "No node available at the current position" +msgstr "Ҳеҷ гуна гиреҳ дар вазъияти ҷорӣ дастрас нест" + +#: ../json-glib/json-reader.c:577 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "Вазъияти ҷорӣ '%s'-ро нигаҳдорӣ мекунад, на қаторро" + +#: ../json-glib/json-reader.c:640 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "Гиреҳи ҷорӣ аз навъи '%s' аст, вале объект пешбинӣ шудааст." + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "Дар вазъияти ҷорӣ аъзои '%s' дар объект муайян нашудааст." + +#: ../json-glib/json-reader.c:730 ../json-glib/json-reader.c:781 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "Вазъияти ҷорӣ '%s'-ро нигаҳдорӣ мекунад, на объектро" + +#: ../json-glib/json-reader.c:821 ../json-glib/json-reader.c:859 +#: ../json-glib/json-reader.c:897 ../json-glib/json-reader.c:935 +#: ../json-glib/json-reader.c:980 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "Вазъияти ҷорӣ '%s'-ро нигаҳдорӣ мекунад, на қиматро" + +#: ../json-glib/json-reader.c:943 +msgid "The current position does not hold a string type" +msgstr "Ҷойгиршавии ҷорӣ ягон намуди сатрро дар бар намегирад" diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 0000000..c7fb61b --- /dev/null +++ b/po/tr.po @@ -0,0 +1,301 @@ +# Turkish translation for json-glib. +# Copyright (C) 2011 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# +# Yaşar Şentürk , 2014. +# Muhammet Kara , 2011, 2014, 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2017-06-27 22:31+0000\n" +"PO-Revision-Date: 2017-09-09 10:05+0300\n" +"Last-Translator: Muhammet Kara \n" +"Language-Team: Türkçe \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Gtranslator 2.91.7\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Çıktıyı güzelleştir" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Girinti boşluğu" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: dosyayı açarken hata: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: dosyayı ayrıştırırken hata: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: stdout'a yazarken hata" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: kapatma hatası: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "DOSYA" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "JSON dosyalarını biçimle." + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format, JSON verilerini biçimlendirir." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Komut satırı seçeneklerini ayrıştırırken hata: %s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +#| msgid "Try \"%s --help\" for more information." +msgid "Try “%s --help” for more information." +msgstr "Daha fazla bilgi için “%s --help” komutunu girin." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: dosyalar eksik" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "JSON dosyalarını doğrula." + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate verilen URI'deki JSON verisini doğrular." + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:943 +#, c-format +#| msgid "Expecting a JSON object, but the root node is of type `%s'" +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "Bir JSON nesnesi bekleniyor, ama kök düğümü “%s” türünde" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:523 +#, c-format +#| msgid "Unexpected type '%s' in JSON node" +msgid "Unexpected type “%s” in JSON node" +msgstr "JSON düğümünde beklenmeyen “%s” türü" + +#: json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "JSON dizisinin bir demete uyması için gereken öğeler eksik" + +#: json-glib/json-gvariant.c:621 +#| msgid "Missing closing symbol ')' in the GVariant tuple type" +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "GVariant demeti türünde kapatma sembolü “)” eksik" + +#: json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON dizisinde beklenmeyen ek öğeler" + +#: json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "GVariant'a dönüştürmede geçersiz dizge değeri" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "" +"Bir GVariant sözlük girdisi, tam olarak bir üyesi olan JSON nesnesi bekler" + +#: json-glib/json-gvariant.c:1248 +#, c-format +#| msgid "GVariant class '%c' not supported" +msgid "GVariant class “%c” not supported" +msgstr "GVariant sınıfı “%c” desteklenmiyor" + +#: json-glib/json-gvariant.c:1296 +msgid "Invalid GVariant signature" +msgstr "Geçersiz GVariant imzası" + +#: json-glib/json-gvariant.c:1344 +msgid "JSON data is empty" +msgstr "JSON verisi boş" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: Ayrıştırma hatası: %s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON verisi UTF-8 ile kodlanmış olmalıdır" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath ifadesinde yalnızca bir kök düğümüne izin verilir" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +#| msgid "Root node followed by invalid character '%c'" +msgid "Root node followed by invalid character “%c”" +msgstr "Kök düğümünü izleyen “%c” karakteri geçersiz" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "Öge ismi ya da . karakterinden sonraki joker karakter eksik" + +#: json-glib/json-path.c:512 +#, c-format +#| msgid "Malformed slice expression '%*s'" +msgid "Malformed slice expression “%*s”" +msgstr "Kusurlu dilim ifadesi “%*s”" + +#: json-glib/json-path.c:556 +#, c-format +#| msgid "Invalid set definition '%*s'" +msgid "Invalid set definition “%*s”" +msgstr "Geçersiz küme tanımı “%*s”" + +#: json-glib/json-path.c:609 +#, c-format +#| msgid "Invalid slice definition '%*s'" +msgid "Invalid slice definition “%*s”" +msgstr "Geçersiz dilim tanımı “%*s”" + +#: json-glib/json-path.c:637 +#, c-format +#| msgid "Invalid array index definition '%*s'" +msgid "Invalid array index definition “%*s”" +msgstr "Geçersiz dizi indisi tanımı “%*s”" + +#: json-glib/json-path.c:656 +#, c-format +#| msgid "Invalid first character '%c'" +msgid "Invalid first character “%c”" +msgstr "Geçersiz ilk karakter “%c”" + +#: json-glib/json-reader.c:474 +#, c-format +#| msgid "" +#| "The current node is of type '%s', but an array or an object was expected." +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "Geçerli düğümün türü “%s”, ama bir dizi ya da bir nesne bekleniyordu." + +#: json-glib/json-reader.c:486 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the array at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "“%d” indisi, geçerli konumdaki dizinin boyutundan daha büyük." + +#: json-glib/json-reader.c:503 +#, c-format +#| msgid "" +#| "The index '%d' is greater than the size of the object at the current " +#| "position." +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "“%d” indisi, geçerli konumdaki nesnenin boyutundan daha büyük." + +#: json-glib/json-reader.c:587 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:802 json-glib/json-reader.c:840 +#: json-glib/json-reader.c:878 json-glib/json-reader.c:916 +#: json-glib/json-reader.c:954 json-glib/json-reader.c:999 +#: json-glib/json-reader.c:1035 json-glib/json-reader.c:1061 +msgid "No node available at the current position" +msgstr "Geçerli konumda kullanılabilir düğüm yok" + +#: json-glib/json-reader.c:594 +#, c-format +#| msgid "The current position holds a '%s' and not an array" +msgid "The current position holds a “%s” and not an array" +msgstr "Geçerli konum bir dizi değil “%s” bulunduruyor" + +#: json-glib/json-reader.c:670 +#, c-format +#| msgid "The current node is of type '%s', but an object was expected." +msgid "The current node is of type “%s”, but an object was expected." +msgstr "Geçerli düğümün türü “%s”, ama bir nesne bekleniyordu." + +#: json-glib/json-reader.c:677 +#, c-format +#| msgid "" +#| "The member '%s' is not defined in the object at the current position." +msgid "The member “%s” is not defined in the object at the current position." +msgstr "“%s” üyesi, geçerli konumdaki nesnede tanımlı değil." + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:809 +#, c-format +#| msgid "The current position holds a '%s' and not an object" +msgid "The current position holds a “%s” and not an object" +msgstr "Geçerli konum bir nesne değil “%s” bulunduruyor" + +#: json-glib/json-reader.c:849 json-glib/json-reader.c:887 +#: json-glib/json-reader.c:925 json-glib/json-reader.c:963 +#: json-glib/json-reader.c:1008 +#, c-format +#| msgid "The current position holds a '%s' and not a value" +msgid "The current position holds a “%s” and not a value" +msgstr "Geçerli konum bir değer değil “%s” bulunduruyor" + +#: json-glib/json-reader.c:971 +msgid "The current position does not hold a string type" +msgstr "Geçerli konum bir dizge türü bulundurmuyor" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "Geçerli konum bir tamsayı türü bulundurmuyor" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "Geçerli konum bir kayan noktalı tür bulundurmuyor" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "Geçerli konum bir mantıksal doğru/yanlış türü bulundurmuyor" diff --git a/po/ug.po b/po/ug.po new file mode 100644 index 0000000..2370d38 --- /dev/null +++ b/po/ug.po @@ -0,0 +1,153 @@ +# Uyghur translation for json-glib. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Gheyret Kenji , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-01-20 02:49+0000\n" +"PO-Revision-Date: 2013-01-26 09:43+0900\n" +"Last-Translator: Gheyret Kenji \n" +"Language-Team: Uyghur Computer Science Association \n" +"Language: ug\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../json-glib/json-gobject.c:925 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "ئەسلى JSON نەڭى بولۇشقا تېگىشلىك ئىدى، بىراق غول تۈگۈننىڭ تىپى «%s» ئىكەن" + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "ھازىر JSON تۈگۈننىڭ تىپى ‹%s› بولۇپ قېلىپتۇ" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "" + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "ھازىر JSON تىزىقىدا ئارتۇقچە ئېلېمېنت بار ئىكەن" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "تېكىستنىڭ قىممىتىنى GVariant قا ئايلاندۇرغىلى بولمايدىكەن" + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "ئادەتتە GVariant لۇغەت ئېلېمېنتى چوقۇم بىرلا ئەزايى بار بولغان JSON نەڭى بولۇشى كېرەك" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant تىپ ‹%c› نى قوللىمايدۇ" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "ئىناۋەتسىز GVariant ئىمزاسى" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "JSON سانلىق-مەلۇماتى قۇرۇق" + +#: ../json-glib/json-parser.c:825 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: پارچىلاشتا خاتالىق كۆرۈلدى: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "ئادەتتە JSONPath ئىپادىسىدە پەقەت بىرلا غول ئېلېمېنتقا ئىجازەت بېرىلگەن" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "پەقەت بىرلا غول ئېلېمېنت كەينىدە ‹%c› دېگەن ھەرپ بار ئىكەن" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "بولمىغۇر كەسمە ئىپادىسى ‹%*s›" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "توپلام ئېنىقلىمىسى ئىناۋەتسىز ‹%*s›" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "كەسمە(slice) ئېنىقلىمىسى ئىناۋەتسىز ‹%*s›" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "تىزىق ئىندېكس ئېنىقلىمىسى ئىناۋەتسىز ‹%*s›" + +#: ../json-glib/json-reader.c:464 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "نۆۋەتتىكى تۈگۈننىڭ تىپى ‹%s›، بىراق بۇ يەرگە تىزىق ياكى بىر نەڭ كەلسە بولاتتى" + +#: ../json-glib/json-reader.c:476 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "ئىندېكس ‹%d› ، نۆۋەتتىكى ئورۇندىكى تىزىقنىڭ چوڭلۇقىدىن چوڭ." + +#: ../json-glib/json-reader.c:493 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "ئىندېكس ‹%d› ، نۆۋەتتىكى ئورۇندىكى نەڭنىڭ چوڭلۇقىدىن چوڭ." + +#: ../json-glib/json-reader.c:577 ../json-glib/json-reader.c:730 +#: ../json-glib/json-reader.c:781 ../json-glib/json-reader.c:819 +#: ../json-glib/json-reader.c:857 ../json-glib/json-reader.c:895 +#: ../json-glib/json-reader.c:933 ../json-glib/json-reader.c:978 +#: ../json-glib/json-reader.c:1014 ../json-glib/json-reader.c:1040 +msgid "No node available at the current position" +msgstr "نۆۋەتتىكى ئورۇندا تۈگۈن يوق" + +#: ../json-glib/json-reader.c:584 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "نۆۋەتتىكى ئورۇندىكىسى ‹%s› بولۇپ، تىزىق ئەمەس" + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "نۆۋەتتىكى ئورۇندىكى تۈگۈننىڭ تىپى ‹%s›، بىراق نەڭ كەلسە بولاتتى." + +#: ../json-glib/json-reader.c:654 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "نۆۋەتتىكى ئورۇندىكى نەڭدە ‹%s› دېگەن ئەزا ئېنىقلانمىغان." + +#: ../json-glib/json-reader.c:737 ../json-glib/json-reader.c:788 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "نۆۋەتتىكى ئورۇندىكىسى ‹%s› بولۇپ، نەڭ ئەمەس" + +#: ../json-glib/json-reader.c:828 ../json-glib/json-reader.c:866 +#: ../json-glib/json-reader.c:904 ../json-glib/json-reader.c:942 +#: ../json-glib/json-reader.c:987 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "نۆۋەتتىكى ئورۇندىكىسى ‹%s› بولۇپ، قىممەت ئەمەس" + +#: ../json-glib/json-reader.c:950 +msgid "The current position does not hold a string type" +msgstr "نۆۋەتتىكى ئورۇندىكىسىنىڭ تىپى تېكىست ئەمەس" diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 0000000..e7c9471 --- /dev/null +++ b/po/uk.po @@ -0,0 +1,269 @@ +# Ukrainian translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Daniel , 2012. +# Mykola Tkach , 2014. +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2014-03-30 09:48+0000\n" +"PO-Revision-Date: 2014-03-30 13:22+0300\n" +"Last-Translator: Mykola Tkach \n" +"Language-Team: translation@linux.org.ua\n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: Virtaal 0.7.0\n" +"X-Project-Style: gnome\n" + +#: ../json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Виводити у зручночитаній формі" + +#: ../json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "Відступи" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:77 +#: ../json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s: не вдалося відкрити файл: %s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:89 +#: ../json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s: не вдалося розібрати файл: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: ../json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s: не вдалося записати у стандартний вивід" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:128 +#: ../json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s: не вдалося закрити: %s\n" + +#: ../json-glib/json-glib-format.c:157 +#: ../json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "ФАЙЛ" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-format.c:160 +msgid "Format JSON files." +msgstr "Форматування файлів JSON." + +#: ../json-glib/json-glib-format.c:161 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format форматує ресурси JSON." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:178 +#: ../json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "Не вдалося розібрати параметри командного рядка: %s\n" + +#: ../json-glib/json-glib-format.c:180 +#: ../json-glib/json-glib-format.c:194 +#: ../json-glib/json-glib-validate.c:138 +#: ../json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "Використовуйте «%s --help» для отримання детальної інформації." + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:192 +#: ../json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s: відсутні файли" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "Перевірка коректності файлів JSON." + +#: ../json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate перевіряє коректність даних JSON за вказаним URI." + +#: ../json-glib/json-gobject.c:915 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Очікування об'єкту JSON, але кореневий вузол є типом «%s»" + +#: ../json-glib/json-gvariant.c:523 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Очікуваний тип «%s» у вузлі JSON" + +#: ../json-glib/json-gvariant.c:593 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Бракує елементів у масиві JSON для підтвердження кортежу" + +#: ../json-glib/json-gvariant.c:621 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Бракує символу закривання «)» у типі кортежу GVariant" + +#: ../json-glib/json-gvariant.c:629 +msgid "Unexpected extra elements in JSON array" +msgstr "Неочікуваний додатковий елемент у масиві JSON" + +#: ../json-glib/json-gvariant.c:908 +msgid "Invalid string value converting to GVariant" +msgstr "Неправильне перетворення значення рядка в GVariant" + +#: ../json-glib/json-gvariant.c:964 +msgid "A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "Запис словника GVariant очікує об'єкт JSON з лише однією частиною" + +#: ../json-glib/json-gvariant.c:1244 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "Клас GVariant «%c» не підтримується" + +#: ../json-glib/json-gvariant.c:1292 +msgid "Invalid GVariant signature" +msgstr "Неправильний підпис GVariant" + +#: ../json-glib/json-gvariant.c:1340 +msgid "JSON data is empty" +msgstr "Дані JSON порожні" + +#: ../json-glib/json-parser.c:815 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d: помилка розбору: %s" + +#: ../json-glib/json-parser.c:883 +msgid "JSON data must be UTF-8 encoded" +msgstr "Дані JSON повинні бути у кодуванні UTF-8" + +#: ../json-glib/json-path.c:388 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Дозволено тільки один кореневий вузол у виразі JSONPath" + +#: ../json-glib/json-path.c:397 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Кореневий вузол супроводжується неправильним символом «%c»" + +#: ../json-glib/json-path.c:437 +msgid "Missing member name or wildcard after . character" +msgstr "Відсутнє ім’я члена або шаблон після символу «.»" + +#: ../json-glib/json-path.c:511 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Неправильний вираз шару «%*s»" + +#: ../json-glib/json-path.c:555 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Неправильне визначення набору «%*s»" + +#: ../json-glib/json-path.c:608 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Неправильне визначення шару «%*s»" + +#: ../json-glib/json-path.c:636 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Неправильне визначення покажчика масиву «%*s»" + +#: ../json-glib/json-path.c:655 +#, c-format +msgid "Invalid first character '%c'" +msgstr "Неправильний перший символ «%c»" + +#: ../json-glib/json-reader.c:456 +#, c-format +msgid "The current node is of type '%s', but an array or an object was expected." +msgstr "Поточний вузол має тип «%s», однак масив або об'єкт не були очікуваними." + +#: ../json-glib/json-reader.c:468 +#, c-format +msgid "The index '%d' is greater than the size of the array at the current position." +msgstr "Покажчик «%d» більший за розмір масиву на поточній позиції." + +#: ../json-glib/json-reader.c:485 +#, c-format +msgid "The index '%d' is greater than the size of the object at the current position." +msgstr "Покажчик «%d» більший за розмір об'єкту на поточній позиції." + +#: ../json-glib/json-reader.c:570 +#: ../json-glib/json-reader.c:724 +#: ../json-glib/json-reader.c:775 +#: ../json-glib/json-reader.c:813 +#: ../json-glib/json-reader.c:851 +#: ../json-glib/json-reader.c:889 +#: ../json-glib/json-reader.c:927 +#: ../json-glib/json-reader.c:972 +#: ../json-glib/json-reader.c:1008 +#: ../json-glib/json-reader.c:1034 +msgid "No node available at the current position" +msgstr "Немає жодного доступного вузла на поточній позиції" + +#: ../json-glib/json-reader.c:577 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "Поточна позиція утримує «%s» і не є масивом" + +#: ../json-glib/json-reader.c:640 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "Поточний вузол має тип «%s», однак об'єкт не був очікуваними." + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "Частину «%s» не визначено в об'єкті на поточні позиції." + +#: ../json-glib/json-reader.c:731 +#: ../json-glib/json-reader.c:782 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "Поточна позиція утримує «%s» і не є об'єктом" + +#: ../json-glib/json-reader.c:822 +#: ../json-glib/json-reader.c:860 +#: ../json-glib/json-reader.c:898 +#: ../json-glib/json-reader.c:936 +#: ../json-glib/json-reader.c:981 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "Поточна позиція утримує «%s» і не є значенням" + +#: ../json-glib/json-reader.c:944 +msgid "The current position does not hold a string type" +msgstr "Поточна позиція не утримує тип рядка" + diff --git a/po/vi.po b/po/vi.po new file mode 100644 index 0000000..563d5a3 --- /dev/null +++ b/po/vi.po @@ -0,0 +1,167 @@ +# Vietnamese translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# Nguyễn Thái Ngọc Duy , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2012-06-21 21:05+0000\n" +"PO-Revision-Date: 2012-06-30 10:26+0700\n" +"Last-Translator: Nguyễn Thái Ngọc Duy \n" +"Language-Team: Vietnamese \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#: ../json-glib/json-gobject.c:934 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "Cần đối tượng JSON nhưng nút gốc thuộc loại '%s'" + +#: ../json-glib/json-gvariant.c:539 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "Cần loại '%s' trong nút JSON" + +#: ../json-glib/json-gvariant.c:609 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "Thiếu phần tử trong mảng JSON để tuân thủ ống" + +#: ../json-glib/json-gvariant.c:637 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "Thiếu dấu đóng ')' trong loại ống GVariant" + +#: ../json-glib/json-gvariant.c:645 +msgid "Unexpected extra elements in JSON array" +msgstr "Cần phần tử bổ sung trong mảng JSON" + +#: ../json-glib/json-gvariant.c:924 +msgid "Invalid string value converting to GVariant" +msgstr "Giá trị chuỗi chuyển đổi sang GVariant không hợp lệ" + +#: ../json-glib/json-gvariant.c:980 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "Mục từ điển GVariant cần đối tượng JSON với duy nhất một phần tử" + +#: ../json-glib/json-gvariant.c:1236 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "Không hỗ trợ lớp GVariant '%c'" + +#: ../json-glib/json-gvariant.c:1281 +msgid "Invalid GVariant signature" +msgstr "Chữ ký GVariant không hợp lệ" + +#: ../json-glib/json-gvariant.c:1326 +msgid "JSON data is empty" +msgstr "Dữ liệu JSON rỗng" + +#: ../json-glib/json-parser.c:818 +#, c-format +msgid "%s:%d: Parse error: %s" +msgstr "%s:%d: Lỗi phân tích: %s" + +#: ../json-glib/json-path.c:375 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "Chỉ cho phép duy nhất một nút gốc trong biểu thức JSONPath" + +#: ../json-glib/json-path.c:384 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "Ký tự không hợp lệ '%c' theo sau nút gốc" + +#: ../json-glib/json-path.c:490 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "Biểu thức chặt '%*s' hư" + +#: ../json-glib/json-path.c:534 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "Định nghĩa tập '%*s' không hợp lệ" + +#: ../json-glib/json-path.c:587 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "Định nghĩa chặt '%*s' không hợp lệ" + +#: ../json-glib/json-path.c:615 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "Định nghĩa chỉ mục mảng '%*s' không hợp lệ" + +#: ../json-glib/json-reader.c:463 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "Nút hiện thời loại '%s', nhưng đang cần mảng hoặc một đối tượng." + +#: ../json-glib/json-reader.c:475 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "Chỉ mục '%d' lớn hơn kích thước mảng tại vị trí hiện thời." + +#: ../json-glib/json-reader.c:492 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "Chỉ mục '%d' lớn hơn kích thước đối tượng tại vị trí hiện thời." + +#: ../json-glib/json-reader.c:576 ../json-glib/json-reader.c:729 +#: ../json-glib/json-reader.c:780 ../json-glib/json-reader.c:818 +#: ../json-glib/json-reader.c:856 ../json-glib/json-reader.c:901 +#: ../json-glib/json-reader.c:946 ../json-glib/json-reader.c:991 +#: ../json-glib/json-reader.c:1034 ../json-glib/json-reader.c:1060 +msgid "No node available at the current position" +msgstr "Không có nút ở vị trí hiện thời." + +#: ../json-glib/json-reader.c:583 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "" + +#: ../json-glib/json-reader.c:646 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "Nút hiện thời thuộc loại '%s', nhưng đang cần đối tượng." + +#: ../json-glib/json-reader.c:653 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "Chưa định nghĩa thành viên '%s' trong đối tượng tại vị trí hiện thời." + +#: ../json-glib/json-reader.c:736 ../json-glib/json-reader.c:787 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "Vị trí hiện thời chứa '%s', không phải đối tượng" + +#: ../json-glib/json-reader.c:827 ../json-glib/json-reader.c:865 +#: ../json-glib/json-reader.c:910 ../json-glib/json-reader.c:955 +#: ../json-glib/json-reader.c:1000 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "Vị trí hiện thời chứa '%s', không phải giá trị" + +#: ../json-glib/json-reader.c:873 +msgid "The current position does not hold an integer type" +msgstr "Vị trí hiện thời không phải kiểu số nguyên" + +#: ../json-glib/json-reader.c:918 +msgid "The current position does not hold a floating point type" +msgstr "Vị trí hiện thời không phải kiểu số thực" + +#: ../json-glib/json-reader.c:963 +msgid "The current position does not hold a string type" +msgstr "Vị trí hiện thời không phải kiểu chuỗi" + +#: ../json-glib/json-reader.c:1008 +msgid "The current position does not hold a boolean type" +msgstr "Vị trí hiện thời không phải kiểu luận lý" diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..f138a25 --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,276 @@ +# Chinese (China) translation for json-glib ui. +# Copyright (C) 2012 json-glib's authors and contributors. +# This file is distributed under the same license as the json-glib package. +# +# Cheng Lu , 2012. +# Wylmer Wang , 2012. +# Sphinx Jiang , 2014. +# Mingcong Bai , 2017. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/json-glib/issues\n" +"POT-Creation-Date: 2017-10-18 15:10+0000\n" +"PO-Revision-Date: 2017-06-10 14:29+0800\n" +"Last-Translator: Mingcong Bai \n" +"Language-Team: Chinese Simplified \n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Poedit 2.0.2\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "美化输出" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "缩进空格" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s: %s:打开文件出错:%s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s: %s:解析文件出错: %s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s: %s:写到标准输出出错" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s: %s:关闭出错: %s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "文件" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "格式化 JSON 文件。" + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format 可以格式化 JSON 资源。" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "解析命令行选项出错:%s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "请运行“%s --help”以了解更多信息。" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s:缺少文件" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "验证 JSON 文件" + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate 验证给定 URI 的 JSON 数据。" + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "期望一个 JSON 对象,但根节点类型是“%s”" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "JSON 节点中存在异常的类型“%s”" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "在 JSON 数组中缺少用来构成 tuple(元组) 的元素" + +#: json-glib/json-gvariant.c:622 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "在 GVariant 元组类型中缺少闭合符号“)”" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "在 JSON 数组中存在意外的其他元素" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "字符串值到 GVariant 的转换无效" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant 字典记录期望仅有一个成员的 JSON 对象" + +#: json-glib/json-gvariant.c:1242 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "不支持的 GVariant 类“%c”" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "无效的 GVariant 签名" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "JSON 数据为空" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:907 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d:解析错误:%s" + +#: json-glib/json-parser.c:990 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON 数据必须是 UTF-8 编码" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "JSONPath 表达式中只允许有一个根节点" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "根节点之后跟随了无效的字符“%c”" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "在字符 . 后面缺少成员名或通配符" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "有错误的 slice 表达式“%*s”" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "无效的 set 定义“%*s”" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "无效的 slice 定义“%*s”" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "无效的数组索引定义“%*s”" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "无效的首字符“%c”" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "当前节点的类型是“%s”,应为数组或对象。" + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "索引“%d”大于当前位置数组的大小。" + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "索引“%d”大于当前位置对象的大小。" + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "当前位置无节点可用" + +#: json-glib/json-reader.c:592 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "当前位置是一个“%s”,而不是一个数组" + +#: json-glib/json-reader.c:668 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "当前节点的类型是“%s”,但应为对象。" + +#: json-glib/json-reader.c:675 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "成员“%s”没有在当前位置的对象中定义。" + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "当前位置是一个“%s”,而不是一个对象" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "当前位置是一个“%s”,不是一个值" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "当前位置不是一个字符串类型" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "当前位置不是一个整数类型" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "当前位置不是一个浮点数类型" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "当前位置不是一个布尔(boolean)类型" diff --git a/po/zh_HK.po b/po/zh_HK.po new file mode 100644 index 0000000..8f6d79b --- /dev/null +++ b/po/zh_HK.po @@ -0,0 +1,265 @@ +# Chinese (Hong Kong) translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=json-" +"glib&keywords=I18N+L10N&component=general\n" +"POT-Creation-Date: 2013-12-19 14:30+0000\n" +"PO-Revision-Date: 2014-02-02 20:40+0800\n" +"Last-Translator: Chao-Hsiung Liao \n" +"Language-Team: Chinese (Hong Kong) \n" +"Language: zh_HK\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 1.6.3\n" + +#: ../json-glib/json-glib-format.c:41 +msgid "Prettify output" +msgstr "Prettify 輸出" + +#: ../json-glib/json-glib-format.c:42 +msgid "Indentation spaces" +msgstr "縮排空間" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:68 ../json-glib/json-glib-validate.c:61 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s:%s:開啟檔案時發生錯誤:%s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:80 ../json-glib/json-glib-validate.c:73 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s:%s:分析檔案時發生錯誤:%s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: ../json-glib/json-glib-format.c:99 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s:%s:寫入標準輸出時發生錯誤" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: ../json-glib/json-glib-format.c:119 ../json-glib/json-glib-validate.c:85 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s:%s:關閉時發生錯誤:%s\n" + +#: ../json-glib/json-glib-format.c:148 ../json-glib/json-glib-validate.c:113 +msgid "FILE" +msgstr "檔案" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-format.c:151 +msgid "Format JSON files." +msgstr "格式化 JSON 檔案。" + +#: ../json-glib/json-glib-format.c:152 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format 格式化 JSON 資源。" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:169 ../json-glib/json-glib-validate.c:134 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "分析命令列選項時發生錯誤:%s\n" + +#: ../json-glib/json-glib-format.c:171 ../json-glib/json-glib-format.c:185 +#: ../json-glib/json-glib-validate.c:136 ../json-glib/json-glib-validate.c:150 +#, c-format +msgid "Try \"%s --help\" for more information." +msgstr "嘗試「%s --help」以獲得更多資訊。" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: ../json-glib/json-glib-format.c:183 ../json-glib/json-glib-validate.c:148 +#, c-format +msgid "%s: missing files" +msgstr "%s:缺少檔案" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: ../json-glib/json-glib-validate.c:116 +msgid "Validate JSON files." +msgstr "驗證 JSON 檔案。" + +#: ../json-glib/json-glib-validate.c:117 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate 驗證指定 URI 的 JSON 資料。" + +#: ../json-glib/json-gobject.c:917 +#, c-format +msgid "Expecting a JSON object, but the root node is of type `%s'" +msgstr "預期是 JSON 物件,但根節點卻是類型「%s」" + +#: ../json-glib/json-gvariant.c:545 +#, c-format +msgid "Unexpected type '%s' in JSON node" +msgstr "JSON 節點中未預期的類型「%s」" + +#: ../json-glib/json-gvariant.c:615 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "在 JSON 陣列中缺少確認變數值組" + +#: ../json-glib/json-gvariant.c:643 +msgid "Missing closing symbol ')' in the GVariant tuple type" +msgstr "在 GVariant 變數值組類型中缺少關閉符號 ')'" + +#: ../json-glib/json-gvariant.c:651 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON 陣列中有未預期的額外元素" + +#: ../json-glib/json-gvariant.c:930 +msgid "Invalid string value converting to GVariant" +msgstr "無效的字串數值轉換到 GVariant" + +#: ../json-glib/json-gvariant.c:986 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant 字典項目預期 JSON 物件只能有一個成員" + +#: ../json-glib/json-gvariant.c:1266 +#, c-format +msgid "GVariant class '%c' not supported" +msgstr "GVariant 類別「%c」不支援" + +#: ../json-glib/json-gvariant.c:1314 +msgid "Invalid GVariant signature" +msgstr "無效的 GVariant 簽署" + +#: ../json-glib/json-gvariant.c:1362 +msgid "JSON data is empty" +msgstr "JSON 資料是空的" + +#: ../json-glib/json-parser.c:817 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d:解析錯誤:%s" + +#: ../json-glib/json-parser.c:885 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON 資料必須以 UTF-8 編碼" + +#: ../json-glib/json-path.c:438 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "在 JSONPath 表示式中不允許一個根節點" + +#: ../json-glib/json-path.c:447 +#, c-format +msgid "Root node followed by invalid character '%c'" +msgstr "根節點跟隨在無效的字符「%c」後" + +#: ../json-glib/json-path.c:487 +msgid "Missing member name or wildcard after . character" +msgstr "在 . 字符後缺少成員名稱或萬用字符" + +#: ../json-glib/json-path.c:561 +#, c-format +msgid "Malformed slice expression '%*s'" +msgstr "格式不良的片段表示式「%*s」" + +#: ../json-glib/json-path.c:605 +#, c-format +msgid "Invalid set definition '%*s'" +msgstr "無效的組定義「%*s」" + +#: ../json-glib/json-path.c:658 +#, c-format +msgid "Invalid slice definition '%*s'" +msgstr "無效的片段定義「%*s」" + +#: ../json-glib/json-path.c:686 +#, c-format +msgid "Invalid array index definition '%*s'" +msgstr "無效的陣列索引定義「%*s」" + +#: ../json-glib/json-path.c:705 +#, c-format +msgid "Invalid first character '%c'" +msgstr "無效的第一個字符「%c」" + +#: ../json-glib/json-reader.c:457 +#, c-format +msgid "" +"The current node is of type '%s', but an array or an object was expected." +msgstr "目前的節點類型是「%s」,但預期應為陣列或物件。" + +#: ../json-glib/json-reader.c:469 +#, c-format +msgid "" +"The index '%d' is greater than the size of the array at the current position." +msgstr "索引「%d」大於目前位置的陣列大小。" + +#: ../json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index '%d' is greater than the size of the object at the current " +"position." +msgstr "索引「%d」大於目前位置的物件大小。" + +#: ../json-glib/json-reader.c:570 ../json-glib/json-reader.c:723 +#: ../json-glib/json-reader.c:774 ../json-glib/json-reader.c:812 +#: ../json-glib/json-reader.c:850 ../json-glib/json-reader.c:888 +#: ../json-glib/json-reader.c:926 ../json-glib/json-reader.c:971 +#: ../json-glib/json-reader.c:1007 ../json-glib/json-reader.c:1033 +msgid "No node available at the current position" +msgstr "目前的位置沒有可用的節點" + +#: ../json-glib/json-reader.c:577 +#, c-format +msgid "The current position holds a '%s' and not an array" +msgstr "目前的位置持有一個「%s」,並非陣列" + +#: ../json-glib/json-reader.c:640 +#, c-format +msgid "The current node is of type '%s', but an object was expected." +msgstr "目前的節點類型是「%s」,但預期應為物件。" + +#: ../json-glib/json-reader.c:647 +#, c-format +msgid "The member '%s' is not defined in the object at the current position." +msgstr "成員「%s」並未在目前的位置的物件中定義。" + +#: ../json-glib/json-reader.c:730 ../json-glib/json-reader.c:781 +#, c-format +msgid "The current position holds a '%s' and not an object" +msgstr "目前的位置持有一個「%s」,並非物件" + +#: ../json-glib/json-reader.c:821 ../json-glib/json-reader.c:859 +#: ../json-glib/json-reader.c:897 ../json-glib/json-reader.c:935 +#: ../json-glib/json-reader.c:980 +#, c-format +msgid "The current position holds a '%s' and not a value" +msgstr "目前的位置持有一個「%s」,並非數值" + +#: ../json-glib/json-reader.c:943 +msgid "The current position does not hold a string type" +msgstr "目前的位置並未持有字串類型" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "目前的位置並未持有整數類型" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "目前的位置並未持有浮點數類型" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "目前的位置並未持有布林類型" diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100644 index 0000000..055d988 --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,271 @@ +# Chinese (Taiwan) translation for json-glib. +# Copyright (C) 2012 json-glib's COPYRIGHT HOLDER +# This file is distributed under the same license as the json-glib package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: json-glib master\n" +"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/json-glib/issues\n" +"POT-Creation-Date: 2018-02-21 01:40+0000\n" +"PO-Revision-Date: 2018-02-28 20:13+0800\n" +"Last-Translator: Chao-Hsiung Liao \n" +"Language-Team: Chinese (Taiwan) \n" +"Language: zh_TW\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.0.6\n" + +#: json-glib/json-glib-format.c:50 +msgid "Prettify output" +msgstr "Prettify 輸出" + +#: json-glib/json-glib-format.c:51 +msgid "Indentation spaces" +msgstr "縮排空間" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:77 json-glib/json-glib-validate.c:63 +#, c-format +msgid "%s: %s: error opening file: %s\n" +msgstr "%s:%s:開啟檔案時發生錯誤:%s\n" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:89 json-glib/json-glib-validate.c:75 +#, c-format +msgid "%s: %s: error parsing file: %s\n" +msgstr "%s:%s:分析檔案時發生錯誤:%s\n" + +#. Translators: the first %s is the program name, the +#. * second one is the URI of the file. +#. +#: json-glib/json-glib-format.c:108 +#, c-format +msgid "%s: %s: error writing to stdout" +msgstr "%s:%s:寫入標準輸出時發生錯誤" + +#. Translators: the first %s is the program name, the second one +#. * is the URI of the file, the third is the error message. +#. +#: json-glib/json-glib-format.c:129 json-glib/json-glib-validate.c:87 +#, c-format +msgid "%s: %s: error closing: %s\n" +msgstr "%s:%s:關閉時發生錯誤:%s\n" + +#: json-glib/json-glib-format.c:158 json-glib/json-glib-validate.c:115 +msgid "FILE" +msgstr "檔案" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-format.c:161 +msgid "Format JSON files." +msgstr "格式化 JSON 檔案。" + +#: json-glib/json-glib-format.c:162 +msgid "json-glib-format formats JSON resources." +msgstr "json-glib-format 格式化 JSON 資源。" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:179 json-glib/json-glib-validate.c:136 +#, c-format +msgid "Error parsing commandline options: %s\n" +msgstr "分析命令列選項時發生錯誤:%s\n" + +#: json-glib/json-glib-format.c:181 json-glib/json-glib-format.c:195 +#: json-glib/json-glib-validate.c:138 json-glib/json-glib-validate.c:152 +#, c-format +msgid "Try “%s --help” for more information." +msgstr "嘗試「%s --help」以獲得更多資訊。" + +#. Translators: the %s is the program name. This error message +#. * means the user is calling json-glib-validate without any +#. * argument. +#. +#: json-glib/json-glib-format.c:193 json-glib/json-glib-validate.c:150 +#, c-format +msgid "%s: missing files" +msgstr "%s:缺少檔案" + +#. Translators: this message will appear after the usage string +#. and before the list of options. +#: json-glib/json-glib-validate.c:118 +msgid "Validate JSON files." +msgstr "驗證 JSON 檔案。" + +#: json-glib/json-glib-validate.c:119 +msgid "json-glib-validate validates JSON data at the given URI." +msgstr "json-glib-validate 驗證指定 URI 的 JSON 資料。" + +#. translators: the %s is the name of the data structure +#: json-glib/json-gobject.c:940 +#, c-format +msgid "Expecting a JSON object, but the root node is of type “%s”" +msgstr "預期是 JSON 物件,但根節點卻是類型「%s」" + +#. translators: the '%s' is the type name +#: json-glib/json-gvariant.c:524 +#, c-format +msgid "Unexpected type “%s” in JSON node" +msgstr "JSON 節點中未預期的類型「%s」" + +#: json-glib/json-gvariant.c:594 +msgid "Missing elements in JSON array to conform to a tuple" +msgstr "在 JSON 陣列中缺少確認變數值組" + +#: json-glib/json-gvariant.c:622 +msgid "Missing closing symbol “)” in the GVariant tuple type" +msgstr "在 GVariant 變數值組類型中缺少關閉符號 ')'" + +#: json-glib/json-gvariant.c:630 +msgid "Unexpected extra elements in JSON array" +msgstr "JSON 陣列中有未預期的額外元素" + +#: json-glib/json-gvariant.c:909 +msgid "Invalid string value converting to GVariant" +msgstr "無效的字串數值轉換到 GVariant" + +#: json-glib/json-gvariant.c:964 +msgid "" +"A GVariant dictionary entry expects a JSON object with exactly one member" +msgstr "GVariant 字典項目預期 JSON 物件只能有一個成員" + +#: json-glib/json-gvariant.c:1242 +#, c-format +msgid "GVariant class “%c” not supported" +msgstr "GVariant 類別「%c」不支援" + +#: json-glib/json-gvariant.c:1290 +msgid "Invalid GVariant signature" +msgstr "無效的 GVariant 簽章" + +#: json-glib/json-gvariant.c:1338 +msgid "JSON data is empty" +msgstr "JSON 資料是空的" + +#. translators: %s: is the file name, the first %d is the line +#. * number, the second %d is the position on the line, and %s is +#. * the error message +#. +#: json-glib/json-parser.c:909 +#, c-format +msgid "%s:%d:%d: Parse error: %s" +msgstr "%s:%d:%d:解析錯誤:%s" + +#: json-glib/json-parser.c:992 +msgid "JSON data must be UTF-8 encoded" +msgstr "JSON 資料必須以 UTF-8 編碼" + +#: json-glib/json-path.c:389 +msgid "Only one root node is allowed in a JSONPath expression" +msgstr "在 JSONPath 表示式中不允許一個根節點" + +#. translators: the %c is the invalid character +#: json-glib/json-path.c:398 +#, c-format +msgid "Root node followed by invalid character “%c”" +msgstr "根節點跟隨在無效的字元「%c」後" + +#: json-glib/json-path.c:438 +msgid "Missing member name or wildcard after . character" +msgstr "在 . 字元後缺少成員名稱或萬用字元" + +#: json-glib/json-path.c:512 +#, c-format +msgid "Malformed slice expression “%*s”" +msgstr "格式不良的片段表示式「%*s」" + +#: json-glib/json-path.c:556 +#, c-format +msgid "Invalid set definition “%*s”" +msgstr "無效的組定義「%*s」" + +#: json-glib/json-path.c:609 +#, c-format +msgid "Invalid slice definition “%*s”" +msgstr "無效的片段定義「%*s」" + +#: json-glib/json-path.c:637 +#, c-format +msgid "Invalid array index definition “%*s”" +msgstr "無效的陣列索引定義「%*s」" + +#: json-glib/json-path.c:656 +#, c-format +msgid "Invalid first character “%c”" +msgstr "無效的第一個字元「%c」" + +#: json-glib/json-reader.c:474 +#, c-format +msgid "" +"The current node is of type “%s”, but an array or an object was expected." +msgstr "目前的節點類型是「%s」,但預期應為陣列或物件。" + +#: json-glib/json-reader.c:486 +#, c-format +msgid "" +"The index “%d” is greater than the size of the array at the current position." +msgstr "索引「%d」大於目前位置的陣列大小。" + +#: json-glib/json-reader.c:503 +#, c-format +msgid "" +"The index “%d” is greater than the size of the object at the current " +"position." +msgstr "索引「%d」大於目前位置的物件大小。" + +#: json-glib/json-reader.c:585 json-glib/json-reader.c:751 +#: json-glib/json-reader.c:799 json-glib/json-reader.c:837 +#: json-glib/json-reader.c:875 json-glib/json-reader.c:913 +#: json-glib/json-reader.c:951 json-glib/json-reader.c:996 +#: json-glib/json-reader.c:1032 json-glib/json-reader.c:1058 +msgid "No node available at the current position" +msgstr "目前的位置沒有可用的節點" + +#: json-glib/json-reader.c:592 +#, c-format +msgid "The current position holds a “%s” and not an array" +msgstr "目前的位置持有一個「%s」,並非陣列" + +#: json-glib/json-reader.c:668 +#, c-format +msgid "The current node is of type “%s”, but an object was expected." +msgstr "目前的節點類型是「%s」,但預期應為物件。" + +#: json-glib/json-reader.c:675 +#, c-format +msgid "The member “%s” is not defined in the object at the current position." +msgstr "成員「%s」並未在目前的位置的物件中定義。" + +#: json-glib/json-reader.c:758 json-glib/json-reader.c:806 +#, c-format +msgid "The current position holds a “%s” and not an object" +msgstr "目前的位置持有一個「%s」,並非物件" + +#: json-glib/json-reader.c:846 json-glib/json-reader.c:884 +#: json-glib/json-reader.c:922 json-glib/json-reader.c:960 +#: json-glib/json-reader.c:1005 +#, c-format +msgid "The current position holds a “%s” and not a value" +msgstr "目前的位置持有一個「%s」,並非數值" + +#: json-glib/json-reader.c:968 +msgid "The current position does not hold a string type" +msgstr "目前的位置並未持有字串類型" + +#~ msgid "The current position does not hold an integer type" +#~ msgstr "目前的位置並未持有整數類型" + +#~ msgid "The current position does not hold a floating point type" +#~ msgstr "目前的位置並未持有浮點數類型" + +#~ msgid "The current position does not hold a boolean type" +#~ msgstr "目前的位置並未持有布林類型"