1use ffi;
2use std::slice::from_raw_parts;
3use std::mem::{size_of, transmute};
4use std::ffi::CString;
5use std::borrow::Cow::{Borrowed, Owned};
6
7pub struct EncodedValue {
8 pub buf: Option<Vec<u8>>,
9}
10
11impl EncodedValue {
12 pub fn new(buf: Option<Vec<u8>>) -> Self {
13 Self { buf }
14 }
15
16 pub fn has_value(&self) -> bool {
17 self.buf.is_some()
18 }
19
20 pub fn column_size(&self) -> ffi::SQLULEN {
21 if let Some(buf) = &self.buf {
22 buf.len() as ffi::SQLULEN
23 } else {
24 0
25 }
26 }
27
28 pub fn value_ptr(&self) -> ffi::SQLPOINTER {
29 if let Some(buf) = &self.buf {
30 buf.as_ptr() as *const Self as ffi::SQLPOINTER
31 } else {
32 0 as *const Self as ffi::SQLPOINTER
33 }
34 }
35}
36
37pub unsafe trait OdbcType<'a>: Sized {
38 fn sql_data_type() -> ffi::SqlDataType;
39 fn c_data_type() -> ffi::SqlCDataType;
40 fn convert(_: &'a [u8]) -> Self;
41 fn column_size(&self) -> ffi::SQLULEN;
42 fn null_bytes_count() -> usize {
43 0
44 }
45 fn value_ptr(&self) -> ffi::SQLPOINTER;
46 fn decimal_digits(&self) -> ffi::SQLSMALLINT {
47 0
48 }
49 fn encoded_value(&self) -> EncodedValue;
50}
51
52unsafe impl<'a> OdbcType<'a> for &'a[u8] {
53 fn sql_data_type() -> ffi::SqlDataType {
54 ffi::SQL_EXT_VARBINARY
55 }
56 fn c_data_type() -> ffi::SqlCDataType {
57 ffi::SQL_C_BINARY
58 }
59
60 fn convert(buffer: &'a [u8]) -> Self {
61 buffer
62 }
63
64 fn column_size(&self) -> ffi::SQLULEN {
65 self.len() as ffi::SQLULEN
66 }
67
68 fn value_ptr(&self) -> ffi::SQLPOINTER {
69 self.as_ptr() as *const Self as ffi::SQLPOINTER
70 }
71
72 fn encoded_value(&self) -> EncodedValue {
73 EncodedValue::new(None)
74 }
75}
76
77unsafe impl<'a> OdbcType<'a> for Vec<u8> {
78 fn sql_data_type() -> ffi::SqlDataType {
79 ffi::SQL_EXT_VARBINARY
80 }
81 fn c_data_type() -> ffi::SqlCDataType {
82 ffi::SQL_C_BINARY
83 }
84
85 fn convert(buffer: &'a [u8]) -> Self {
86 buffer.to_vec()
87 }
88
89 fn column_size(&self) -> ffi::SQLULEN {
90 self.len() as ffi::SQLULEN
91 }
92
93 fn value_ptr(&self) -> ffi::SQLPOINTER {
94 self.as_ptr() as *const Self as ffi::SQLPOINTER
95 }
96
97 fn encoded_value(&self) -> EncodedValue {
98 EncodedValue::new(None)
99 }
100}
101
102unsafe impl<'a> OdbcType<'a> for &'a[u16] {
103 fn sql_data_type() -> ffi::SqlDataType {
104 ffi::SQL_EXT_WVARCHAR
105 }
106 fn c_data_type() -> ffi::SqlCDataType {
107 ffi::SQL_C_WCHAR
108 }
109
110 fn convert(buffer: &'a [u8]) -> Self {
111 unsafe { from_raw_parts(buffer.as_ptr() as *const u16, buffer.len() / 2) }
112 }
113
114 fn column_size(&self) -> ffi::SQLULEN {
115 (self.len() * 2) as ffi::SQLULEN
116 }
117
118 fn null_bytes_count() -> usize {
119 2
120 }
121
122 fn value_ptr(&self) -> ffi::SQLPOINTER {
123 self.as_ptr() as *const Self as ffi::SQLPOINTER
124 }
125
126 fn encoded_value(&self) -> EncodedValue {
127 EncodedValue::new(None)
128 }
129}
130
131unsafe impl<'a> OdbcType<'a> for Vec<u16> {
132 fn sql_data_type() -> ffi::SqlDataType {
133 ffi::SQL_EXT_WVARCHAR
134 }
135 fn c_data_type() -> ffi::SqlCDataType {
136 ffi::SQL_C_WCHAR
137 }
138
139 fn convert(buffer: &'a [u8]) -> Self {
140 let buffer = unsafe { from_raw_parts(buffer.as_ptr() as *const u16, buffer.len() / 2) };
141 buffer.to_vec()
142 }
143
144 fn column_size(&self) -> ffi::SQLULEN {
145 (self.len() * 2) as ffi::SQLULEN
146 }
147
148 fn null_bytes_count() -> usize {
149 2
150 }
151
152 fn value_ptr(&self) -> ffi::SQLPOINTER {
153 self.as_ptr() as *const Self as ffi::SQLPOINTER
154 }
155
156 fn encoded_value(&self) -> EncodedValue {
157 EncodedValue::new(None)
158 }
159}
160
161unsafe impl<'a> OdbcType<'a> for CString {
162 fn sql_data_type() -> ffi::SqlDataType {
163 ffi::SQL_VARCHAR
164 }
165 fn c_data_type() -> ffi::SqlCDataType {
166 ffi::SQL_C_CHAR
167 }
168
169 fn convert(buffer: &'a [u8]) -> Self {
170 CString::new(buffer).unwrap()
171 }
172
173 fn column_size(&self) -> ffi::SQLULEN {
174 self.as_bytes().len() as ffi::SQLULEN
175 }
176
177 fn value_ptr(&self) -> ffi::SQLPOINTER {
178 self.as_bytes().as_ptr() as *const Self as ffi::SQLPOINTER
179 }
180
181 fn null_bytes_count() -> usize {
182 1
183 }
184
185 fn encoded_value(&self) -> EncodedValue {
186 EncodedValue::new(None)
187 }
188}
189
190unsafe impl<'a> OdbcType<'a> for String {
191 fn sql_data_type() -> ffi::SqlDataType {
192 ffi::SQL_VARCHAR
193 }
194 fn c_data_type() -> ffi::SqlCDataType {
195 ffi::SQL_C_CHAR
196 }
197
198 fn convert(buffer: &'a [u8]) -> Self {
199 unsafe { ::environment::DB_ENCODING }.decode(buffer).0.to_string()
200 }
201
202 fn column_size(&self) -> ffi::SQLULEN {
203 unsafe { ::environment::DB_ENCODING }.encode(&self).0.len() as ffi::SQLULEN
204 }
205
206 fn value_ptr(&self) -> ffi::SQLPOINTER {
207 unsafe { ::environment::DB_ENCODING }.encode(&self).0.as_ptr() as *const Self as ffi::SQLPOINTER
208 }
209
210 fn null_bytes_count() -> usize {
211 1
212 }
213
214 fn encoded_value(&self) -> EncodedValue {
215 EncodedValue::new(Some(unsafe { ::environment::DB_ENCODING }.encode(&self).0.to_vec()))
216 }
217}
218
219unsafe impl<'a> OdbcType<'a> for &'a str {
220 fn sql_data_type() -> ffi::SqlDataType {
221 ffi::SQL_VARCHAR
222 }
223 fn c_data_type() -> ffi::SqlCDataType {
224 ffi::SQL_C_CHAR
225 }
226
227 fn convert(buffer: &'a [u8]) -> Self {
228 let cow = unsafe { ::environment::DB_ENCODING }.decode(buffer).0;
229 match cow {
230 Borrowed(strref) => strref,
231 Owned(_string) => panic!("Couldn't convert data to `&str`. Try `String` or `Cow<str>` instead."),
232 }
233 }
234
235 fn column_size(&self) -> ffi::SQLULEN {
236 unsafe { ::environment::DB_ENCODING }.encode(self).0.len() as ffi::SQLULEN
237 }
238
239 fn value_ptr(&self) -> ffi::SQLPOINTER {
240 unsafe { ::environment::DB_ENCODING }.encode(self).0.as_ptr() as *const Self as ffi::SQLPOINTER
241 }
242
243 fn null_bytes_count() -> usize {
244 1
245 }
246
247 fn encoded_value(&self) -> EncodedValue {
248 EncodedValue::new(Some(unsafe { ::environment::DB_ENCODING }.encode(&self).0.to_vec()))
249 }
250}
251
252unsafe impl<'a> OdbcType<'a> for ::std::borrow::Cow<'a, str> {
253 fn sql_data_type() -> ffi::SqlDataType {
254 ffi::SQL_VARCHAR
255 }
256 fn c_data_type() -> ffi::SqlCDataType {
257 ffi::SQL_C_CHAR
258 }
259
260 fn convert(buffer: &'a [u8]) -> Self {
261 unsafe {::environment::DB_ENCODING.decode(buffer).0}
262 }
263
264 fn column_size(&self) -> ffi::SQLULEN {
265 unsafe { ::environment::DB_ENCODING }.encode(self).0.len() as ffi::SQLULEN
266 }
267
268 fn value_ptr(&self) -> ffi::SQLPOINTER {
269 unsafe { ::environment::DB_ENCODING }.encode(self).0.as_ptr() as *const Self as ffi::SQLPOINTER
270 }
271
272 fn null_bytes_count() -> usize {
273 1
274 }
275
276 fn encoded_value(&self) -> EncodedValue {
277 EncodedValue::new(Some(unsafe { ::environment::DB_ENCODING }.encode(self).0.to_vec()))
278 }
279}
280
281fn convert_primitive<T>(buf: &[u8]) -> T
282where
283 T: Copy,
284{
285 unsafe { from_raw_parts(buf.as_ptr() as *const T, 1)[0] }
286}
287
288unsafe impl<'a> OdbcType<'a> for u8 {
289 fn sql_data_type() -> ffi::SqlDataType {
290 ffi::SQL_SMALLINT
291 }
292 fn c_data_type() -> ffi::SqlCDataType {
293 ffi::SQL_C_UTINYINT
294 }
295
296 fn convert(buffer: &'a [u8]) -> Self {
297 convert_primitive(buffer)
298 }
299
300 fn column_size(&self) -> ffi::SQLULEN {
301 size_of::<Self>() as ffi::SQLULEN
302 }
303 fn value_ptr(&self) -> ffi::SQLPOINTER {
304 self as *const Self as ffi::SQLPOINTER
305 }
306
307 fn encoded_value(&self) -> EncodedValue {
308 EncodedValue::new(None)
309 }
310}
311
312unsafe impl<'a> OdbcType<'a> for i8 {
313 fn sql_data_type() -> ffi::SqlDataType {
314 ffi::SQL_SMALLINT
315 }
316 fn c_data_type() -> ffi::SqlCDataType {
317 ffi::SQL_C_STINYINT
318 }
319
320 fn convert(buffer: &'a [u8]) -> Self {
321 convert_primitive(buffer)
322 }
323
324 fn column_size(&self) -> ffi::SQLULEN {
325 size_of::<Self>() as ffi::SQLULEN
326 }
327 fn value_ptr(&self) -> ffi::SQLPOINTER {
328 self as *const Self as ffi::SQLPOINTER
329 }
330
331 fn encoded_value(&self) -> EncodedValue {
332 EncodedValue::new(None)
333 }
334}
335
336unsafe impl<'a> OdbcType<'a> for i16 {
337 fn sql_data_type() -> ffi::SqlDataType {
338 ffi::SQL_SMALLINT
339 }
340 fn c_data_type() -> ffi::SqlCDataType {
341 ffi::SQL_C_SSHORT
342 }
343
344 fn convert(buffer: &'a [u8]) -> Self {
345 convert_primitive(buffer)
346 }
347
348 fn column_size(&self) -> ffi::SQLULEN {
349 size_of::<Self>() as ffi::SQLULEN
350 }
351 fn value_ptr(&self) -> ffi::SQLPOINTER {
352 self as *const Self as ffi::SQLPOINTER
353 }
354
355 fn encoded_value(&self) -> EncodedValue {
356 EncodedValue::new(None)
357 }
358}
359
360unsafe impl<'a> OdbcType<'a> for u16 {
361 fn sql_data_type() -> ffi::SqlDataType {
362 ffi::SQL_SMALLINT
363 }
364 fn c_data_type() -> ffi::SqlCDataType {
365 ffi::SQL_C_USHORT
366 }
367
368 fn convert(buffer: &'a [u8]) -> Self {
369 convert_primitive(buffer)
370 }
371
372 fn column_size(&self) -> ffi::SQLULEN {
373 size_of::<Self>() as ffi::SQLULEN
374 }
375 fn value_ptr(&self) -> ffi::SQLPOINTER {
376 self as *const Self as ffi::SQLPOINTER
377 }
378
379 fn encoded_value(&self) -> EncodedValue {
380 EncodedValue::new(None)
381 }
382}
383
384unsafe impl<'a> OdbcType<'a> for i32 {
385 fn sql_data_type() -> ffi::SqlDataType {
386 ffi::SQL_INTEGER
387 }
388 fn c_data_type() -> ffi::SqlCDataType {
389 ffi::SQL_C_SLONG
390 }
391
392 fn convert(buffer: &'a [u8]) -> Self {
393 convert_primitive(buffer)
394 }
395
396 fn column_size(&self) -> ffi::SQLULEN {
397 size_of::<Self>() as ffi::SQLULEN
398 }
399 fn value_ptr(&self) -> ffi::SQLPOINTER {
400 self as *const Self as ffi::SQLPOINTER
401 }
402
403 fn encoded_value(&self) -> EncodedValue {
404 EncodedValue::new(None)
405 }
406}
407
408unsafe impl<'a> OdbcType<'a> for u32 {
409 fn sql_data_type() -> ffi::SqlDataType {
410 ffi::SQL_INTEGER
411 }
412 fn c_data_type() -> ffi::SqlCDataType {
413 ffi::SQL_C_ULONG
414 }
415
416 fn convert(buffer: &'a [u8]) -> Self {
417 convert_primitive(buffer)
418 }
419
420 fn column_size(&self) -> ffi::SQLULEN {
421 size_of::<Self>() as ffi::SQLULEN
422 }
423 fn value_ptr(&self) -> ffi::SQLPOINTER {
424 self as *const Self as ffi::SQLPOINTER
425 }
426
427 fn encoded_value(&self) -> EncodedValue {
428 EncodedValue::new(None)
429 }
430}
431
432unsafe impl<'a> OdbcType<'a> for i64 {
433 fn sql_data_type() -> ffi::SqlDataType {
434 ffi::SQL_EXT_BIGINT
435 }
436 fn c_data_type() -> ffi::SqlCDataType {
437 ffi::SQL_C_SBIGINT
438 }
439
440 fn convert(buffer: &'a [u8]) -> Self {
441 convert_primitive(buffer)
442 }
443
444 fn column_size(&self) -> ffi::SQLULEN {
445 size_of::<Self>() as ffi::SQLULEN
446 }
447 fn value_ptr(&self) -> ffi::SQLPOINTER {
448 self as *const Self as ffi::SQLPOINTER
449 }
450
451 fn encoded_value(&self) -> EncodedValue {
452 EncodedValue::new(None)
453 }
454}
455
456unsafe impl<'a> OdbcType<'a> for u64 {
457 fn sql_data_type() -> ffi::SqlDataType {
458 ffi::SQL_EXT_BIGINT
459 }
460 fn c_data_type() -> ffi::SqlCDataType {
461 ffi::SQL_C_UBIGINT
462 }
463
464 fn convert(buffer: &'a [u8]) -> Self {
465 convert_primitive(buffer)
466 }
467
468 fn column_size(&self) -> ffi::SQLULEN {
469 size_of::<Self>() as ffi::SQLULEN
470 }
471 fn value_ptr(&self) -> ffi::SQLPOINTER {
472 self as *const Self as ffi::SQLPOINTER
473 }
474
475 fn encoded_value(&self) -> EncodedValue {
476 EncodedValue::new(None)
477 }
478}
479
480unsafe impl<'a> OdbcType<'a> for f32 {
481 fn sql_data_type() -> ffi::SqlDataType {
482 ffi::SQL_FLOAT
483 }
484 fn c_data_type() -> ffi::SqlCDataType {
485 ffi::SQL_C_FLOAT
486 }
487
488 fn convert(buffer: &'a [u8]) -> Self {
489 convert_primitive(buffer)
490 }
491
492 fn column_size(&self) -> ffi::SQLULEN {
493 size_of::<Self>() as ffi::SQLULEN
494 }
495 fn value_ptr(&self) -> ffi::SQLPOINTER {
496 self as *const Self as ffi::SQLPOINTER
497 }
498
499 fn encoded_value(&self) -> EncodedValue {
500 EncodedValue::new(None)
501 }
502}
503
504unsafe impl<'a> OdbcType<'a> for f64 {
505 fn sql_data_type() -> ffi::SqlDataType {
506 ffi::SQL_DOUBLE
507 }
508 fn c_data_type() -> ffi::SqlCDataType {
509 ffi::SQL_C_DOUBLE
510 }
511
512 fn convert(buffer: &'a [u8]) -> Self {
513 convert_primitive(buffer)
514 }
515
516 fn column_size(&self) -> ffi::SQLULEN {
517 size_of::<Self>() as ffi::SQLULEN
518 }
519 fn value_ptr(&self) -> ffi::SQLPOINTER {
520 self as *const Self as ffi::SQLPOINTER
521 }
522
523 fn encoded_value(&self) -> EncodedValue {
524 EncodedValue::new(None)
525 }
526}
527
528unsafe impl<'a> OdbcType<'a> for bool {
529 fn sql_data_type() -> ffi::SqlDataType {
530 ffi::SQL_EXT_BIT
531 }
532 fn c_data_type() -> ffi::SqlCDataType {
533 ffi::SQL_C_BIT
534 }
535
536 fn convert(buffer: &'a [u8]) -> Self {
537 assert!(buffer.len() == 1);
538 buffer[0] > 0
539 }
540
541 fn column_size(&self) -> ffi::SQLULEN {
542 1 as ffi::SQLULEN
543 }
544 fn value_ptr(&self) -> ffi::SQLPOINTER {
545 self as *const Self as ffi::SQLPOINTER
546 }
547
548 fn encoded_value(&self) -> EncodedValue {
549 EncodedValue::new(None)
550 }
551}
552
553pub type SqlDate = ffi::SQL_DATE_STRUCT;
554
555unsafe impl<'a> OdbcType<'a> for SqlDate {
556 fn sql_data_type() -> ffi::SqlDataType {
557 ffi::SQL_DATE
558 }
559 fn c_data_type() -> ffi::SqlCDataType {
560 ffi::SQL_C_DATE
561 }
562
563 fn convert(buffer: &'a [u8]) -> Self {
564 assert_eq!(buffer.len(), size_of::<Self>());
565 unsafe {
566 let ptr = buffer.as_ptr() as *const [u8; size_of::<Self>()];
567 transmute(*ptr)
568 }
569 }
570
571 fn column_size(&self) -> ffi::SQLULEN {
572 size_of::<Self>() as ffi::SQLULEN
573 }
574 fn value_ptr(&self) -> ffi::SQLPOINTER {
575 self as *const Self as ffi::SQLPOINTER
576 }
577
578 fn encoded_value(&self) -> EncodedValue {
579 EncodedValue::new(None)
580 }
581}
582
583pub type SqlTime = ffi::SQL_TIME_STRUCT;
584
585unsafe impl<'a> OdbcType<'a> for SqlTime {
586 fn sql_data_type() -> ffi::SqlDataType {
587 ffi::SQL_TIME
588 }
589 fn c_data_type() -> ffi::SqlCDataType {
590 ffi::SQL_C_TIME
591 }
592
593 fn convert(buffer: &'a [u8]) -> Self {
594 assert_eq!(buffer.len(), size_of::<Self>());
595 unsafe {
596 let ptr = buffer.as_ptr() as *const [u8; size_of::<Self>()];
597 transmute(*ptr)
598 }
599 }
600
601 fn column_size(&self) -> ffi::SQLULEN {
602 size_of::<Self>() as ffi::SQLULEN
603 }
604 fn value_ptr(&self) -> ffi::SQLPOINTER {
605 self as *const Self as ffi::SQLPOINTER
606 }
607
608 fn encoded_value(&self) -> EncodedValue {
609 EncodedValue::new(None)
610 }
611}
612
613pub type SqlTimestamp = ffi::SQL_TIMESTAMP_STRUCT;
614
615unsafe impl<'a> OdbcType<'a> for SqlTimestamp {
616 fn sql_data_type() -> ffi::SqlDataType {
617 ffi::SQL_TIMESTAMP
618 }
619 fn c_data_type() -> ffi::SqlCDataType {
620 ffi::SQL_C_TYPE_TIMESTAMP
621 }
622
623 fn convert(buffer: &'a [u8]) -> Self {
624 assert_eq!(buffer.len(), size_of::<Self>());
625 unsafe {
626 let ptr = buffer.as_ptr() as *const [u8; size_of::<Self>()];
627 transmute(*ptr)
628 }
629 }
630
631 fn column_size(&self) -> ffi::SQLULEN {
632 size_of::<Self>() as ffi::SQLULEN
633 }
634 fn value_ptr(&self) -> ffi::SQLPOINTER {
635 self as *const Self as ffi::SQLPOINTER
636 }
637
638 fn encoded_value(&self) -> EncodedValue {
639 EncodedValue::new(None)
640 }
641}
642
643pub type SqlSsTime2 = ffi::SQL_SS_TIME2_STRUCT;
644
645unsafe impl<'a> OdbcType<'a> for SqlSsTime2 {
646 fn sql_data_type() -> ffi::SqlDataType {
647 ffi::SQL_EXT_VARBINARY
648 }
649 fn c_data_type() -> ffi::SqlCDataType {
650 ffi::SQL_C_BINARY
652 }
653
654 fn convert(buffer: &'a [u8]) -> Self {
655 assert_eq!(buffer.len(), size_of::<Self>());
656 unsafe {
657 let ptr = buffer.as_ptr() as *const [u8; size_of::<Self>()];
658 transmute(*ptr)
659 }
660 }
661
662 fn column_size(&self) -> ffi::SQLULEN {
663 size_of::<Self>() as ffi::SQLULEN
664 }
665 fn value_ptr(&self) -> ffi::SQLPOINTER {
666 self as *const Self as ffi::SQLPOINTER
667 }
668
669 fn encoded_value(&self) -> EncodedValue {
670 EncodedValue::new(None)
671 }
672}
673
674unsafe impl<'a, T> OdbcType<'a> for Option<T> where T: OdbcType<'a> {
675 fn sql_data_type() -> ffi::SqlDataType {
676 T::sql_data_type()
677 }
678
679 fn c_data_type() -> ffi::SqlCDataType {
680 T::c_data_type()
681 }
682
683 fn convert(buffer: &'a [u8]) -> Self {
684 Some(T::convert(buffer))
685 }
686
687 fn column_size(&self) -> ffi::SQLULEN {
688 if let Some(t) = self {
689 t.column_size()
690 } else {
691 0
692 }
693 }
694 fn value_ptr(&self) -> ffi::SQLPOINTER {
695 if let Some(t) = self {
696 t.value_ptr()
697 } else {
698 0 as *const Self as ffi::SQLPOINTER
699 }
700 }
701
702 fn null_bytes_count() -> usize {
703 T::null_bytes_count()
704 }
705
706 fn encoded_value(&self) -> EncodedValue {
707 EncodedValue::new(None)
708 }
709}
710
711
712mod test {
713 use super::*;
715 use std::collections::HashSet;
716 use std::borrow::Cow;
717
718 #[test]
719 fn encoded_value_test() {
720 let mut checker = HashSet::new();
721 let mut encoded_values = Vec::new();
722
723 for i in 0..10 {
727 for h in 0..10 {
728 let string_value = format!("{}{}", i, h);
729 let enc = string_value.encoded_value();
732 if checker.len() == 0 || !checker.contains(&enc.value_ptr()) {
734 checker.insert(enc.value_ptr());
735 encoded_values.push(enc);
736 } else {
737 panic!("same address occur!");
738 }
739 }
740 }
741 checker.clear();
742 encoded_values.clear();
743
744 for i in 0..10 {
746 for h in 0..10 {
747 let str_value: &str = &format!("{}{}", i, h);
748 let enc = str_value.encoded_value();
751 if checker.len() == 0 || !checker.contains(&enc.value_ptr()) {
752 checker.insert(enc.value_ptr());
753 encoded_values.push(enc);
754 } else {
755 panic!("same address occur!");
756 }
757 }
758 }
759 checker.clear();
760 encoded_values.clear();
761
762 for i in 0..10 {
764 for h in 0..10 {
765 let cow_value: Cow<str> = Cow::from(format!("{}{}", i, h));
766 let enc = cow_value.encoded_value();
769 if checker.len() == 0 || !checker.contains(&enc.value_ptr()) {
770 checker.insert(enc.value_ptr());
771 encoded_values.push(enc);
772 } else {
773 panic!("same address occur!");
774 }
775 }
776 }
777 checker.clear();
778 encoded_values.clear();
779
780 }
781}