Exemplo n.º 1
0
        public void testRegex()
        {
            var rxlist = new Regex[] {
                new Regex(""),
                new Regex("foo", RegexOptions.IgnoreCase|RegexOptions.CultureInvariant),
                new Regex("x.*y", RegexOptions.Multiline),
                new Regex("a", RegexOptions.ExplicitCapture),
                new Regex("b", RegexOptions.Singleline),
            };
            foreach(var rx in rxlist) {
                var recode = (Regex)BertCodec.Decode(BertCodec.Encode(rx));
                AssertRegexEqual(recode, rx);
            }

            /* It would be nice to translate
             * IgnorePatternWhitespace to erlang's "extended", but
             * they differ in their handling of whitespace within
             * character classes. Maybe that's ok, given other
             * possible differences of interpretation? */
            Assert.Throws<NotSupportedException>( () => { BertCodec.Encode(new Regex("", RegexOptions.IgnorePatternWhitespace)); } );
            Assert.Throws<NotSupportedException>( () => { BertCodec.Encode(new Regex("", RegexOptions.RightToLeft)); } );
            Assert.Throws<NotSupportedException>( () => { BertCodec.Encode(new Regex("", RegexOptions.ECMAScript)); } );
            Assert.Throws<NotSupportedException>( () => { BertCodec.Encode(new Regex("", RegexOptions.IgnoreCase)); } );
            Assert.Throws<NotSupportedException>( () => { BertCodec.Encode(new Regex("", RegexOptions.CultureInvariant)); } );

            var decodeExamples = new List<Tuple<byte[], ArrayList, Regex>>() {
                Tuple.Create(new byte[0], new ArrayList(), new Regex("")),
                Tuple.Create(new byte[0], new ArrayList() { BertCodec.caseless },
                        new Regex("", RegexOptions.IgnoreCase|RegexOptions.CultureInvariant)),
                Tuple.Create(new byte[0], new ArrayList() { BertCodec.caseless, BertCodec.dotall },
                        new Regex("", RegexOptions.IgnoreCase|RegexOptions.CultureInvariant|RegexOptions.Singleline)),
                Tuple.Create(new byte[0], new ArrayList() { BertCodec.multiline },
                        new Regex("", RegexOptions.Multiline)),
                Tuple.Create(new byte[0], new ArrayList() { BertCodec.no_auto_capture },
                        new Regex("", RegexOptions.ExplicitCapture)),
                new Tuple<byte[], ArrayList, Regex>(new byte[0], new ArrayList() { new Atom("invalid") }, null),
            };
            foreach(var t in decodeExamples) {
                var rx = new ETFTuple() { BertCodec.bert, BertCodec.regex, t.Item1, t.Item2 };
                if(t.Item3 == null) {
                    Assert.Throws<NotSupportedException>( () => BertCodec.bertDecode(rx));
                } else {
                    AssertRegexEqual(t.Item3, (Regex)BertCodec.bertDecode(rx));
                }
            }
        }
Exemplo n.º 2
0
        internal static object bertDecode(object obj)
        {
            if(obj is ETFTuple) {
                var tuple = (ETFTuple)obj;
                if(tuple.Count > 1 && bert.Equals(tuple[0])) {
                    switch(tuple.Count) {
                        case 2:
                            if(nil.Equals(tuple[1])) {
                                obj = null;
                            } else if(True.Equals(tuple[1])) {
                                obj = true;
                            } else if(False.Equals(tuple[1])) {
                                obj = false;
                            } else {
                                goto default;
                            }
                            break;

                        case 3:
                            if(dict.Equals(tuple[1])) {
                                var il = (IList)tuple[2];
                                var ht = new Hashtable(il.Count);
                                foreach(object o in il) {
                                    ETFTuple item = (ETFTuple)o;
                                    var key = bertDecode(item[0]);
                                    byte[] b = key as byte[];
                                    if(b != null) {
                                        lock(utf8) {
                                            key = utf8.GetString(b, 0, b.Length);
                                        }
                                    }
                                    ht.Add(key, bertDecode(item[1]));
                                }
                                obj = ht;
                                break;
                            }
                            goto default;

                        case 4:
                            if(regex.Equals(tuple[1])) {
                                var options = RegexOptions.None;
                                foreach(var opt in ((IList)tuple[3]).Cast<Atom>()) {
                                    RegexOptions optflag;
                                    if(RegexOptionTranslations.TryGetValue(opt, out optflag)) {
                                        options |= optflag;
                                    } else {
                                        throw new NotSupportedException(string.Format("regex option: {0}", opt));
                                    }
                                }

                                string pattern;
                                lock(utf8) {
                                    pattern = utf8.GetString((byte[])tuple[2]);
                                }
                                obj = new Regex(pattern, options);
                                break;
                            }
                            goto default;

                        case 5:
                            if(time.Equals(tuple[1])) {
                                obj = BeginEpoch.Add(new TimeSpan(
                                      Convert.ToInt64(tuple[2]) * TicksPerMegaSecond
                                    + Convert.ToInt64(tuple[3]) * TimeSpan.TicksPerSecond
                                    + Convert.ToInt64(tuple[4]) * TimeSpan.TicksPerMillisecond
                                ));
                                break;
                            }
                            goto default;

                        default:
                            throw new NotSupportedException(string.Format("invalid bert type: {0}", tuple[1]));
                    }
                } else {
                    var nt = new ETFTuple(tuple.Count);
                    foreach(var e in tuple) {
                        nt.Add(bertDecode(e));
                    }
                    obj = nt;
                }
            } else if(obj is byte[]) {
                // don't treat byte[] as IList
            } else if(obj is IList) {
                var il = (IList)obj;
                var nl = new ArrayList(il.Count);
                foreach(var e in il) {
                    nl.Add(bertDecode(e));
                }
                obj = nl;
            }

            return obj;
        }
Exemplo n.º 3
0
        internal static object DecodePart(byte[] encoded, ref int offset)
        {
            byte encoding_type = encoded[offset++];
            switch(encoding_type) {
                case Constants.SMALL_INTEGER_EXT:
                    return encoded[offset++];

                case Constants.INTEGER_EXT:
                    return DecodeInt(encoded, ref offset);

                case Constants.STRING_EXT:
                    ushort slen = DecodeUshort(encoded, ref offset);
                    var cl = new List<byte>(slen);
                    for(var i = 0; i < slen; i++) {
                        cl.Add(encoded[offset + i]);
                    }
                    offset += slen;
                    return cl;

                case Constants.BINARY_EXT:
                    int blen = (int)DecodeUint(encoded, ref offset);
                    byte[] b = new byte[blen];
                    Buffer.BlockCopy(encoded, offset, b, 0, blen);
                    offset += blen;
                    return b;

                case Constants.LIST_EXT:
                    uint llen = DecodeUint(encoded, ref offset);
                    var list = new ArrayList((int)llen);
                    DecodeList(encoded, ref offset, list, llen, true);
                    return list;

                case Constants.SMALL_TUPLE_EXT:
                    var stlen = encoded[offset++];
                    var st = new ETFTuple(stlen);
                    DecodeList(encoded, ref offset, st, stlen);
                    return st;

                case Constants.LARGE_TUPLE_EXT:
                    uint ltlen = DecodeUint(encoded, ref offset);
                    var lt = new ETFTuple((int)ltlen);
                    DecodeList(encoded, ref offset, lt, ltlen);
                    return lt;

                case Constants.SMALL_ATOM_EXT:
                    var salen = encoded[offset++];
                    offset += salen;
                    return new Atom(encoded, offset - salen, salen);

                case Constants.ATOM_EXT:
                    var alen = DecodeUshort(encoded, ref offset);
                    offset += alen;
                    return new Atom(encoded, offset - alen, alen);

                case Constants.SMALL_BIG_EXT:
                    return DecodeBig(encoded, ref offset, encoded[offset++]);

                case Constants.LARGE_BIG_EXT:
                    int size = (int)DecodeUint(encoded, ref offset);
                    return DecodeBig(encoded, ref offset, size);

                case Constants.NEW_FLOAT_EXT:
                    return DecodeDouble(encoded, ref offset);

                case Constants.FLOAT_EXT:
                    double dret;
                    string ds = Encoding.ASCII.GetString(encoded, offset, Constants.FLOAT_EXT_BYTES);
                    offset += Constants.FLOAT_EXT_BYTES;
                    NumberStyles style =
                          NumberStyles.AllowDecimalPoint
                        | NumberStyles.AllowExponent
                        | NumberStyles.AllowLeadingSign
                        | NumberStyles.AllowLeadingWhite;
                    if(Double.TryParse(ds, style, NumberFormatInfo.InvariantInfo, out dret)) {
                        return dret;
                    } else {
                        throw new EncodingError(string.Format("invalid float encoding: \"{0}\"", ds));
                    }

                case Constants.NIL_EXT:
                    return new ArrayList();

                default:
                    throw new EncodingError(string.Format("invalid encoding type: {0}", encoding_type));
            }
        }
Exemplo n.º 4
0
 static object bertEncode(object obj)
 {
     if(obj == null) {
         obj = BertNil;
     } else if(obj is bool) {
         obj = (bool)obj ? BertTrue : BertFalse;
     } else if(obj is ETFTuple) {	// has to come before IList case so tuples won't be converted
         var tuple = (ETFTuple)obj;
         var nt = new ETFTuple(tuple.Count);
         foreach(var e in tuple) {
             nt.Add(bertEncode(e));
         }
         obj = nt;
     } else if(obj is byte[]) {
         // don't treat byte[] as IList
     } else if(obj is IList) {
         var il = (IList)obj;
         var nl = new ArrayList(il.Count);
         foreach(var e in il) {
             nl.Add(bertEncode(e));
         }
         obj = nl;
     } else if(obj is IDictionary) {
         var id = (IDictionary)obj;
         var items = new ArrayList(id.Count);
         foreach(DictionaryEntry e in id) {
             items.Add(new ETFTuple() { bertEncode(e.Key), bertEncode(e.Value) });
         }
         obj = new ETFTuple() { bert, dict, items };
     } else if(obj is IDictionary<string, object>) {
         var id = (IDictionary<string, object> )obj;
         var items = new ArrayList(id.Count);
         foreach(var e in id) {
             items.Add(new ETFTuple() { bertEncode(e.Key), bertEncode(e.Value) });
         }
         obj = new ETFTuple() { bert, dict, items };
     } else if(obj is DateTime) {
         var dt = (DateTime)obj;
         TimeSpan span = dt - BeginEpoch;
         long megaSeconds = span.Ticks / TicksPerMegaSecond;
         long seconds = (span.Ticks % TicksPerMegaSecond) / TimeSpan.TicksPerSecond;
         long milliSeconds = (span.Ticks % TimeSpan.TicksPerSecond) / TimeSpan.TicksPerMillisecond;
         obj = new ETFTuple() { bert, time, megaSeconds, seconds, milliSeconds };
     } else if(obj is Regex) {
         obj = encodeRegex((Regex)obj);
     }
     return obj;
 }