rdfutil.cpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. /*
  6. Implementations for a bunch of useful RDF utility routines. Many of
  7. these will eventually be exported outside of RDF.DLL via the
  8. nsIRDFService interface.
  9. TO DO
  10. 1) Make this so that it doesn't permanently leak the RDF service
  11. object.
  12. 2) Make container functions thread-safe. They currently don't ensure
  13. that the RDF:nextVal property is maintained safely.
  14. */
  15. #include "nsCOMPtr.h"
  16. #include "nsIRDFDataSource.h"
  17. #include "nsIRDFNode.h"
  18. #include "nsIRDFService.h"
  19. #include "nsIServiceManager.h"
  20. #include "nsIURL.h"
  21. #include "nsIIOService.h"
  22. #include "nsIURL.h"
  23. #include "nsRDFCID.h"
  24. #include "nsString.h"
  25. #include "nsXPIDLString.h"
  26. #include "nsUnicharUtils.h"
  27. #include "rdfutil.h"
  28. #include "prtime.h"
  29. ////////////////////////////////////////////////////////////////////////
  30. nsresult
  31. rdf_MakeRelativeRef(const nsCSubstring& aBaseURI, nsCString& aURI)
  32. {
  33. // This implementation is extremely simple: e.g., it can't compute
  34. // relative paths, or anything fancy like that. If the context URI
  35. // is not a prefix of the URI in question, we'll just bail.
  36. uint32_t prefixLen = aBaseURI.Length();
  37. if (prefixLen != 0 && StringBeginsWith(aURI, aBaseURI)) {
  38. if (prefixLen < aURI.Length() && aURI.CharAt(prefixLen) == '/')
  39. ++prefixLen; // chop the leading slash so it's not `absolute'
  40. aURI.Cut(0, prefixLen);
  41. }
  42. return NS_OK;
  43. }
  44. void
  45. rdf_FormatDate(PRTime aTime, nsACString &aResult)
  46. {
  47. // Outputs Unixish date in GMT plus usecs; e.g.,
  48. // Wed Jan 9 19:15:13 2002 +002441
  49. //
  50. PRExplodedTime t;
  51. PR_ExplodeTime(aTime, PR_GMTParameters, &t);
  52. char buf[256];
  53. PR_FormatTimeUSEnglish(buf, sizeof buf, "%a %b %d %H:%M:%S %Y", &t);
  54. aResult.Append(buf);
  55. // usecs
  56. aResult.AppendLiteral(" +");
  57. int32_t usec = t.tm_usec;
  58. for (int32_t digit = 100000; digit > 1; digit /= 10) {
  59. aResult.Append(char('0' + (usec / digit)));
  60. usec %= digit;
  61. }
  62. aResult.Append(char('0' + usec));
  63. }
  64. PRTime
  65. rdf_ParseDate(const nsACString &aTime)
  66. {
  67. PRTime t;
  68. PR_ParseTimeString(PromiseFlatCString(aTime).get(), true, &t);
  69. int32_t usec = 0;
  70. nsACString::const_iterator begin, digit, end;
  71. aTime.BeginReading(begin);
  72. aTime.EndReading(end);
  73. // Walk backwards until we find a `+', run out of string, or a
  74. // non-numeric character.
  75. digit = end;
  76. while (--digit != begin && *digit != '+') {
  77. if (*digit < '0' || *digit > '9')
  78. break;
  79. }
  80. if (digit != begin && *digit == '+') {
  81. // There's a usec field specified (or, at least, something
  82. // that looks close enough. Parse it, and add it to the time.
  83. while (++digit != end) {
  84. usec *= 10;
  85. usec += *digit - '0';
  86. }
  87. t += usec;
  88. }
  89. return t;
  90. }