1: <?php
2: /*
3: * Copyright (c) 2015 @trashtoy
4: * https://github.com/trashtoy/
5: *
6: * Permission is hereby granted, free of charge, to any person obtaining a copy of
7: * this software and associated documentation files (the "Software"), to deal in
8: * the Software without restriction, including without limitation the rights to use,
9: * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
10: * Software, and to permit persons to whom the Software is furnished to do so,
11: * subject to the following conditions:
12: *
13: * The above copyright notice and this permission notice shall be included in all
14: * copies or substantial portions of the Software.
15: *
16: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18: * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
19: * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20: * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21: * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22: */
23: /**
24: * PHP class file.
25: * @auhtor trashtoy
26: * @since 2.1.0
27: */
28: namespace Peach\DF;
29:
30: /**
31: * 複数の Codec のエンコード・デコード処理を連結させるための Codec です.
32: *
33: * このクラスはコンストラクタに 2 種類の Codec を指定してインスタンスを初期化します.
34: * エンコードは, コンストラクタに指定した 1 番目, 2 番目の Codec の encode() を順に呼び出すことで実行されます.
35: * デコードは, エンコードとは逆に 2 番目, 1 番目の順番で実行されます.
36: */
37: class CodecChain implements Codec
38: {
39: /**
40: * 1 番目の Codec です. エンコードの際に先に処理されます.
41: *
42: * @var Codec
43: */
44: private $first;
45:
46: /**
47: * 2 番目の Codec です. デコードの際に先に処理されます.
48: *
49: * @var Codec
50: */
51: private $second;
52:
53: /**
54: * 指定された Codec を使用して変換を行う CodecChain インスタンスを生成します.
55: *
56: * もしも第 1 Codec が CodecChain インスタンスだった場合は以下のアルゴリズムに従ってチェーンの再構成を行います.
57: *
58: * - 引数の CodecChain の第 1 Codec を新しいインスタンスの第 1 Codec として適用します
59: * - 引数の CodecChain の第 2 Codec とコンストラクタ引数の第 2 Codec で新しい CodecChain を生成し, それを新しいインスタンスの第 2 Codec として適用します
60: *
61: * @param Codec $first 1 番目の Codec
62: * @param Codec $second 2 番目の Codec
63: */
64: public function __construct(Codec $first, Codec $second)
65: {
66: if ($first instanceof CodecChain) {
67: $this->first = $first->first;
68: $this->second = new self($first->second, $second);
69: } else {
70: $this->first = $first;
71: $this->second = $second;
72: }
73: }
74:
75: /**
76: * チェーンの末尾に新しい Codec を連結させた, 新しい CodecChain インスタンスを返します.
77: *
78: * @param Codec $c
79: * @return CodecChain
80: */
81: public function append(Codec $c)
82: {
83: return new CodecChain($this->first, new CodecChain($this->second, $c));
84: }
85:
86: /**
87: * チェーンの先頭に新しい Codec を連結させた, 新しい CodecChain インスタンスを返します.
88: *
89: * @param Codec $c
90: * @return CodecChain
91: */
92: public function prepend(Codec $c)
93: {
94: return new CodecChain($c, $this);
95: }
96:
97: /**
98: * このオブジェクトに指定された Codec を使って指定された値をデコードします.
99: *
100: * @param mixed $text デコード対象の値
101: * @return mixed 変換結果
102: */
103: public function decode($text)
104: {
105: return $this->first->decode($this->second->decode($text));
106: }
107:
108: /**
109: * このオブジェクトに指定された Codec を使って指定された値をエンコードします.
110: *
111: * @param mixed $var エンコード対象の値
112: * @return mixed 変換結果
113: */
114: public function encode($var)
115: {
116: return $this->second->encode($this->first->encode($var));
117: }
118: }
119: