public DataPage(XElement Element, SimplifiedSchema KnownSchema, int Page) { if (KnownSchema == null) { throw new SchemaMissMatchException(); } string NewSchemaVersion = Element.Attribute("schemaversion").Value; if (NewSchemaVersion != KnownSchema.GetVersion()) { throw new SchemaMissMatchException(); } Schema = KnownSchema; this.NrTotalPages = (int)(((double)Convert.ToInt32(Element.Attribute("totalpoints").Value) + 0.5) / (double)PointsPerPage); foreach (var it in Element.Elements(LWTSD.Namespace + "resource")) { ResourcePath Path = it.Attribute("path").Value; switch (KnownSchema.Resources[Path].SimpleType) { case SimplifiedType.String: Data.Add(new ResourceString(it)); break; case SimplifiedType.Integer: Data.Add(new ResourceInteger(it)); break; case SimplifiedType.Base64Binary: Data.Add(new ResourceBase64Binary(it)); break; case SimplifiedType.DateTime: Data.Add(new ResourceDateTime(it)); break; case SimplifiedType.Boolean: Data.Add(new ResourceBoolean(it)); break; case SimplifiedType.Decimal: Data.Add(new ResourceDecimal(it)); break; case SimplifiedType.Duration: Data.Add(new ResourceDuration(it)); break; case SimplifiedType.Float: Data.Add(new ResourceFloat(it)); break; case SimplifiedType.Time: Data.Add(new ResourceTime(it)); break; case SimplifiedType.Double: Data.Add(new ResourceDouble(it)); break; } } }
void HandleReadData(StanzaIQ Request) { XElement ReadDataElement = Request.Payload.Elements().First(); try { List <ResourceAccess> LimitedAccess = GetAccessRights(Request.From, LWTSD.GetAccessToken(ReadDataElement)); int maxpoints = XmlConvert.ToInt32(ReadDataElement.Attribute("maxpoints").Value); int startindex = XmlConvert.ToInt32(ReadDataElement.Attribute("startindex").Value); SortOrder OrderByTime = SortOrder.None; if (ReadDataElement.Attribute("orderedbytime") != null) { OrderByTime = SortOrderMethods.LoadFromString(ReadDataElement.Attribute("orderedbytime").Value); } StanzaIQ Response = new StanzaIQ(StanzaIQ.StanzaIQType.Result); Response.ID = Request.ID; Response.To = Request.From; XElement DataElement = new XElement(LWTSD.Namespace + "data"); List <Resource> MatchingResources = new List <Resource>(); foreach (XElement ReadElement in ReadDataElement.Elements(LWTSD.Namespace + "read")) { if (ReadElement.Attribute("maxpoints") != null) { if (XmlConvert.ToInt32(ReadElement.Attribute("maxpoints").Value) < 1) { throw new InvalidOperationException("Maxpoints < 0 in read"); } } if (ReadElement.Attribute("startindex") != null) { int localstartindex = XmlConvert.ToInt32(ReadElement.Attribute("startindex").Value); if (localstartindex < 1) { throw new InvalidOperationException("startindex < 0 in read"); } if (localstartindex > 1) { continue; // We only have one point / resource } } ResourcePath Path = ReadElement.Attribute("resource-path").Value; if (!ResourceAccess.AllowsRead(LimitedAccess, Path)) { throw new AccessViolation(); } if (!Resources.ContainsKey(Path)) { // Todo: Explicit exception to set proper error code throw new Exception("Path does not exist: " + Path); } Resource Res = Resources[Path]; if (!Res.SupportsRead) { throw new InvalidOperationException("Resource does not support read: " + Path); } MatchingResources.Add(Res); } lock (Schema) { int Index = 0; int ReturnedPoints = 0; foreach (Resource Res in MatchingResources) { if (Index < startindex) { Index++; continue; } if ((Index - startindex) >= maxpoints) { Index++; break; } Index++; ReturnedPoints++; XElement ResourceElement = new XElement(LWTSD.Namespace + "resource"); ResourceElement.SetAttributeValue("path", Res.Path); ResourceElement.SetAttributeValue("returnedpoints", "1"); ResourceElement.SetAttributeValue("totalpoints", "1"); XElement PointElement = Res.GetPoint(); ResourceElement.Add(PointElement); DataElement.Add(ResourceElement); } DataElement.SetAttributeValue("schemaversion", Schema.GetVersion()); DataElement.SetAttributeValue("returnedpoints", XmlConvert.ToString(ReturnedPoints)); DataElement.SetAttributeValue("totalpoints", XmlConvert.ToString(MatchingResources.Count)); } foreach (XElement ReSubscribeElement in ReadDataElement.Elements(LWTSD.Namespace + "re-subscribe")) { string localsid = ReSubscribeElement.Attribute("subscriptionid").Value; string sid = GetSafeSubscriptionID(Request.From, localsid); if (!Subscribers.ContainsKey(sid)) { throw new InvalidOperationException("Subscription ID does not exist: " + localsid); } Subscriber Subscription = Subscribers[sid]; Subscription.LastResubscribed = DateTime.UtcNow; } Response.Payload.Add(DataElement); Uplink.SendStanza(Response); } catch (System.Exception ex) { StanzaIQ ErrorResponse = new StanzaIQ(StanzaIQ.StanzaIQType.Error); ErrorResponse.ID = Request.ID; ErrorResponse.To = Request.From; XElement ErroReasonElement = new XElement(LWTSD.Namespace + "errorreason"); ErroReasonElement.SetAttributeValue("reason", ErrorReason.InvalidData); ErroReasonElement.Value = ex.ToString(); ErrorResponse.Payload.Add(ErroReasonElement); Uplink.SendStanza(ErrorResponse); } }