[prev in list] [next in list] [prev in thread] [next in thread] 

List:       xalan-dev
Subject:    Re: XPath Function Internals
From:       Gareth Reakes <gareth () we7 ! com>
Date:       2012-07-31 6:14:17
Message-ID: 62CE158A-14B2-407A-A356-FF7B10F02B54 () we7 ! com
[Download RAW message or body]

Hey,

	At 1 point it was an path 1 implementation. I can't recall what kind of a test suite \
it had then but its probably still worth a look. If you have trouble finding the code \
base for that time period drop me a line and I will see what I can do.

G


On 30 Jul 2012, at 17:28, shathawa@e-z.net wrote:

> Gareth,
> 
> Thanks for the link.  Our first priority is to get additional functionality
> with XPath 1.0 and EXSLT functions.
> 
> I am interested in pursuing the XPath2 integration after our XalanC 1.11
> product is released at the end of summer.  I see this XPath2 integration
> to become XalanC 2.0.
> 
> Sincerely,
> Steven J. Hathaway
> GSoC 2012 mentor
> 
> > Hey Samuel,
> > 
> > 	A long while ago I was one of the people who wrote Pathan (an XPath2
> > implementation on top of Xerces C). Its been replaced with XQilla now
> > (http://xqilla.sourceforge.net/HomePage). I expect its worth a look for
> > function implementations. We also had a thorough test suite which could
> > still be there / be of use.
> > 
> > Cheers,
> > 
> > G
> > 
> > 
> > On 30 Jul 2012, at 03:06, Steve Hathaway wrote:
> > 
> > > Samuel - GSOC 2012
> > > 
> > > You're doing good.
> > > 
> > > It looks like you understand the basics of the XPath function class that
> > > needs to be extended
> > > and customizing the appropriate execute() methods.
> > > 
> > > Here are some comments:: Ref: file OspXpathConvertDate.cpp from zip
> > > example.
> > > 
> > > YourXPathFunction::execute(
> > > XPathExecutionContext & executionContext,
> > > XalanNode *           context,  /*may not be needed*/
> > > const XObjectPtr      arg1,
> > > const XObjectPtr      arg2,
> > > const LocatorType *   locator   /*may not be needed*/
> > > ) const
> > > {
> > > CharVectorType  theFirstArg;
> > > char *          charFirstArg;
> > > CharVectorType  theSecondArg;
> > > char *          charSecondArg;
> > > 
> > > MemoryManager * theManager = executionContext.getMemoryManager();
> > > 
> > > theFirstArg = TranscodeToLocalCodePage(arg1->str());
> > > charFirstArg = theFirstArg.begin();
> > > 
> > > theSecondArg = TranscodeToLocalCodePage(arg2->str());
> > > charSecondArg = theSecondArg.begin();
> > > 
> > > /* NOTES
> > > *
> > > * TransCodeToLocalCodePage()
> > > *   creates a new instance of CharVectorType containing
> > > *   converted transformed Unicode to the host character set
> > > (ASCII/EBCDIC...)
> > > *
> > > * The CharVectorType.begin() method returns a pointer to the
> > > * null-terminated character string.  This string is owned by the
> > > CharVectorType
> > > * class.  This CharVectorType class is a local variable with local
> > > scope.
> > > * The allocation for CharVectorType will be properly destroyed when the
> > > * execute() method returns.
> > > *
> > > * You should not access the m_data storage variable directly, but
> > > instead
> > > * use the access method begin() to ensure a proper address.
> > > *
> > > * Note also that XalanDOMString may not be what you want.  Its native
> > > * character storage is 16-bit characters (UTF-16) encoding.
> > > *
> > > * The above sample I have shown here will give you standard 'C' strings
> > > * extracted from the XPath function arguments in a safe way.
> > > *
> > > * The XalanDOMString class does know how to import data from (char *)
> > > * strings.
> > > */
> > > 
> > > char * charResult;
> > > charResult = someFunction(...) // returning a pointer to type (char *);
> > > 
> > > // The following creates a XalanDOMString and initializes it with
> > > charResult.
> > > // Declaring XalanDOMString as a local instance, it will be destroyed
> > > when
> > > // the execute method exits.
> > > 
> > > XalanDOMString theResult(charResult);
> > > 
> > > // You may need to free the memory associated with the charResult
> > > pointer
> > > // before you return.  After charResult is saved in a XalanDOMString,
> > > you
> > > // should be able to release owhership of the (char *) pointer and free
> > > the
> > > // (char *) allocation.
> > > 
> > > free(charResult);  // or program specific equivalent.
> > > 
> > > // The execution.GetXObjectFactory() creates a XObjectPtr to data owned
> > > // by the XObjectFactory.  This content is returned to the XPath
> > > // interpreter execution context.
> > > 
> > > return executionContext.getXObjectFactory().createString(theResult);
> > > 
> > > }
> > > 
> > > /*
> > > * Create an error reporter
> > > */
> > > const XalanDOMString &
> > > YourXPathFunction::getError(XalanDOMString & theResult) const
> > > {
> > > return XalanMessageLoader::getMessage(
> > > theResult,
> > > XalanMessages::FunctionTakesTwoArguments_1Param,
> > > "name of you XPath Function");
> > > }
> > > 
> > > /* NOTE:
> > > * The example error reporter.
> > > * The XalanMessageLoader::getMessage(...) prepares a standard message
> > > * showing theResult, "The function '(0)' requires two arguments."
> > > * with '(0)' replaced with "name of your XPath Function");
> > > *
> > > * If you need messages that are not in the NLS library, we can create
> > > * new message templates and put them into the NLS library.
> > > *
> > > * FunctionTakesTwoArguments_1Param is an address to the NLS string:
> > > * "The function '(0)' requires two arguments."
> > > */
> > > 
> > > 
> > > Sincerely,
> > > Steven J. Hathaway
> > > 
> > > 
> > > 
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
> > > For additional commands, e-mail: xalan-dev-help@xml.apache.org
> > > 
> > > 
> > 
> > --
> > Gareth Reakes, CTO         WE7 - Great Music, Free
> > +44-20-7117-0809                    http://www.we7.com
> > 
> > “The music business is a cruel and shallow money trench, a long plastic
> > hallway where thieves and pimps run free, and good men die like dogs.
> > There's also a negative side. “
> > - Hunter S. Thompson
> > 
> > 
> > 
> > 
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: xalan-dev-unsubscribe@xml.apache.org
> For additional commands, e-mail: xalan-dev-help@xml.apache.org
> 
> 

-- 
Gareth Reakes, CTO         WE7 - Great Music, Free
+44-20-7117-0809                    http://www.we7.com

“The music business is a cruel and shallow money trench, a long plastic hallway where \
thieves and pimps run free, and good men die like dogs. There's also a negative side. \
                “
- Hunter S. Thompson


[Attachment #3 (unknown)]

<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; \
-webkit-line-break: after-white-space; "><div>Hey,</div><div><br></div><div><span \
class="Apple-tab-span" style="white-space:pre">	</span>At 1 point it was an path 1 \
implementation. I can't recall what kind of a test suite it had then but its probably \
still worth a look. If you have trouble finding the code base for that time period \
drop me a line and I will see what I can \
do.</div><div><br></div><div>G</div><div><br></div><br><div><div>On 30 Jul 2012, at \
17:28, <a href="mailto:shathawa@e-z.net">shathawa@e-z.net</a> wrote:</div><br \
class="Apple-interchange-newline"><blockquote type="cite"><div>Gareth,<br><br>Thanks \
for the link. &nbsp;Our first priority is to get additional functionality<br>with \
XPath 1.0 and EXSLT functions.<br><br>I am interested in pursuing the XPath2 \
integration after our XalanC 1.11<br>product is released at the end of summer. \
&nbsp;I see this XPath2 integration<br>to become XalanC \
2.0.<br><br>Sincerely,<br>Steven J. Hathaway<br>GSoC 2012 mentor<br><br><blockquote \
type="cite">Hey Samuel,<br></blockquote><blockquote \
type="cite"><br></blockquote><blockquote type="cite"><span class="Apple-tab-span" \
style="white-space:pre">	</span>A long while ago I was one of the people who wrote \
Pathan (an XPath2<br></blockquote><blockquote type="cite">implementation on top of \
Xerces C). Its been replaced with XQilla now<br></blockquote><blockquote \
type="cite">(<a href="http://xqilla.sourceforge.net/HomePage">http://xqilla.sourceforge.net/HomePage</a>). \
I expect its worth a look for<br></blockquote><blockquote type="cite">function \
implementations. We also had a thorough test suite which \
could<br></blockquote><blockquote type="cite">still be there / be of \
use.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote \
type="cite">Cheers,<br></blockquote><blockquote \
type="cite"><br></blockquote><blockquote type="cite">G<br></blockquote><blockquote \
type="cite"><br></blockquote><blockquote type="cite"><br></blockquote><blockquote \
type="cite">On 30 Jul 2012, at 03:06, Steve Hathaway \
wrote:<br></blockquote><blockquote type="cite"><br></blockquote><blockquote \
type="cite"><blockquote type="cite">Samuel - GSOC \
2012<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">You're doing good.<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">It looks like you understand the basics of the \
XPath function class that<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">needs to be \
extended<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">and customizing the appropriate execute() \
methods.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">Here are some comments:: Ref: file OspXpathConvertDate.cpp from \
zip<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">example.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">YourXPathFunction::execute(<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> XPathExecutionContext &amp; \
executionContext,<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"> XalanNode * \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;context, &nbsp;/*may not \
be needed*/<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"> const XObjectPtr \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg1,<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> const XObjectPtr \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arg2,<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> const LocatorType * &nbsp;&nbsp;locator \
&nbsp;&nbsp;/*may not be needed*/<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">) const<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">{<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> CharVectorType \
&nbsp;theFirstArg;<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"> char * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charFirstArg;<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> CharVectorType \
&nbsp;theSecondArg;<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"> char * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;charSecondArg;<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> MemoryManager * theManager = \
executionContext.getMemoryManager();<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> theFirstArg = \
TranscodeToLocalCodePage(arg1-&gt;str());<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> charFirstArg = \
theFirstArg.begin();<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"> theSecondArg = \
TranscodeToLocalCodePage(arg2-&gt;str());<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> charSecondArg = \
theSecondArg.begin();<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">/* NOTES<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">*<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* \
TransCodeToLocalCodePage()<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* &nbsp;&nbsp;creates a new instance of \
CharVectorType containing<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* &nbsp;&nbsp;converted transformed Unicode to \
the host character set<br></blockquote></blockquote><blockquote \
type="cite"><blockquote \
type="cite">(ASCII/EBCDIC...)<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">*<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* The CharVectorType.begin() method returns a \
pointer to the<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* null-terminated character string. &nbsp;This string is owned by \
the<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">CharVectorType<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* class. &nbsp;This CharVectorType class is a \
local variable with local<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">scope.<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* The allocation for CharVectorType will be \
properly destroyed when the<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* execute() method \
returns.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* You should not access the m_data storage variable directly, \
but<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">instead<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* use the access method begin() to ensure a proper \
address.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* Note also that XalanDOMString may not be what you want. &nbsp;Its \
native<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">* \
character storage is 16-bit characters (UTF-16) \
encoding.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* The above sample I have shown here will give you standard 'C' \
strings<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* extracted from the XPath function arguments in a safe \
way.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* The XalanDOMString class does know how to import data from (char \
*)<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">* \
strings.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*/<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">char * charResult;<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">charResult = someFunction(...) // returning a \
pointer to type (char *);<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">// The following creates a XalanDOMString and \
initializes it with<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">charResult.<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">// Declaring XalanDOMString as a local instance, \
it will be destroyed<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">when<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">// the execute method exits.<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">XalanDOMString \
theResult(charResult);<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">// You may need to free the memory associated \
with the charResult<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">pointer<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">// before you return. &nbsp;After charResult is saved in a \
XalanDOMString,<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">you<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">// should be able to release owhership of the (char *) pointer and \
free<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">the<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">// (char *) allocation.<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">free(charResult); &nbsp;// or program specific \
equivalent.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">// The execution.GetXObjectFactory() creates a XObjectPtr to data \
owned<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">// \
by the XObjectFactory. &nbsp;This content is returned to the \
XPath<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">// \
interpreter execution context.<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">return \
executionContext.getXObjectFactory().createString(theResult);<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">}<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">/*<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* Create an error \
reporter<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*/<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">const XalanDOMString &amp;<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">YourXPathFunction::getError(XalanDOMString &amp; \
theResult) const<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">{<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"> return XalanMessageLoader::getMessage(<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> \
&nbsp;&nbsp;theResult,<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> \
&nbsp;&nbsp;XalanMessages::FunctionTakesTwoArguments_1Param,<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite"> &nbsp;&nbsp;"name of you XPath \
Function");<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">}<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">/* NOTE:<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* The example error reporter.<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* The XalanMessageLoader::getMessage(...) \
prepares a standard message<br></blockquote></blockquote><blockquote \
type="cite"><blockquote type="cite">* showing theResult, "The function '(0)' requires \
two arguments."<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* with '(0)' replaced with "name of your XPath \
Function");<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* If you need messages that are not in the NLS library, we can \
create<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">* \
new message templates and put them into the NLS \
library.<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* FunctionTakesTwoArguments_1Param is an address to the NLS \
string:<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">* "The function '(0)' requires two \
arguments."<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite">*/<br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote \
<span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); \
font-family: Helvetica; font-size: medium; font-style: normal; font-variant: normal; \
font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; \
text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; \
widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; \
-webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; \
-webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><span \
class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); \
font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; \
font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; \
text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: \
0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; \
-webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; \
-webkit-text-stroke-width: 0px; "><div style="word-wrap: break-word; \
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space; \
"><div>--&nbsp;<br>Gareth Reakes, CTO &nbsp; &nbsp; &nbsp; &nbsp; WE7 - Great Music, \
Free<br>+44-20-7117-0809 \
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a \
href="http://www.we7.com/">http://www.we7.com</a></div><div><br></div></div></span><span \
class="Apple-style-span" style="font-size: 12px; "><div>“The music business is a \
cruel and shallow money trench, a long plastic hallway where thieves and pimps run \
free, and good men die like dogs. There's also a negative side. “</div><div>- Hunter \
S. Thompson</div><div><br></div></span></span><br class="Apple-interchange-newline"> \
</div> <br></body></html>



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic