d77a638ce5311db64efae84ab9b4e0aeed380003
[yaffs-website] / vendor / easyrdf / easyrdf / lib / EasyRdf / Serialiser / Ntriples.php
1 <?php
2
3 /**
4  * EasyRdf
5  *
6  * LICENSE
7  *
8  * Copyright (c) 2009-2013 Nicholas J Humfrey.  All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright notice,
15  *    this list of conditions and the following disclaimer in the documentation
16  *    and/or other materials provided with the distribution.
17  * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
18  *    promote products derived from this software without specific prior
19  *    written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * @package    EasyRdf
34  * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
35  * @license    http://www.opensource.org/licenses/bsd-license.php
36  */
37
38 /**
39  * Class to serialise an EasyRdf_Graph to N-Triples
40  * with no external dependancies.
41  *
42  * @package    EasyRdf
43  * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
44  * @license    http://www.opensource.org/licenses/bsd-license.php
45  */
46 class EasyRdf_Serialiser_Ntriples extends EasyRdf_Serialiser
47 {
48     private $escChars = array();   // Character encoding cache
49
50     /**
51      * @ignore
52      */
53     protected function escapeString($str)
54     {
55         if (strpos(utf8_decode(str_replace('?', '', $str)), '?') === false) {
56             $str = utf8_decode($str);
57         }
58
59         $result = '';
60         $strLen = strlen($str);
61         for ($i = 0; $i < $strLen; $i++) {
62             $c = $str[$i];
63             if (!isset($this->escChars[$c])) {
64                 $this->escChars[$c] = $this->escapedChar($c);
65             }
66             $result .= $this->escChars[$c];
67         }
68         return $result;
69     }
70
71     /**
72      * @ignore
73      */
74     protected function unicodeCharNo($c)
75     {
76         $cUtf = utf8_encode($c);
77         $bl = strlen($cUtf); /* binary length */
78         $r = 0;
79         switch ($bl) {
80             case 1: /* 0####### (0-127) */
81                 $r = ord($cUtf);
82                 break;
83             case 2: /* 110##### 10###### = 192+x 128+x */
84                 $r = ((ord($cUtf[0]) - 192) * 64) +
85                      (ord($cUtf[1]) - 128);
86                 break;
87             case 3: /* 1110#### 10###### 10###### = 224+x 128+x 128+x */
88                 $r = ((ord($cUtf[0]) - 224) * 4096) +
89                      ((ord($cUtf[1]) - 128) * 64) +
90                      (ord($cUtf[2]) - 128);
91                 break;
92             case 4: /* 1111#### 10###### 10###### 10###### = 240+x 128+x 128+x 128+x */
93                 $r = ((ord($cUtf[0]) - 240) * 262144) +
94                      ((ord($cUtf[1]) - 128) * 4096) +
95                      ((ord($cUtf[2]) - 128) * 64) +
96                      (ord($cUtf[3]) - 128);
97                 break;
98         }
99         return $r;
100     }
101
102     /**
103      * @ignore
104      */
105     protected function escapedChar($c)
106     {
107         $no = $this->unicodeCharNo($c);
108
109         /* see http://www.w3.org/TR/rdf-testcases/#ntrip_strings */
110         if ($no < 9) {
111             return "\\u" . sprintf('%04X', $no);  /* #x0-#x8 (0-8) */
112         } elseif ($no == 9) {
113             return '\t';                          /* #x9 (9) */
114         } elseif ($no == 10) {
115             return '\n';                          /* #xA (10) */
116         } elseif ($no < 13) {
117             return "\\u" . sprintf('%04X', $no);  /* #xB-#xC (11-12) */
118         } elseif ($no == 13) {
119             return '\r';                          /* #xD (13) */
120         } elseif ($no < 32) {
121             return "\\u" . sprintf('%04X', $no);  /* #xE-#x1F (14-31) */
122         } elseif ($no < 34) {
123             return $c;                            /* #x20-#x21 (32-33) */
124         } elseif ($no == 34) {
125             return '\"';                          /* #x22 (34) */
126         } elseif ($no < 92) {
127             return $c;                            /* #x23-#x5B (35-91) */
128         } elseif ($no == 92) {
129             return '\\';                          /* #x5C (92) */
130         } elseif ($no < 127) {
131             return $c;                            /* #x5D-#x7E (93-126) */
132         } elseif ($no < 65536) {
133             return "\\u" . sprintf('%04X', $no);  /* #x7F-#xFFFF (128-65535) */
134         } elseif ($no < 1114112) {
135             return "\\U" . sprintf('%08X', $no);  /* #x10000-#x10FFFF (65536-1114111) */
136         } else {
137             return '';                            /* not defined => ignore */
138         }
139     }
140
141     /**
142      * @ignore
143      */
144     protected function serialiseResource($res)
145     {
146         $escaped = $this->escapeString($res);
147         if (substr($res, 0, 2) == '_:') {
148             return $escaped;
149         } else {
150             return "<$escaped>";
151         }
152     }
153
154     /**
155      * Serialise an RDF value into N-Triples
156      *
157      * The value can either be an array in RDF/PHP form, or
158      * an EasyRdf_Literal or EasyRdf_Resource object.
159      *
160      * @param array|object  $value   An associative array or an object
161      * @throws EasyRdf_Exception
162      * @return string The RDF value serialised to N-Triples
163      */
164     public function serialiseValue($value)
165     {
166         if (is_object($value)) {
167             $value = $value->toRdfPhp();
168         }
169
170         if ($value['type'] == 'uri' or $value['type'] == 'bnode') {
171             return $this->serialiseResource($value['value']);
172         } elseif ($value['type'] == 'literal') {
173             $escaped = $this->escapeString($value['value']);
174             if (isset($value['lang'])) {
175                 $lang = $this->escapeString($value['lang']);
176                 return '"' . $escaped . '"' . '@' . $lang;
177             } elseif (isset($value['datatype'])) {
178                 $datatype = $this->escapeString($value['datatype']);
179                 return '"' . $escaped . '"' . "^^<$datatype>";
180             } else {
181                 return '"' . $escaped . '"';
182             }
183         } else {
184             throw new EasyRdf_Exception(
185                 "Unable to serialise object of type '".$value['type']."' to ntriples: "
186             );
187         }
188     }
189
190     /**
191      * Serialise an EasyRdf_Graph into N-Triples
192      *
193      * @param EasyRdf_Graph $graph   An EasyRdf_Graph object.
194      * @param string        $format  The name of the format to convert to.
195      * @param array         $options
196      * @throws EasyRdf_Exception
197      * @return string The RDF in the new desired format.
198      */
199     public function serialise($graph, $format, array $options = array())
200     {
201         parent::checkSerialiseParams($graph, $format);
202
203         if ($format == 'ntriples') {
204             $nt = '';
205             foreach ($graph->toRdfPhp() as $resource => $properties) {
206                 foreach ($properties as $property => $values) {
207                     foreach ($values as $value) {
208                         $nt .= $this->serialiseResource($resource)." ";
209                         $nt .= "<" . $this->escapeString($property) . "> ";
210                         $nt .= $this->serialiseValue($value)." .\n";
211                     }
212                 }
213             }
214             return $nt;
215         } else {
216             throw new EasyRdf_Exception(
217                 "EasyRdf_Serialiser_Ntriples does not support: $format"
218             );
219         }
220     }
221 }