// called by socket reader to find the total read size public unsafe int ParseRequestHeader(int totalRead) { if (RequestBodyStart == 0) { RequestBodyStart = findHeaderEnd(totalRead); } if (RequestBodyStart > 0) { if (Method.IsEmpty) // headers unparsed { var headers = new AString(Buffer, 0, RequestBodyStart); while (headers.Length > 0) { // get the next line var i = headers.IndexOfCRLF(); if (i < 0) { break; } // get the next line and advance the header span var line = headers.Substring(0, i); headers = headers.Substring(i + 2); // remove leading spaces while (line.Length > 0 && line[0] < 'A') { line = line.Substring(1); } // skip the empty line if (line.Length == 0) { continue; } if (Method.IsEmpty) // first line is not parsed, so this is it { FirstLine = line; ParseFirstLine(line); } else // the only other line we are interested in is content-length if (RequestBodyLength == 0) { //var str = Encoding.ASCII.GetString(line); // for debugging, remove if (line.StartsWith(content_length)) { i = line.IndexOf((byte)':'); line = line.Substring(i + 2); line.TryToInt(out RequestBodyLength); } } } } return(ResponseStart); } return(0); }
// clean up before returning to the pool public DtoAccount Reset() { id = birth = joined = premium.start = premium.finish = 0; fnameIdx = snameIdx = cityIdx = countryIdx = 0; phone = email = AString.Empty; status = 0; sex = false; interests = new BitMap96(); likes.Clear(); flags = 0; return(this); }
public object Tag; // general tag // reset public void Reset() { Method = AString.Empty; Path = AString.Empty; Params.Clear(); QueryId = 0; RequestBodyStart = 0; RequestBodyLength = 0; //ResponseBodyStart = 0; //ResponseBodyLength = 0; StatusCode = 0; tcs = null; Tag = null; }
public AString areaCodeFromPhone(AString phone) { if (phone.IsEmpty) { return(AString.Empty); } var openBrace = phone.IndexOf('('); var closeBrace = phone.IndexOf(')'); if (openBrace >= 0 && closeBrace == openBrace + 4) { return(phone.Substring(openBrace + 1, 3)); } return(null); }
// string, not AString, as parameters can be non-ASCII public void ParseParams(AString paramStr) { Params.Clear(); paramStr = paramStr.InPlaceUrlDecode(); var paramParts = paramStr.Split('&'); for (int i = 0; i < paramParts.Length; i++) { var pp = paramParts[i].Split('='); Params.Add(pp[0].ToString(), pp[1].ToString()); if (pp[0] == "query_id") { pp[1].TryToInt(out QueryId); } } }
public void ParseFirstLine(AString firstLine) { var parts = firstLine.Split(' '); Trace.Assert(parts.Length == 3); Method = parts[0]; var pathParts = parts[1].Split('?'); Path = pathParts[0]; if (pathParts.Length == 1 || pathParts[1].IsEmpty) { Params.Clear(); } else { ParseParams(pathParts[1]); } }
public bool bufferFromEmail(AString email, out byte[] buffer) { var amp = email.IndexOf((byte)'@'); if (amp < 0 || amp == email.Length - 1) { buffer = null; return(false); } byte domainIdx = (byte)Domains.GetOrCreateRange(email.Substring(amp + 1)).Index; buffer = new byte[amp + 1]; for (int i = 0; i < amp; i++) { buffer[i] = email[i]; } buffer[amp] = domainIdx; return(true); }
private int emailHash(AString value) { if (value.Length == 4) // 2 characters, typical case { return((byte)value[0] << 24 | (byte)value[1] << 16 | (byte)value[2] << 8 | (byte)value[3]); } if (value.Length == 2) // less typical case { return((byte)value[0] << 24 | (byte)value[1] << 16); } if (value.Length == 3) { return((byte)value[0] << 24 | (byte)value[1] << 16 | (byte)value[2] << 8); } if (value.Length == 1) { return((byte)value[0] << 24); } return(0); }
// using low-level to catch wrong structure or properties // ids and likes are internalized public static bool Parse(ref JsonReader reader, DtoAccount dto, Storage store) { var count = 0; if (reader.ReadIsNull() || !reader.ReadIsBeginObject()) { return(false); } while (true) { var prop = reader.ReadPropertyNameSegmentRaw(); // id if (prop.EqualTo(s_id)) { if (reader.GetCurrentJsonToken() != JsonToken.Number) { return(false); } dto.id = Mapper.ExtIdToIntIdCreate(reader.ReadInt32()); dto.flags |= DtoFlags.Id; } else // status if (prop.EqualTo(s_status)) { var st = new AString(reader.ReadStringSegmentRaw()).InPlaceUnescape(); if (st == s_Free) { dto.status = STATUS_FREE; } else if (st == s_Taken) { dto.status = STATUS_TAKEN; } else if (st == s_Complicated) { dto.status = STATUS_COMPLICATED; } else { return(false); } dto.flags |= DtoFlags.Status; } else // sex if (prop.EqualTo(s_sex)) { var st = reader.ReadStringSegmentRaw(); if (st.EqualTo(s_male)) { dto.sex = SEX_MALE; } else if (st.EqualTo(s_female)) { dto.sex = SEX_FEMALE; } else { return(false); } dto.flags |= DtoFlags.Sex; } else // email if (prop.EqualTo(s_email)) { dto.email = reader.ReadStringSegmentRaw(); dto.flags |= DtoFlags.Email; } else // phone if (prop.EqualTo(s_phone)) { dto.phone = new AString(reader.ReadStringSegmentRaw()).Duplicate(); dto.flags |= DtoFlags.Phone; } else // fname if (prop.EqualTo(s_fname)) { dto.fnameIdx = (short)store.Fnames.GetOrCreateRange( new AString(reader.ReadStringSegmentRaw()).InPlaceUnescape()).Index; dto.flags |= DtoFlags.Fname; } else // sname if (prop.EqualTo(s_sname)) { dto.snameIdx = (short)store.Snames.GetOrCreateRange( new AString(reader.ReadStringSegmentRaw()).InPlaceUnescape()).Index; dto.flags |= DtoFlags.Sname; } else // country if (prop.EqualTo(s_country)) { dto.countryIdx = (byte)store.Countries.GetOrCreateRange( new AString(reader.ReadStringSegmentRaw()).InPlaceUnescape()).Index; dto.flags |= DtoFlags.Country; } else // city if (prop.EqualTo(s_city)) { dto.cityIdx = (short)store.Cities.GetOrCreateRange( new AString(reader.ReadStringSegmentRaw()).InPlaceUnescape()).Index; dto.flags |= DtoFlags.City; } else // birth if (prop.EqualTo(s_birth)) { if (reader.GetCurrentJsonToken() != JsonToken.Number) { return(false); } dto.birth = reader.ReadInt32(); dto.flags |= DtoFlags.Birth; } else // joined if (prop.EqualTo(s_joined)) { if (reader.GetCurrentJsonToken() != JsonToken.Number) { return(false); } dto.joined = reader.ReadInt32(); dto.flags |= DtoFlags.Joined; } else // premium if (prop.EqualTo(s_premium)) { if (!DtoPremium.Parse(ref reader, ref dto.premium)) { return(false); } dto.flags |= DtoFlags.Premium; } else // interests if (prop.EqualTo(s_interests)) { if (!reader.ReadIsBeginArray()) { return(false); } while (!reader.ReadIsEndArrayWithSkipValueSeparator(ref count)) { dto.interests.Set(store.Interests.GetOrCreateRange(new AString(reader.ReadStringSegmentRaw()).InPlaceUnescape()).Index); } dto.flags |= DtoFlags.Interests; } else // likes if (prop.EqualTo(s_likes)) { if (!reader.ReadIsBeginArray()) { return(false); } // read likes if (reader.GetCurrentJsonToken() == JsonToken.BeginObject) { while (true) { Like like = new Like(); if (!reader.ReadIsBeginObject()) { return(false); } while (true) { var propName = reader.ReadPropertyNameSegmentRaw(); if (propName[0] == (byte)'t') // ts { if (reader.GetCurrentJsonToken() != JsonToken.Number) { return(false); } like.ts = Like.ExtToIntTS(reader.ReadInt32()); } else if (propName[0] == (byte)'i') // id { if (reader.GetCurrentJsonToken() != JsonToken.Number) { return(false); } if (!Mapper.ExtIdToIntId(reader.ReadInt32(), out like.id)) { return(false); } } else // not ts nor id { return(false); } if (!reader.ReadIsValueSeparator()) { break; } } if (!reader.ReadIsEndObject()) { return(false); } dto.likes.Add(like); if (!reader.ReadIsValueSeparator()) { break; } } } if (!reader.ReadIsEndArray()) { return(false); } dto.flags |= DtoFlags.Likes; } else { return(false); } if (!reader.ReadIsValueSeparator()) { break; } } if (!reader.ReadIsEndObject()) { return(false); } return(true); }