1: <?php
2: namespace phpcassa\Schema\DataType;
3:
4: use phpcassa\Schema\DataType\Serialized;
5: use phpcassa\ColumnFamily;
6:
7: 8: 9: 10: 11:
12: class CompositeType extends CassandraType implements Serialized
13: {
14: 15: 16: 17:
18: public function __construct($inner_types) {
19: $this->inner_types = $inner_types;
20: }
21:
22: public function pack($value, $is_name=true, $slice_end=null, $is_data=false) {
23: if ($is_name && $is_data)
24: $value = unserialize($value);
25:
26: $res = "";
27: $num_items = count($value);
28: for ($i = 0; $i < $num_items; $i++) {
29: $item = $value[$i];
30: $eoc = 0x00;
31: if (is_array($item)) {
32: list($actual_item, $inclusive) = $item;
33: $item = $actual_item;
34: if ($inclusive) {
35: if ($slice_end == ColumnFamily::SLICE_START)
36: $eoc = 0xFF;
37: else if ($slice_end == ColumnFamily::SLICE_FINISH)
38: $eoc = 0x01;
39: } else {
40: if ($slice_end == ColumnFamily::SLICE_START)
41: $eoc = 0x01;
42: else if ($slice_end == ColumnFamily::SLICE_FINISH)
43: $eoc = 0xFF;
44: }
45: } else if ($i === ($num_items - 1)) {
46: if ($slice_end == ColumnFamily::SLICE_START)
47: $eoc = 0xFF;
48: else if ($slice_end == ColumnFamily::SLICE_FINISH)
49: $eoc = 0x01;
50: }
51:
52: $type = $this->inner_types[$i];
53: $packed = $type->pack($item);
54: $len = strlen($packed);
55: $res .= pack("C2", $len&0xFF00, $len&0xFF).$packed.pack("C1", $eoc);
56: }
57:
58: return $res;
59: }
60:
61: public function unpack($data, $is_name=true) {
62: $component_idx = 0;
63: $components = array();
64: while (empty($data) !== true) {
65: $bytes = unpack("Chi/Clow", substr($data, 0, 2));
66: $len = $bytes["hi"]*256 + $bytes["low"];
67: $component_data = substr($data, 2, $len);
68:
69: $type = $this->inner_types[$component_idx];
70: $unpacked = $type->unpack($component_data);
71: $components[] = $unpacked;
72:
73: $data = substr($data, $len + 3);
74: $component_idx++;
75: }
76:
77: if ($is_name) {
78: return serialize($components);
79: } else {
80: return $components;
81: }
82: }
83:
84: public function __toString() {
85: $inner_strs = array();
86: foreach ($inner_types as $inner_type) {
87: $inner_strs[] = (string)$inner_type;
88: }
89:
90: return 'CompositeType(' . join(', ', $inner_strs) . ')';
91: }
92: }
93: