@@ -113,7 +113,36 @@ fn uv_ip_as_ip<T>(addr: UvIpAddr, f: &fn(IpAddr) -> T) -> T {
113
113
} ;
114
114
match s {
115
115
"" => ~[ ] ,
116
- s => s. split_iter ( ':' ) . transform ( read_hex_segment) . collect ( ) ,
116
+ // IPv4-Mapped/Compatible IPv6 Address?
117
+ s if s. find ( '.' ) . is_some ( ) => {
118
+ let i = s. rfind ( ':' ) . get_or_default ( -1 ) ;
119
+
120
+ let b = s. slice ( i + 1 , s. len ( ) ) ; // the ipv4 part
121
+
122
+ let h = b. split_iter ( '.' )
123
+ . transform ( |s : & str | -> u8 { FromStr :: from_str ( s) . unwrap ( ) } )
124
+ . transform ( |s : u8 | -> ~str { fmt ! ( "%02x" , s as uint) } )
125
+ . collect :: < ~[ ~str ] > ( ) ;
126
+
127
+ if i == -1 {
128
+ // Ipv4 Compatible Address (::x.x.x.x)
129
+ // first 96 bits are zero leaving 32 bits
130
+ // for the ipv4 part
131
+ // (i.e ::127.0.0.1 == ::7F00:1)
132
+ ~[ num:: FromStrRadix :: from_str_radix ( h[ 0 ] + h[ 1 ] , 16 ) . unwrap ( ) ,
133
+ num:: FromStrRadix :: from_str_radix ( h[ 2 ] + h[ 3 ] , 16 ) . unwrap ( ) ]
134
+ } else {
135
+ // Ipv4-Mapped Address (::FFFF:x.x.x.x)
136
+ // first 80 bits are zero, followed by all ones
137
+ // for the next 16 bits, leaving 32 bits for
138
+ // the ipv4 part
139
+ // (i.e ::FFFF:127.0.0.1 == ::FFFF:7F00:1)
140
+ ~[ 1 ,
141
+ num:: FromStrRadix :: from_str_radix ( h[ 0 ] + h[ 1 ] , 16 ) . unwrap ( ) ,
142
+ num:: FromStrRadix :: from_str_radix ( h[ 2 ] + h[ 3 ] , 16 ) . unwrap ( ) ]
143
+ }
144
+ } ,
145
+ s => s. split_iter ( ':' ) . transform ( read_hex_segment) . collect ( )
117
146
}
118
147
} ;
119
148
s. split_str_iter ( "::" ) . transform ( convert_each_segment) . collect ( )
0 commit comments