internal int importBinary(XMLElement elem, int offs, ByteBuffer buf, String fieldName) { if (elem == null || elem.isNullValue()) { buf.extend(offs + 4); Bytes.pack4(buf.arr, offs, -1); offs += 4; } else if (elem.isStringValue()) { String hexStr = elem.StringValue; int len = hexStr.Length; if (hexStr.StartsWith("#")) { buf.extend(offs + 4 + len / 2 - 1); Bytes.pack4(buf.arr, offs, -2 - getHexValue(hexStr[1])); offs += 4; for (int j = 2; j < len; j += 2) { buf.arr[offs++] = (byte)((getHexValue(hexStr[j]) << 4) | getHexValue(hexStr[j + 1])); } } else { buf.extend(offs + 4 + len / 2); Bytes.pack4(buf.arr, offs, len / 2); offs += 4; for (int j = 0; j < len; j += 2) { buf.arr[offs++] = (byte)((getHexValue(hexStr[j]) << 4) | getHexValue(hexStr[j + 1])); } } } else { XMLElement refElem = elem.getSibling("ref"); if (refElem != null) { buf.extend(offs + 4); Bytes.pack4(buf.arr, offs, mapId(getIntAttribute(refElem, "id"))); offs += 4; } else { XMLElement item = elem.getSibling("element"); int len = (item == null) ? 0 : item.Counter; buf.extend(offs + 4 + len); Bytes.pack4(buf.arr, offs, len); offs += 4; while (--len >= 0) { if (item.isIntValue()) { buf.arr[offs] = (byte)item.IntValue; } else if (item.isRealValue()) { buf.arr[offs] = (byte)item.RealValue; } else { throwException("Conversion for field " + fieldName + " is not possible"); } item = item.NextSibling; offs += 1; } } } return offs; }
internal int importRef(XMLElement elem, int offs, ByteBuffer buf) { int oid = 0; if (elem != null) { if (elem.isStringValue()) { String str = elem.StringValue; offs = buf.packI4(offs, -1-(int)ClassDescriptor.FieldType.tpString); return buf.packString(offs, str); } else { XMLElement value = elem.FirstSibling; if (value == null) { throwException("object reference expected"); } string name = value.Name; if (name == "scalar") { int tid = getIntAttribute(value, "type"); string hexStr = getAttribute(value, "value"); int len = hexStr.Length; buf.extend(offs + 4 + len/2); Bytes.pack4(buf.arr, offs, -1-tid); offs += 4; if (tid == (int)ClassDescriptor.FieldType.tpCustom) { object obj = storage.serializer.Parse(hexStr); storage.serializer.Pack(obj, buf.GetWriter()); offs = buf.used; } else { for (int j = 0; j < len; j += 2) { buf.arr[offs++] = (byte)((getHexValue(hexStr[j]) << 4) | getHexValue(hexStr[j+1])); } } return offs; } else if (name == "type") { string typeName = getAttribute(value, "name"); offs = buf.packI4(offs, -1-(int)ClassDescriptor.FieldType.tpType); return buf.packString(offs, typeName); } else if (name == "ref") { oid = mapId(getIntAttribute(value, "id")); } else { ClassDescriptor desc = storage.getClassDescriptor(findClassByName(name)); offs = buf.packI4(offs, -(int)ClassDescriptor.FieldType.tpValueTypeBias - desc.Oid); if (desc.isCollection) { XMLElement item = value.getSibling("element"); int len = (item == null) ? 0 : item.Counter; offs = buf.packI4(offs, len); while (--len >= 0) { offs = importRef(item, offs, buf); item = item.NextSibling; } } else if (desc.isDictionary) { XMLElement item = value.getSibling("element"); int len = (item == null) ? 0 : item.Counter; offs = buf.packI4(offs, len); while (--len >= 0) { XMLElement key = item.getSibling("key"); offs = importRef(key, offs, buf); XMLElement val = item.getSibling("value"); offs = importRef(val, offs, buf); item = item.NextSibling; } } else { offs = packObject(value, desc, offs, buf); } return offs; } } } return buf.packI4(offs, oid); }