]>
Commit | Line | Data |
---|---|---|
fb70f26e AD |
1 | <?php\r |
2 | /*\r | |
3 | * PHP QR Code encoder\r | |
4 | *\r | |
5 | * Input splitting classes\r | |
6 | *\r | |
7 | * Based on libqrencode C library distributed under LGPL 2.1\r | |
8 | * Copyright (C) 2006, 2007, 2008, 2009 Kentaro Fukuchi <fukuchi@megaui.net>\r | |
9 | *\r | |
10 | * PHP QR Code is distributed under LGPL 3\r | |
11 | * Copyright (C) 2010 Dominik Dzienia <deltalab at poczta dot fm>\r | |
12 | *\r | |
13 | * The following data / specifications are taken from\r | |
14 | * "Two dimensional symbol -- QR-code -- Basic Specification" (JIS X0510:2004)\r | |
15 | * or\r | |
16 | * "Automatic identification and data capture techniques -- \r | |
17 | * QR Code 2005 bar code symbology specification" (ISO/IEC 18004:2006)\r | |
18 | *\r | |
19 | * This library is free software; you can redistribute it and/or\r | |
20 | * modify it under the terms of the GNU Lesser General Public\r | |
21 | * License as published by the Free Software Foundation; either\r | |
22 | * version 3 of the License, or any later version.\r | |
23 | *\r | |
24 | * This library is distributed in the hope that it will be useful,\r | |
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of\r | |
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r | |
27 | * Lesser General Public License for more details.\r | |
28 | *\r | |
29 | * You should have received a copy of the GNU Lesser General Public\r | |
30 | * License along with this library; if not, write to the Free Software\r | |
31 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\r | |
32 | */\r | |
33 | class QRsplit {\r | |
34 | \r | |
35 | public $dataStr = '';\r | |
36 | public $input;\r | |
37 | public $modeHint;\r | |
38 | \r | |
39 | //----------------------------------------------------------------------\r | |
40 | public function __construct($dataStr, $input, $modeHint) \r | |
41 | {\r | |
42 | $this->dataStr = $dataStr;\r | |
43 | $this->input = $input;\r | |
44 | $this->modeHint = $modeHint;\r | |
45 | }\r | |
46 | \r | |
47 | //----------------------------------------------------------------------\r | |
48 | public static function isdigitat($str, $pos)\r | |
49 | { \r | |
50 | if ($pos >= strlen($str))\r | |
51 | return false;\r | |
52 | \r | |
53 | return ((ord($str[$pos]) >= ord('0'))&&(ord($str[$pos]) <= ord('9')));\r | |
54 | }\r | |
55 | \r | |
56 | //----------------------------------------------------------------------\r | |
57 | public static function isalnumat($str, $pos)\r | |
58 | {\r | |
59 | if ($pos >= strlen($str))\r | |
60 | return false;\r | |
61 | \r | |
62 | return (QRinput::lookAnTable(ord($str[$pos])) >= 0);\r | |
63 | }\r | |
64 | \r | |
65 | //----------------------------------------------------------------------\r | |
66 | public function identifyMode($pos)\r | |
67 | {\r | |
68 | if ($pos >= strlen($this->dataStr)) \r | |
69 | return QR_MODE_NUL;\r | |
70 | \r | |
71 | $c = $this->dataStr[$pos];\r | |
72 | \r | |
73 | if(self::isdigitat($this->dataStr, $pos)) {\r | |
74 | return QR_MODE_NUM;\r | |
75 | } else if(self::isalnumat($this->dataStr, $pos)) {\r | |
76 | return QR_MODE_AN;\r | |
77 | } else if($this->modeHint == QR_MODE_KANJI) {\r | |
78 | \r | |
79 | if ($pos+1 < strlen($this->dataStr)) \r | |
80 | {\r | |
81 | $d = $this->dataStr[$pos+1];\r | |
82 | $word = (ord($c) << 8) | ord($d);\r | |
83 | if(($word >= 0x8140 && $word <= 0x9ffc) || ($word >= 0xe040 && $word <= 0xebbf)) {\r | |
84 | return QR_MODE_KANJI;\r | |
85 | }\r | |
86 | }\r | |
87 | }\r | |
88 | \r | |
89 | return QR_MODE_8;\r | |
90 | } \r | |
91 | \r | |
92 | //----------------------------------------------------------------------\r | |
93 | public function eatNum()\r | |
94 | {\r | |
95 | $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());\r | |
96 | \r | |
97 | $p = 0;\r | |
98 | while(self::isdigitat($this->dataStr, $p)) {\r | |
99 | $p++;\r | |
100 | }\r | |
101 | \r | |
102 | $run = $p;\r | |
103 | $mode = $this->identifyMode($p);\r | |
104 | \r | |
105 | if($mode == QR_MODE_8) {\r | |
106 | $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln\r | |
107 | + QRinput::estimateBitsMode8(1) // + 4 + l8\r | |
108 | - QRinput::estimateBitsMode8($run + 1); // - 4 - l8\r | |
109 | if($dif > 0) {\r | |
110 | return $this->eat8();\r | |
111 | }\r | |
112 | }\r | |
113 | if($mode == QR_MODE_AN) {\r | |
114 | $dif = QRinput::estimateBitsModeNum($run) + 4 + $ln\r | |
115 | + QRinput::estimateBitsModeAn(1) // + 4 + la\r | |
116 | - QRinput::estimateBitsModeAn($run + 1);// - 4 - la\r | |
117 | if($dif > 0) {\r | |
118 | return $this->eatAn();\r | |
119 | }\r | |
120 | }\r | |
121 | \r | |
122 | $ret = $this->input->append(QR_MODE_NUM, $run, str_split($this->dataStr));\r | |
123 | if($ret < 0)\r | |
124 | return -1;\r | |
125 | \r | |
126 | return $run;\r | |
127 | }\r | |
128 | \r | |
129 | //----------------------------------------------------------------------\r | |
130 | public function eatAn()\r | |
131 | {\r | |
132 | $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());\r | |
133 | $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());\r | |
134 | \r | |
135 | $p = 0;\r | |
136 | \r | |
137 | while(self::isalnumat($this->dataStr, $p)) {\r | |
138 | if(self::isdigitat($this->dataStr, $p)) {\r | |
139 | $q = $p;\r | |
140 | while(self::isdigitat($this->dataStr, $q)) {\r | |
141 | $q++;\r | |
142 | }\r | |
143 | \r | |
144 | $dif = QRinput::estimateBitsModeAn($p) // + 4 + la\r | |
145 | + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln\r | |
146 | - QRinput::estimateBitsModeAn($q); // - 4 - la\r | |
147 | \r | |
148 | if($dif < 0) {\r | |
149 | break;\r | |
150 | } else {\r | |
151 | $p = $q;\r | |
152 | }\r | |
153 | } else {\r | |
154 | $p++;\r | |
155 | }\r | |
156 | }\r | |
157 | \r | |
158 | $run = $p;\r | |
159 | \r | |
160 | if(!self::isalnumat($this->dataStr, $p)) {\r | |
161 | $dif = QRinput::estimateBitsModeAn($run) + 4 + $la\r | |
162 | + QRinput::estimateBitsMode8(1) // + 4 + l8\r | |
163 | - QRinput::estimateBitsMode8($run + 1); // - 4 - l8\r | |
164 | if($dif > 0) {\r | |
165 | return $this->eat8();\r | |
166 | }\r | |
167 | }\r | |
168 | \r | |
169 | $ret = $this->input->append(QR_MODE_AN, $run, str_split($this->dataStr));\r | |
170 | if($ret < 0)\r | |
171 | return -1;\r | |
172 | \r | |
173 | return $run;\r | |
174 | }\r | |
175 | \r | |
176 | //----------------------------------------------------------------------\r | |
177 | public function eatKanji()\r | |
178 | {\r | |
179 | $p = 0;\r | |
180 | \r | |
181 | while($this->identifyMode($p) == QR_MODE_KANJI) {\r | |
182 | $p += 2;\r | |
183 | }\r | |
184 | \r | |
185 | $ret = $this->input->append(QR_MODE_KANJI, $p, str_split($this->dataStr));\r | |
186 | if($ret < 0)\r | |
187 | return -1;\r | |
188 | \r | |
189 | return $run;\r | |
190 | }\r | |
191 | \r | |
192 | //----------------------------------------------------------------------\r | |
193 | public function eat8()\r | |
194 | {\r | |
195 | $la = QRspec::lengthIndicator(QR_MODE_AN, $this->input->getVersion());\r | |
196 | $ln = QRspec::lengthIndicator(QR_MODE_NUM, $this->input->getVersion());\r | |
197 | \r | |
198 | $p = 1;\r | |
199 | $dataStrLen = strlen($this->dataStr);\r | |
200 | \r | |
201 | while($p < $dataStrLen) {\r | |
202 | \r | |
203 | $mode = $this->identifyMode($p);\r | |
204 | if($mode == QR_MODE_KANJI) {\r | |
205 | break;\r | |
206 | }\r | |
207 | if($mode == QR_MODE_NUM) {\r | |
208 | $q = $p;\r | |
209 | while(self::isdigitat($this->dataStr, $q)) {\r | |
210 | $q++;\r | |
211 | }\r | |
212 | $dif = QRinput::estimateBitsMode8($p) // + 4 + l8\r | |
213 | + QRinput::estimateBitsModeNum($q - $p) + 4 + $ln\r | |
214 | - QRinput::estimateBitsMode8($q); // - 4 - l8\r | |
215 | if($dif < 0) {\r | |
216 | break;\r | |
217 | } else {\r | |
218 | $p = $q;\r | |
219 | }\r | |
220 | } else if($mode == QR_MODE_AN) {\r | |
221 | $q = $p;\r | |
222 | while(self::isalnumat($this->dataStr, $q)) {\r | |
223 | $q++;\r | |
224 | }\r | |
225 | $dif = QRinput::estimateBitsMode8($p) // + 4 + l8\r | |
226 | + QRinput::estimateBitsModeAn($q - $p) + 4 + $la\r | |
227 | - QRinput::estimateBitsMode8($q); // - 4 - l8\r | |
228 | if($dif < 0) {\r | |
229 | break;\r | |
230 | } else {\r | |
231 | $p = $q;\r | |
232 | }\r | |
233 | } else {\r | |
234 | $p++;\r | |
235 | }\r | |
236 | }\r | |
237 | \r | |
238 | $run = $p;\r | |
239 | $ret = $this->input->append(QR_MODE_8, $run, str_split($this->dataStr));\r | |
240 | \r | |
241 | if($ret < 0)\r | |
242 | return -1;\r | |
243 | \r | |
244 | return $run;\r | |
245 | }\r | |
246 | \r | |
247 | //----------------------------------------------------------------------\r | |
248 | public function splitString()\r | |
249 | {\r | |
250 | while (strlen($this->dataStr) > 0)\r | |
251 | {\r | |
252 | if($this->dataStr == '')\r | |
253 | return 0;\r | |
254 | \r | |
255 | $mode = $this->identifyMode(0);\r | |
256 | \r | |
257 | switch ($mode) {\r | |
258 | case QR_MODE_NUM: $length = $this->eatNum(); break;\r | |
259 | case QR_MODE_AN: $length = $this->eatAn(); break;\r | |
260 | case QR_MODE_KANJI:\r | |
261 | if ($hint == QR_MODE_KANJI)\r | |
262 | $length = $this->eatKanji();\r | |
263 | else $length = $this->eat8();\r | |
264 | break;\r | |
265 | default: $length = $this->eat8(); break;\r | |
266 | \r | |
267 | }\r | |
268 | \r | |
269 | if($length == 0) return 0;\r | |
270 | if($length < 0) return -1;\r | |
271 | \r | |
272 | $this->dataStr = substr($this->dataStr, $length);\r | |
273 | }\r | |
274 | }\r | |
275 | \r | |
276 | //----------------------------------------------------------------------\r | |
277 | public function toUpper()\r | |
278 | {\r | |
279 | $stringLen = strlen($this->dataStr);\r | |
280 | $p = 0;\r | |
281 | \r | |
282 | while ($p<$stringLen) {\r | |
283 | $mode = self::identifyMode(substr($this->dataStr, $p), $this->modeHint);\r | |
284 | if($mode == QR_MODE_KANJI) {\r | |
285 | $p += 2;\r | |
286 | } else {\r | |
287 | if (ord($this->dataStr[$p]) >= ord('a') && ord($this->dataStr[$p]) <= ord('z')) {\r | |
288 | $this->dataStr[$p] = chr(ord($this->dataStr[$p]) - 32);\r | |
289 | }\r | |
290 | $p++;\r | |
291 | }\r | |
292 | }\r | |
293 | \r | |
294 | return $this->dataStr;\r | |
295 | }\r | |
296 | \r | |
297 | //----------------------------------------------------------------------\r | |
298 | public static function splitStringToQRinput($string, QRinput $input, $modeHint, $casesensitive = true)\r | |
299 | {\r | |
300 | if(is_null($string) || $string == '\0' || $string == '') {\r | |
301 | throw new Exception('empty string!!!');\r | |
302 | }\r | |
303 | \r | |
304 | $split = new QRsplit($string, $input, $modeHint);\r | |
305 | \r | |
306 | if(!$casesensitive)\r | |
307 | $split->toUpper();\r | |
308 | \r | |
309 | return $split->splitString();\r | |
310 | }\r | |
311 | } |