This refers to transforming or changing the characteristics of a signal to make it more suitable for some intended application, usually for transmission from one location to another or for storage onto some medium that is different than the original medium. Coding can improve fidelity, optimize carrier bandwidth, increase essence carriage, improve security or provide error detection and correction.
Friday, February 29, 2008
Developing AJAX Applications
AJAX is the buzzword of the moment among web developers, so much so that you could be sick of introductions to AJAX by now (if that's the case, skip down to "The Chat Web Page"). AJAX is a technology that is hotly debated from many angles, but it has stuck because it encapsulates something that is new from a user's perspective. The functionally that is newly available to all web users is "in-page replacement": the ability for a web page to change using data from a web server without totally redrawing itself. This functionality has been around in Mozilla and Internet Explorer for a while, but it is only recently that Safari and Konqueror users have been able to join in.
It is this ability to have web pages that update dynamically that is changing the way users interact with the web. For example:
Activity Old Style AJAX Style Scrolling in a mapping website Click on a right arrow to refresh whole page. Drag map area to the right--and watch the map scroll, like Google Maps. Looking up a word in a dictionary Enter the word, and click Submit to see a definition for that word. Begin typing the word, see possible matches as you type and the definitions as soon as you finish typing, like ObjectGraph Dictionary. Interacting in online forum Type message, click Submit, regularly click "check new messages". Type messages, and wait as new replies appear automatically without needing your interaction. We will create a site like this in this article. Filling out form with a number of fields Visit a number of pages of a "wizard," getting error messages about invalid fields. Fill out a form that reports on errors as you type, and can dynamically add data (like filling in full address details from a zip code) without needing a slow page refresh.
AJAX isn't the best acronym in the world: it stands for Asynchronous JavaScript and XML. This does nothing to describe the benefits to a user: the technology behind it does not have to be asynchronous, and the best implementations don't necessarily use XML, either. However, the buzzword has stuck so we are better off going with the flow now.
The problem for the web developer is that while this is a very attractive way of creating websites, and one where you can get started without a huge amount of effort, there are a number of pitfalls that can make life harder. All browsers have different quirks, so you can easily discover that, for example, you have locked Mac users out of the party.
DWR, hosted on java.net, is an Java open source library that helps developers to write websites that include AJAX technology. Its mantra is "Easy Ajax for Java." It allows code in a web browser to use Java functions running on a web server as if they were in the browser.
This article demonstrates the use of DWR to create a multi-user web-based chat site. It demonstrates how simple it is to integrate JavaScript in the web browser with Java on the server. The aim is to have a fully functional system in about 100 lines of code for both the client and the server. The emphasis will not be on fancy graphics or lots of chat features, because that would distract us from the core business of how to write AJAX code without lots of effort.
The Chat Web Page The web page has two parts: one area where you can see the messages that others type, and an input field where you can type messages yourself. Figure 1 shows what it looks like.
Figure 1. The chat web page The HTML is very simple:
Messages:
Your Message:
We'll come to the JavaScript code in a bit, but let's start with the server side. Just how much code do you need for a multi-user web-based chat system?
Server-Side Java We have two classes to do the server-side work. The first is the Message class that holds a single string entered by the user. The Message also maintains a unique ID as a property. For now, we are going to cheat by using the current time in milliseconds as the ID:
public class Message { public Message(String newtext) { text = newtext; if (text.length() > 256) { text = text.substring(0, 256); } text = text.replace('<', '['); text = text.replace('&', '_'); } public long getId() { return id; } public String getText() { return text; } long id = System.currentTimeMillis(); String text; } The constructor does a few simple things: it shortens messages to 256 characters and replaces <> 0) { messages.addFirst(new Message(text)); while (messages.size() > 10) { messages.removeLast(); } }
return messages; }
public List getMessages() { return messages; }
static LinkedList messages =new LinkedList(); }
And that's it for the server-side code!
Two of these methods are important from the web browser's point of view: addMessage(), which is called in response to a user typing in the input area, and getMessages(), which is polled from time to time to see if anyone else has said anything.
Configuring DWR Now we need to remote these two methods to the web browser. The first step is to copy dwr.jar into your web app. You can download dwr.jar from its java.net project. Next, you need to configure your app server's web.xml to understand DWR. The standard bit of code looks like this:
Finally, you need to tell DWR about the chat server you just created. Specifically, you need to tell it two things:
That Chat is safe to be remoted to the browser. That Message is allowed as a parameter. DWR could do the second bit for you, but we'll do it this way to make sure that you don't give away access to anything by mistake. The DWR configuration file, dwr.xml, is placed alongside web.xml in your WEB-INF folder. For your chat application, dwr.xml should look like this (obviously, replace the [your.package] bits with the package that you used from the code above):
We are telling DWR it is OK to create Chat classes for remoting to the browser, and that in JavaScript they will be called 'Chat'. It also says that Message is safe to use as a parameter.
The Client-Side Scripting The final bit is the JavaScript that is fired off by the HTML to call into the Java code. The good news is that DWR makes this bit easy. Typically, the JavaScript code for this type of thing would contain complex XMLHttpRequest code, DOM manipulation, and parameter collation. With DWR, you don't worry about any of that.
First we include the JavaScript that tells the browser about the Chat code. There are there useful script lines:
The script engine.js contains the core of DWR. Generally, you just include it as is, and then ignore it. There are a few methods in it that are sometimes useful, but you can see the full documentation for them at the DWR website. The script util.js contains some utility functions that are totally optional, but will help you greatly in getting anything done with DWR. Chat.js is dynamically generated by DWR as the remote version of Chat.java. If you look at it, you'll see something like this:
DWR does everything it can to make the JavaScript version of your Java code as simple as possible, but there are some things you need to be aware of. The most obvious is that the "A" in AJAX stands for asynchronous; so by definition, the remote method is not executed the instant your JavaScript code is executed. This would not be an issue, except for the complexity of knowing what to do with the values returned by Java to the browser. DWR solves the problem by asking for a callback method, to which it will pass the returned data. The first parameter to any DWR-generated method is always the callback function.
Above, we created a web page with a JavaScript function that we've not implemented, until now: the sendMessage() event is fired off by the browser whenever the "send" button is pressed. As you might guess, this is going to call Chat.addMessage():
function sendMessage() { var text = DWRUtil.getValue("text"); DWRUtil.setValue("text", ""); Chat.addMessage(gotMessages, text); }
The first line gets the value from the input field. DWRUtil.getValue() works with most HTML elements, so long as they have an id attribute (in this case, the input element has an id="text").
Next, we use the setValue() method to blank out the input element; again, the setValue() is very smart at working out what to do with your data and how it should update your web page with the new data.
Then we call Chat.addMessage() and ask DWR to return the list of messages typed by other web users to the gotMessages() function. It looks like this:
function gotMessages(messages) { var chatlog = ""; for (var data in messages) { chatlog = "
This is where DWR excels. The Java method Chat.addMessage() returned a List of Message objects. DWR has automatically converted this into an array of JavaScript objects. All we need to do in gotMessages() is to iterate over the messages array, getting the text member from each object in the array, and build some HTML from it. Finally, we push the string we have created into the div using the ever-versatile setValue() method.
And that's it! We have a basic multi-user, web-based chat system in about 100 lines of code, for both the client and server code.
There are a number of things missing for this to be useful: a polling method that uses setTimeout() to call Chat.getMessages() would keep things flowing a bit more. The downloaded code contains an extra six lines of JavaScript to make this happen. We could also add code to only alter the display if new messages have arrived; this would make for a flicker-free display. Finally, having a back-off mechanism where the browsers poll the server less often if nothing much is happening would be a good idea to prevent swamping the server.
You can see the final version here. It adds the features listed above, plus highlighting of new messages--all of which takes an extra 50 or so lines of JavaScript.
It is also worth checking out http://localhost:8080/[YOUR-WEB-APP]/dwr, which is a test debug page that automatically shows you the classes you have remoted, and allows you to test their functionality.
Conclusion Using DWR can make creating cross-browser AJAX websites very easy, and introduces a very neat way to interact between JavaScript in the web browser and Java on the server. It is simple to get started with and integrates well with your current website
This is a problem that we see a lot in .NET as well as programming in general these days. There are a lot of good ideas built into .NET and more ideas that are just carried forward for compatibility's sake. In particular, there are a lot of methods to choose from if you need to save a little configuration data for your program.
This article will describe the various ways that this can be done, but we'll finish up with a very simple example - complete with the downloadable source - showing what I think is the easiest way to save a few data items between program executions: native XML.
From a historical perspective, configuration information used to be saved in simple text files. You may still see a file named "settings.txt" or "config.txt" even today. In their latest book (Visual Basic 2005 for Programmers, 2nd Edition, Paul J. Deitel, Harvey M. Deitel, ISBN: 0-13-225140-X), the Deitel Developer Series has a major section showing how to create and read what is actually a "comma separated value" (CSV) file - an idea that is decades old. (Their goal is to demonstrate stream oriented sequential file processing, but the end result is the same.)
The next step up the ladder was to require some structure for configuration files. The best example is proably the .INI files. Here's what a typical .INI file looks like (from Wikipedia):
[section1]
; some comment on section1 var1 = foo var2 = doodle
[section2]
; another comment var1 = baz var2 = shoodle
These types of files were very typical when Windows 3.1 was the hot OS, even though Windows itself used config.sys and autoexec.bat for most startup configuration.
Then the thinking shifted to another idea: Put all your eggs in one basket and then watch that basket !! The "basket" is the Windows registry and it's still used for most of the Windows OS information. The next version of Windows, Vista, will continue to use the registry in just about the same way. In the era of Windows 2000 and Windows NT, creating lots of little .INI files was discouraged and programmers were encouraged to put their own program configuration information in the registry too, but we have discovered now that stuffing everything into one basket has it's own set of problems. So while COM, the technology used in VB 6, required that DLL's be "registered" .NET does not. VB.NET does provide excellent support for saving configuration information in the registry using the My.Computer.Registry object that is new in Framework 2.0 if that's the way you want to go.
The idea of using individual configuration files - information that is only used by your program in a few small files in the program folder - gets a lot more respect these days, thanks in no small measure to .NET. After all, Visual Studio will create a couple of dozen different files for even the simplest Windows application filled with exactly this kind of information.
But there are still more options to be considered.
The new buzzword for writing a file these days is "persist" -- as in "Persisting an Object" or "Persist an ADO.NET DataSet" (titles taken directly from Microsoft's web site). I used to call it, "saving an object" or "writing a dataset" but I guess I'll have to catch up with the times and start saying "persist" now. The idea is that some result of the program lasts after the program stops running and is restored when the program starts up again. The dictionary definition of "persist" is "to exist in spite of adversity." Being removed from computer memory is an example of adversity, I suppose.
You can persist information in several formats, however. We started the article by considering CSV and INI files, but there are more formats available now. VB.NET has excellent objects that help you serialize data to binary files, SOAP files, or XML files. Serialization is just the process of converting an object into a linear sequence of bytes. You can read more about serialization in lesson 3 from an About Visual Basic email tutorial. Microsoft's own Visual Studio will save configuration data in binary, XML, and proprietary formats. You can find examples in Microsoft's MSDN web site about how to persist data in all of these formats.
The code . . . In my opinion, however, if you want your program to be as easy to understand as possible, and you want the data itself to be easy-to-read text too, then creating a configuration file using XML methods is probably the way to go. Most modern programming technologies now completely support XML and you can open an XML file in either Notepad or most browsers to see what's in it. Writing the file directly with XML methods in VB.NET makes what is happening as clear as possible in the program code. The alternative of "serializing" to an XML file does a lot of the work for you but also makes the creation of the XML a "black box". The example you will see here puts it all out there in the open.
As an example of an alternative, here's a program designed to be used as a desktop utility for simple calculations of stock market prices and amounts.
The starting values are set using an XML configuration file. The starting values that will be used the next time the program is loaded can be set using an update routine that overwrites the XML file with new values. The illustration below shows the XML file displayed in IE. (IE is one of the best XML utilities!) The first task for the program is to write the XML file. The code that writes the XML file is shown below.
Dim Doc As New XmlDocument 'Create a 'vanilla' XML Declaration (processing instruction) Dim myXmlDeclaration As XmlDeclaration myXmlDeclaration = _ Doc.CreateXmlDeclaration("1.0", "UTF-8", "yes") Doc.AppendChild(myXmlDeclaration) ' <-Root Created Dim Root As XmlElement Root = Doc.CreateElement("StockCalcDefaults") 'Create a company name child node Dim Child As XmlElement Child = Doc.CreateElement("companyName") Child.InnerText = companyName.Text Root.AppendChild(Child) 'Create a Buy Price child node Child = Doc.CreateElement("buyPrice") Child.InnerText = _ CStr(Decimal.Round(buyPrice.Value, 2)) Root.AppendChild(Child) 'Create a Sell Price child node Child = Doc.CreateElement("sellPrice") Child.InnerText = _ CStr(Decimal.Round(sellPrice.Value, 2)) Root.AppendChild(Child) 'Create a Number of Shares child node Child = Doc.CreateElement("numShares") Child.InnerText = CStr(numShares.Value) Root.AppendChild(Child) 'Add an attribute to the child node Dim Attr As XmlAttribute Attr = Doc.CreateAttribute("incByThousand") Attr.Value = CStr(incByThousand.Checked) Child.Attributes.Append(Attr) 'Create a Profit Amount child node Child = Doc.CreateElement("profitAmount") Child.InnerText = _ CStr(Decimal.Round(profitAmount.Value, 2)) Root.AppendChild(Child) ' <-Root Added to Doc Doc.AppendChild(Root) 'Write XML to a file Dim Output As New XmlTextWriter( _ "StockDefaults.xml", _ System.Text.Encoding.UTF8) ' <-Document Written Doc.WriteTo(Output) Output.Close()
How the code works There are a lot of lines of code here, but they fit into some neat categories that will help you understand what they do.
When programming XML, you have to learn to "think" XML first. The most fundamental organization of XML is a hierarchy. So, rather than writing the XML line-by-line as you might expect in a sequential file, the most direct way to write an XML file is to create it node-by-node and then write it. There are other techniques and you might want to experiment. You might find one that fits your way of thinking about it better.
In this program, the first statements create the XML declaration. This identifies the file as an XML file and is strictly required. Then a root node is created and populated with all of the content: child nodes and any XML attributes.
(This program includes just one XML attribute, incByThousand, to the numShares element.) Finally the root node is appended to the XML document and the whole thing is written to a file. No path information is provided so this file is written to the same folder that the executable is in. I used the same names for the XML elements and attributes as I used for VB program variables just to make things easier to code. This isn't required. In this program, reading the XML document back again requires you to change your thinking back to a sequential mode. Although Microsoft's System.Xml namespace gives you the tools to zero in on exactly what you need, in this case it's easiest to simply read through the XML in sequence and assign the data back into variables. I do this in the Load event for the form. A Do While loop moves through the XML document from front to back and a Select Case block simply extracts the values that the program needs.
One interesting sidenote that contributes to confusion is that the Value property of an XML node can be used some of the time and some of the time it can't. The Tool-Tip unhelpfully tells us that Value "Gets the text value of the current node."
Not exactly right.
For example, this statement compiles, but creates an exception when the program runs:
Child.Value = companyName.Text
This statement works fine when the node type is an attribute but always assigns a null reference when the node type is an element.
varName = Input.Value
This MSDN page tells you when it works and when it doesn't. Although their documentation could be a lot more clear about why things work this way, you can't really blame Microsoft for the problem. The cause is the very exact way that XML works. For example, a node in XML might look like this:
FirstDataSecondData
What's the "value" of the element node? Is it "FirstData"? Or "FirstDataSecondData"? Microsoft's very complete System.Xml namespace has methods to deal with every possibility, but some of them don't make sense until you have more experience with XML.
!dump – Dump memory to disk Example: !dump \??\c:\unpackedmalware.bin 400000 fc00 Very useful, for example, if a malware was compressed with an unknown packer before. The first parameter is the file to write, the second is the start address and the third is the length. !dumpscreen – Dump SoftICE screen to disk in RAW format Example: !dumpscreen \??\c:\SoftICEScreen.raw In cases where you don’t have the debugger running under VMWare it isn’t possible to make a snapshot of the current SoftICE screen. The feature !dumpscreen eliminates this obstacle. To convert the saved .raw file into a .bmp file use the tool SiwRender. This commandline tool can be found in the directory %ProgramFiles%\IceExt\SiwRender. Before the tool is used assure that the settings in the SiwRender.ini are equal to your current SoftICE window settings, eg font, width and height. Otherwise adjust them like in the example below. SiwRender.ini: [Main] FontName = 8x8std.fnt FontWidth = 8 FontHeight = 8 ScreenWidth = 80 ScreenHeight = 90 !protect – Turn SoftICE protection on/off Example: !protect on Some applications and malware use several techniques to protect themselves from getting debugged. This nice feature works as a bypass for some of the common Anti-SoftICE tricks. It protects from MeltICE, UEF tricks, NtQuerySystemInformation and CR4 Debug Extensions bit protection.
Setting the right breakpoint – Useful APIs If a reverser searches for a special action in an application it’s important to know which API calls the system might use. Below is a categorized list of calls, often used in programs. File: CreateFileA / CreateFileW ReadFile ReadFileEx WriteFile WriteFileEx SetFilePointer SetFilePointerEx GetSystemDirectoryA / GetSystemDirectoryW GetFileAttributesA / GetFileAttributesW GetFileAttributesExA / GetFileAttributesExW GetFileSize GetFileSizeEx GetDriveTypeA / GetDriveTypeW GetLastError INI-File: GetPrivateProfileStringA / GetPrivateProfileStringW GetPrivateProfileIntA / GetPrivateProfileIntW GetPrivateProfileSectionA / GetPrivateProfileSectionW GetPrivateProfileStructA / GetPrivateProfileStructW WritePrivateProfileStringA / WritePrivateProfileStringW WritePrivateProfileSectionA / WritePrivateProfileSectionW WritePrivateProfileStructA / WritePrivateProfileStructW Registry: RegCreateKeyA / RegCreateKeyW RegCreateKeyExA / RegCreateKeyExW RegDeleteKeyA / RegDeleteKeyW RegQueryValue / RegQueryValueEx RegEnumKeyA / RegEnumKeyW RegEnumKeyExA / RegEnumKeyExW RegEnumValueA / RegEnumValueW RegSetValueA / RegSetValueW RegSetValueExA / RegSetValueExW RegOpenKeyA /RegOpenKeyW RegOpenKeyExA /RegOpenKeyExW RegCloseKey
There are many occasions where if someone updates a records or even deletes a record we need to keep the Audit trails of the record updated or deleted or even keep a history of records as what are the updates that happened on the database as well as what are the records deleted from the table. In Any database system there are triggers to achieve the same but remember that if triggers if not used efficiently can degrade the performance of the Database system
If we have a table
Code to create table CREATE TABLE [dbo].[Details] ( [RegNo] [varchar] (50) NOT NULL , [RegYear] [varchar] (4) NOT NULL , [FullName] [varchar] (50) NOT NULL , [FathersName] [varchar] (50) NOT NULL , [Location] [varchar] (250) NOT NULL , [Village] [varchar] (250) NOT NULL , [PresentAdd] [varchar] (500) NOT NULL , [CreatedBy] [varchar] (50) NOT NULL , [DateCreated] [datetime] NOT NULL , [UpdatedBy] [varchar] (50) NULL , [DateUpdated] [datetime] NULL ) GO
ALTER TABLE [dbo].[Details] WITH NOCHECK ADD CONSTRAINT [PK_Details] PRIMARY KEY CLUSTERED ( [RegNo], [RegYear] ) ON [PRIMARY] GO
Code to create the log table
Code: CREATE TABLE [dbo].[logDetails] ( [LogType] [varchar] (50) NULL , [RegNo] [varchar] (50) NOT NULL , [RegYear] [varchar] (4) NOT NULL , [FullName] [varchar] (50) NOT NULL , [FathersName] [varchar] (50) NOT NULL , [Location] [varchar] (250) NOT NULL , [Village] [varchar] (250) NOT NULL , [PresentAdd] [varchar] (500) NOT NULL , [CreatedBy] [varchar] (50) NOT NULL , [DateCreated] [datetime] NOT NULL , [UpdatedBy] [varchar] (50) NULL , [DateUpdated] [datetime] NULL ) GO
Now We need to write the trigger to create the Audit Trail / log of updation/deletion of record on Details into the logDetails table.
Code: CREATE TRIGGER AuditDetails ON dbo.Details FOR Update,Delete AS
BEGIN DECLARE @auditType varchar(10) -- Audit OLD record. IF EXISTS (Select i.RegNo,i.RegYear from Inserted i) -- Record is updated BEGIN SET @auditType = 'Updated' END ELSE -- Record is deleted BEGIN SET @auditType = 'Deleted' END
INSERT INTO logDetails (logtype, RegNo, RegYear, FullName, FathersName, Location, Village, PresentAdd, CreatedBy, DateCreated, UpdatedBy, DateUpdated ) SELECT @auditType, d.RegNo, d.RegYear, d.FullName, d.FathersName, d.Location, d.Village, d.PresentAdd, d.CreatedBy, d.DateCreated, d.UpdatedBy, d.DateUpdated FROM deleted d END
gcc is pretty easy. Just say "gcc --help" in a graphical console and look at all the options, OR if your in console, pipe the output to less by saying "gcc --help | less" to see all the options. But in general I think, for console apps, I just say "gcc myfile.c -o myapp" or whatnot. Also, if your doing C++ you may be using gpp instead of gcc.
Assuming you are new to Linux in general, and also assuming you aren't using Gentoo, you may be unfamiliar with makefiles. Linux has a "make" tool that executes a makefile, which is a glorified batch:
Code: compile: gcc main.c -o app clean: rm appthen you can say "make clean" or "make compile" or whatnot. You may want to read up on this.. its an invaluable tool as far as programming in linux goes.
gcc test.c
will compile ur program and create an executable file named a.out and run that program by issuing
A standard algorithm for LU decomposition, described in Numerical Recipes,[1] transforms a square matrix "in place", storing the values for all the elements of L and U in the same space in memory where the original square matrix was stored. This can be done by overlapping the two arrays so that the mandatory zeros on the opposite sides of both L and U, and the ones on the diagonal of L, are not explicitly represented in memory. The algorithm transforms the array A in the previous example into the following array:
The lower triangle of this array contains all the significant elements of L, and its upper triangle contains all the significant elements of U.
The algorithm for accomplishing this transformation is constructed of three controlling structures:
A sequential DO loop moves down the diagonal from A(1,1) to A(n-1,n-1) in order. For each diagonal element A(k,k) , the following operations are performed (on successively smaller portions of the matrix): Column normalization - The elements in the column below the diagonal element A(k,k) are divided by the diagonal element. Submatrix modification - A submatrix is defined containing all the elements of A that are below and to the right of A(k,k) , not including the column and row that contain A(k,k) . The value of each element A(i,j) in the submatrix is modified by subtracting A(i,k)*A(k,j) . For the sake of simplicity, the issue of pivoting is ignored here, although the algorithm can be unstable without it.
Fortran 77 Style Code In Fortran 77 syntax, the algorithm (without pivoting), is coded as follows:
DO k = 1, n-1 DO x = k+1, n ! Column A(x, k) = A(x, k) / A(k, k) ! Normalization END DO ! DO i = k+1, n ! DO j = k+1, n ! Submatrix A(i, j) = A(i, j) - A(i, k)*A(k, j) ! Modification END DO ! END DO ! END DO
Like all Fortran 77 code, this code is compiled and executed correctly by Digital Fortran 90. However, the compiler does not recognize it as parallelizable, and compiles it to run serially, with no parallel speed-up.
Parallelizing the DO Loops In order to achieve parallel speed-up, eligible DO loops should be changed to one of these:
DO loops marked with the INDEPENDENT directive Fortran 90 array assignment statements, or their extended form, Fortran 95 FORALL structures. Some caution is required, because these three parallel constructs are not the same as a non-parallel DO loop. In many cases, simply re-writing a DO loop into one of these three forms can result in different answers, or even be illegal. In other cases, the three forms are equivalent.
In our example, the column normalization DO loop can be expressed any of these three ways:
INDEPENDENT DO loop:
!HPF$ INDEPENDENT DO x = k+1, n A(x, k) = A(x, k) / A(k, k) END DO
Fortran 90 array assignment statement:
A(k+1:n, k) = A(k+1:n, k) / A(k, k)
FORALL statement:
FORALL (i=k+1:n) A(i, k) = A(i, k) / A(k, k)
The submatrix modification DO loop is too complex to be expressed by a single array assignment statement. It can, however, be marked with the INDEPENDENT directive, or changed into a FORALL.
INDEPENDENT version:
!HPF$ INDEPENDENT, NEW(j) DO i = k+1, n !HPF$ INDEPENDENT DO j = k+1, n A(i, j) = A(i, j) - A(i, k)*A(k, j) END DO END DO
The NEW(j) keyword tells the compiler that in each iteration, the inner DO loop variable j is unrelated to the j from the previous iteration. Digital's compiler currently requires the NEW keyword in order to parallelize nested INDEPENDENT DO loops.
Putting the two together, here are two versions of the complete parallelized algorithm:
Fortran 90/95 syntax version:
DO k = 1, n-1 A(k+1:n, k) = A(k+1:n, k) / A(k, k) ! Column Normalization FORALL (i=k+1:n, j=k+1:n) ! Sub- A(i, j) = A(i, j) - A(i, k)*A(k, j) ! matrix END FORALL ! Modification END DO
DO INDEPENDENT version:
DO k = 1, n-1 !HPF$ INDEPENDENT DO x = k+1, n ! Column A(x, k) = A(x, k) / A(k, k) ! Normalization END DO ! !HPF$ INDEPENDENT, NEW(j) DO i = k+1, n ! !HPF$ INDEPENDENT ! DO j = k+1, n ! Submatrix A(i, j) = A(i, j) - A(i, k)*A(k, j) ! Modification END DO ! END DO ! END DO
The Ghostscript source code is divided conceptually as follows:
PostScript interpreter: PostScript operators z*.h and z*.c Other interpreter code i*.h and i*.c PostScript code gs_*.ps PDF interpreter: PostScript code pdf_*.ps Graphics library: Main library code g*.h and g*.c Streams s*.h and s*.c Device drivers gdev*.h and gdev*.c Platform-specific code gp*.h and gp*.c
PostScript Interpreter gs.c is the main program for the interactive language interpreter; gserver.c is an alternative main program that is a rudimentary server. If you configure Ghostscript as a server rather than an interactive program, you will use gserver.c instead of gs.c.
Files named z*.c are Ghostscript operator files. The names of the files generally follow the section headings of the operator summary in section 6.2 (Second Edition) or 8.2 (Third Edition) of the PostScript Language Reference Manual. Each operator XXX is implemented by a procedure named zXXX, for example, zfill and zarray.
Files named i*.c, and *.h other than g*.h, are the rest of the interpreter. See the makefile for a little more information on how the files are divided functionally.
The main loop of the PostScript interpreter is the interp procedure in interp.c. When the interpreter is reading from an input file, it calls the token scanner in iscan*.c.
idebug.c contains a lot of debugger-callable routines useful for printing PostScript objects when debugging.
PDF interpreter The PDF interpreter is written entirely in PostScript. Its main loop is the .pdfrun procedure in pdf_base.ps. When the PDF interpreter is configured into the build, it redefines the "run" operator to test whether the file is a PDF file. This redefinition is near the beginning of pdf_main.ps.
Graphics library Files beginning with gs, gx, or gz (both .c and .h), other than gs.c and gserver.c, are the Ghostscript library. Files beginning with gdev are device drivers or related code, also part of the library. Other files beginning with g are library files that don't fall neatly into either the kernel or the driver category.
Files named s*.c and s*.h are a flexible stream package, including the Level 2 PostScript "filters" supported by Ghostscript. See stream.h, scommon.h, and strimpl.h for all the details.
Device drivers The interface between the graphics library and device drivers is the only really well documented one in all of Ghostscript: see the documentation on drivers.
In addition to many real device and file format drivers listed in devs.mak and contrib.mak, a number of drivers are used for internal purposes. You can search lib.mak for files named gdev*.c to find almost all of them.
Drivers are divided into "printer" drivers, which support banding, and non-printer drivers, which don't. The decision whether banding is required is made (by default on the basis of how much memory is available) in the procedure gdev_prn_alloc in gdevprn.c: it implements this decision by filling the virtual procedure table for the printer device in one of two different ways.
A good simple "printer" (bandable) driver to read is gdevmiff.c: it's less than 100 lines, of which much is boilerplate. There are no simple non-printer drivers that actually drive devices: probably the simplest non-printer driver for reading is gdevm8.c, which implements 8-bit-deep devices that only store the bits in memory.
Platform-specific code There are very few platform dependencies in Ghostscript. Ghostscript deals with them in three ways:
Files named *_.h substitute for the corresponding <*.h> file by adding conditionals that provide a uniform set of system interfaces on all platforms. The file arch.h contains a set of mechanically-discovered platform properties like byte order, size of int, etc. These properties, not the names of specific platforms, are used to select between different algorithms or parameters at compile time. Files named gp*.h define interfaces that are intended to be implemented differently on each platform, but whose specification is common to all platforms. The platform-specific implementations of the gp*.h interfaces have names of the form "gp_{platform}.c, specifically (this list may be out of date):
gp_dosfb.c DOS gp_dosfs.c DOS and MS Windows gp_itbc.c DOS, Borland compilers gp_iwatc.c DOS, Watcom or Microsoft compiler gp_msdos.c DOS and MS Windows gp_ntfs.c MS-Windows Win32s and Windows NT gp_os2.c OS/2 gp_os9.c OS-9 gp_unifs.c Unix, OS-9, and QNX gp_unix.c Unix and QNX gp_sysv.c System V Unix gp_vms.c VMS gp_win32.c MS-Windows Win32s and Windows NT
If you are going to extend Ghostscript to new machines or operating systems, check the *_.h files for ifdef on things other than DEBUG. You should probably plan to make a new makefile and a new gp_XXX.c file.
Makefiles This section is only for advanced developers who need to integrate Ghostscript into a larger program at build time.
NOTE: THIS SECTION IS INCOMPLETE. IT WILL BE IMPROVED IN A LATER REVISION.
The Ghostscript makefiles are meant to be organized according to the following two principles:
All the parameters that vary from platform to platform appear in the top-level makefile for a given platform. ("Platform" = OS + compiler + choice of interpreter vs. library) All the rules and definitions that can meaningfully be shared among more than 1 platform appear in a makefile that is "included" by a makefile (normally the top-level makefile) for those platforms. Thus, for example:
Rules and definitions shared by all builds are in gs.mak. Rules and definitions specific to the library (on all platforms) are in lib.mak. In principle this could be merged with gs.mak, but we wanted to leave open the possibility that gs.mak might be useful with hypothetical interpreter-only products. Stuff specific to interpreters (on all platforms) is in int.mak. Stuff specific to all Unix platforms should be in a single unix.mak file, but because make sometimes cares about the order of definitions, and because some of it is shared with DV/X, it got split between unix-aux.mak, unix-end.mak, unixhead.mak, unixinst.mak, and unixlink.mak. For MS-DOS and MS Windows builds, there should be:
A makefile for all MS OS (DOS or Windows) builds, for all compilers and products. Perhaps a makefile for all MS-DOS builds, for all compilers and products, although since Watcom is the only such compiler we're likely to support this may be overkill. A makefile for all MS Windows builds, for all compilers and products. A makefile for all Watcom builds (DOS or Windows), for all products. A top-level makefile for the Watcom DOS interpreter product. A top-level makefile for the Watcom Windows interpreter product. A top-level makefile for the Watcom DOS library "product". A top-level makefile for the Watcom Windows library "product". A makefile for all Borland builds (DOS or Windows), for all products. and so on.
What are some ways try / catch / throw can improve software quality? By eliminating one of the reasons for if statements.
The commonly used alternative to try / catch / throw is to return a return code (sometimes called an error code) that the caller explicitly tests via some conditional statement such as if. For example, printf(), scanf() and malloc() work this way: the caller is supposed to test the return value to see if the function succeeded.
Although the return code technique is sometimes the most appropriate error handling technique, there are some nasty side effects to adding unnecessary if statements:
Degrade quality: It is well known that conditional statements are approximately ten times more likely to contain errors than any other kind of statement. So all other things being equal, if you can eliminate conditionals / conditional statements from your code, you will likely have more robust code. Slow down time-to-market: Since conditional statements are branch points which are related to the number of test cases that are needed for white-box testing, unnecessary conditional statements increase the amount of time that needs to be devoted to testing. Basically if you don't exercise every branch point, there will be instructions in your code that will never have been executed under test conditions until they are seen by your users/customers. That's bad. Increase development cost: Bug finding, bug fixing, and testing are all increased by unnecessary control flow complexity. So compared to error reporting via return-codes and if, using try / catch / throw is likely to result in code that has fewer bugs, is less expensive to develop, and has faster time-to-market. Of course if your organization doesn't have any experiential knowledge of try / catch / throw, you might want to use it on a toy project first just to make sure you know what you're doing — you should always get used to a weapon on the firing range before you bring it to the front lines of a shooting war.
How can I handle a constructor that fails? Throw an exception.
Constructors don't have a return type, so it's not possible to use return codes. The best way to signal constructor failure is therefore to throw an exception. If you don't have the option of using exceptions, the "least bad" work-around is to put the object into a "zombie" state by setting an internal status bit so the object acts sort of like it's dead even though it is technically still alive.
The idea of a "zombie" object has a lot of down-side. You need to add a query ("inspector") member function to check this "zombie" bit so users of your class can find out if their object is truly alive, or if it's a zombie (i.e., a "living dead" object), and just about every place you construct one of your objects (including within a larger object or an array of objects) you need to check that status flag via an if statement. You'll also want to add an if to your other member functions: if the object is a zombie, do a no-op or perhaps something more obnoxious.
In practice the "zombie" thing gets pretty ugly. Certainly you should prefer exceptions over zombie objects, but if you do not have the option of using exceptions, zombie objects might be the "least bad" alternative.
How can I handle a destructor that fails? Write a message to a log-file. Or call Aunt Tilda. But do not throw an exception!
Here's why (buckle your seat-belts):
The C++ rule is that you must never throw an exception from a destructor that is being called during the "stack unwinding" process of another exception. For example, if someone says throw Foo(), the stack will be unwound so all the stack frames between the throw Foo() and the } catch (Foo e) { will get popped. This is called stack unwinding.
During stack unwinding, all the local objects in all those stack frames are destructed. If one of those destructors throws an exception (say it throws a Bar object), the C++ runtime system is in a no-win situation: should it ignore the Bar and end up in the } catch (Foo e) { where it was originally headed? Should it ignore the Foo and look for a } catch (Bar e) { handler? There is no good answer — either choice loses information.
So the C++ language guarantees that it will call terminate() at this point, and terminate() kills the process. Bang you're dead.
The easy way to prevent this is never throw an exception from a destructor. But if you really want to be clever, you can say never throw an exception from a destructor while processing another exception. But in this second case, you're in a difficult situation: the destructor itself needs code to handle both throwing an exception and doing "something else", and the caller has no guarantees as to what might happen when the destructor detects an error (it might throw an exception, it might do "something else"). So the whole solution is harder to write. So the easy thing to do is always do "something else". That is, never throw an exception from a destructor.
Of course the word never should be "in quotes" since there is always some situation somewhere where the rule won't hold. But certainly at least 99% of the time this is a good rule of thumb.
How should I handle resources if my constructors may throw exceptions? Every data member inside your object should clean up its own mess.
If a constructor throws an exception, the object's destructor is not run. If your object has already done something that needs to be undone (such as allocating some memory, opening a file, or locking a semaphore), this "stuff that needs to be undone" must be remembered by a data member inside the object.
For example, rather than allocating memory into a raw Fred* data member, put the allocated memory into a "smart pointer" member object, and the destructor of this smart pointer will delete the Fred object when the smart pointer dies. The template std::auto_ptr is an example of such as "smart pointer." You can also write your own reference counting smart pointer. You can also use smart pointers to "point" to disk records or objects on other machines.
By the way, if you think your Fred class is going to be allocated into a smart pointer, be nice to your users and create a typedef within your Fred class:
#include
class Fred { public: typedef std::auto_ptr Ptr; ... }; That typedef simplifies the syntax of all the code that uses your objects: your users can say Fred::Ptr instead of std::auto_ptr:
Most of the times when the system gets halted improperly due to power outage or due to some other reason, the file system gets corrupted and Windows is unable to mount the boot drive properly. There are other factors that also result in unmountable boot volume. These include faster UDMA modes configured in BIOS and using 40 wire data cable for the hard drive.
Resolution Load the fail-safe defaults in your BIOS and use 80 wire data cable for the hard drive for optimum performance. If the file system is demaged (which usually is the case) If you have Recovery Console installed at startup, then start the recovery console and go to step 3. (See here how to install recovery console at startup) If Recovery Console is not installed at startup, then boot with Windows XP CD. When the “Welcome to setup” message appears, press R to start the Recovery Console. Select your Windows installation and type administrator password when prompted. At the command prompt, type chkdsk /r and then press enter. This will check your file system for errors and try to fix if any. When the above process is complete, type fixboot at the command prompt. This will fix the boot sector of the hard drive. Type exit at the command prompt to restart the system. Most probably the system will boot into Windows now.
A valuable reader asks about the DNS Cache in my previous post about clearing the DNS Cache. So I thought it was worthy a post rather than a comment.
So what is DNS. The Domain Name System (DNS) is responsible for translating IP addresses to Domain Names and vice versa. IP address is a number that uniquely identifies a computer on the Internet or network (like your full name uniquely identifies you). For more information about IP address, please see this wikipedia article. As it is easier for the humans to memorize names instead of numbers and the computers deal with numbers rather than names, DNS comes to the rescue which translates names to numbers and numbers to names for the ease of human beings. For example, it is a lot easier to remember www.yahoo.com rather than 209.131.36.158. But actually they correspond to the same system. For confirmation, type either value in the address bar of your browser and you will get the same web page. Most people probably use the DNS server of their ISPs. To see your DNS server, type ipconfig /all in command prompt.
Whenever you type an address in your browser, your system queries your DNS server if it knows about the address. If it does, the server sends back the IP address of the address you typed in your browser otherwise forwards your query to another DNS server for resolution. The process continues until you reach your desired results.
As this process of resolving the IP address gets time consuming, Windows and Linux use a local DNS cache which just saves the corresponding domain names with their IP addresses. So if the same domain name gets queried again, instead of repeating the DNS resolution process, it consults the local DNS records and gives the results instantly. This improves the DNS resolution process very much. The whole process of DNS resolution is completely transparent to the end user. Sometimes the DNS cache gets corrupted and it has to be cleared which is covered in my previous post about clearing the DNS Cache.
Unlike other .NET languages, Visual C++ has interoperability support that allows managed and unmanaged code to exist in the same application and even in the same file (with the managed, unmanaged pragmas). This allows Visual C++ developers to integrate .NET functionality into existing Visual C++ applications without disturbing the rest of the application.
You can also call unmanaged functions from a managed compiland using dllexport, dllimport.
Implicit PInvoke is useful when you do not need to specify how function parameters will be marshaled, or any of the other details that can be specified when explicitly calling DllImportAttribute.
Visual C++ provides two ways for managed and unmanaged functions to interoperate:
Using Explicit PInvoke in C++ (DllImport Attribute)
Explicit PInvoke is supported by the .NET Framework and is available in most .NET languages. But as its name implies, C++ Interop is specific to Visual C++.
C++ Interop C++ Interop is recommended over explicit PInvoke because it provides better type safety, is typically less tedious to implement, is more forgiving if the unmanaged API is modified, and makes performance enhancements possible that are not possible with explicit PInvoke. However, C++ Interop is not possible if the unmanaged source code is not available or when compiling with /clr:safe (see Pure and Verifiable Code for more information).
C++ COM Interop The interoperability features supported by Visual C++ offer a particular advantage over other .NET languages when it comes to interoperating with COM components. Instead of being limited to the restrictions of the .NET Framework Type Library Importer (Tlbimp.exe), such as limited support for data types and the mandatory exposure of every member of every COM interface, C++ Interop allows COM components to be accessed at will and does not require separate interop assemblies. For more information, see Using Native COM Servers from .NET.
Blittable Types For unmanaged APIs that use simple, intrinsic types (see Blittable and Non-Blittable Types), no special coding is required because these data types have the same representation in memory, but more complex data types require explicit data marshaling. For an example, see How to: Call Native DLLs from Managed Code Using PInvoke.
Example Copy Code // vcmcppv2_impl_dllimp.cpp // compile with: /clr:pure user32.lib using namespace System::Runtime::InteropServices;
// explicit DLLImport needed here to use P/Invoke marshalling because // System::String ^ is not the type of the first parameter to printf [DllImport("msvcrt.dll", EntryPoint = "printf", CallingConvention = CallingConvention::Cdecl, CharSet = CharSet::Ansi)] // or just // [DllImport("msvcrt.dll")] int printf(System::String ^, ...);
int main() { // (string literals are System::String by default) printf("Begin beep\n"); MessageBeep(100000); printf("Done\n"); } Copy Code Begin beep Done
A Checkbox An Optionbox A Textbox A Label A Commandbutton
For more information see the Attachments!
How To begin: First make a Standard EXE ( this will be our main porgram ), Seconde, go to Menu >> File >> Add Project >> ActiveX DLL. Ok we got this, Then go in Project1 to your menu: Project >> References >> Project2 You'll find more information in the tutorial itself
In Form1 @ Project1 ( our main program ):
Code:
' ***************************************** ' * What to do befor we start:������������* ' ***************************************** ' First we create a new Standard EXE, like ' we normaly do. So this is going to be our ' main program were we're going to put a large ' amount of our coding during DLL coding. ' Now the seconde step we take is go to your menu: ' [File] >> [Add Project...] >> [ActiveX DLL] >> [OK] ' So now we've got a seconde project ( called ' Project2 ) and a Class Module ( Called Class1 ) ' underneath our Project1 & Form1. ' Good! ' But we still need the Project1 ( our main prog ) ' to know that he'll have to work with the DLL! ' So go to your menu: ' [Project] >> [References] >> [Project2] >> [OK] ' Very good! We have given it access to Project2 (DLL) ' We can now start coding our Project1 & Project2
' ***************************************** ' * Next step with programming DLL:������ * ' ***************************************** ' We still need to put a code in our Form1 ' to let him know we're realy going to use ' Project2 (DLL). ' We don't put this into Form_load() of anything ' Just on top ( @ the beginning ) of our program. Option Explicit ' Ok, the coding Below is to let the program know ' what we're going to name it, you see that DLL ' is going to be short for the Class Module in ' our Project2 (DLL-File) Private DLL As New Class1 Private Sub Form_Load() ' When The forum Loads we need it to do several things: ' Name Form1 ' Name Check1 ' Name Option1 ' Name Textbox1 ' Name Label1 ' Name Button1
' Naming Form1 ( Standard ) Form1.Caption = DLL.StrProgName
' Naming Check1 ( Standard ) Check1.Caption = DLL.StrCheckName
' Naming Option1 ( Standard ) Option1.Caption = DLL.StrOptionName
'Naming Textbox1 ( Standard ) Text1.Text = DLL.StrTxtName
' Naming Label1 ( Standard ) Label1.Caption = DLL.StrLblName
' Naming Button1 ( Standard ) Command1.Caption = DLL.StrCmdName End Sub Private Sub Command1_Click() ' So when they click the button show the ' String for the messagebox MsgBox DLL.StrFunix End Sub
' Ofcourse DLL can be used for many more, ' but this is just a basic tutorial of what you can do with this!
In Class1 @ project2 ( our DLL ):
Code:
' ***************************************** ' * DLL coding:�������������������������� * ' ***************************************** ' Why should we use DLL coding any way? ' Well, I use it when I write a program that ' is going to have a next version of it. ' I code standerd stuff into the DLL so I ' Don't need to put it into the whole coding ' of the program over and over again, every ' version. Plus, it makes the code of our ' program smaller and that's what users like!
' ***************************************** ' * The real coding:����������������������* ' ***************************************** Option Explicit
' We're going to use functions to code into this ' DLL. Public Function StrFunix() As String ' So This will be used for the MessageBox Example ' StrFunix is what we're going to use short for: ' This is an example of DLL coding StrFunix = "This is an example of DLL coding" End Function Public Function StrCmdName() As String ' This Will Be used as name for the button StrCmdName = "Dll-Button" End Function Public Function StrLblName() As String ' This Will Be used as name for the Label StrLblName = "Dll-Label" End Function Public Function StrCheckName() As String ' This Will Be used as name for the Checkbox StrCheckName = "Dll-Check1" End Function Public Function StrTxtName() As String ' This Will Be used as name for the Textbox StrTxtName = "Dll-Text-box" End Function Public Function StrOptionName() As String ' This Will Be used as name for the OptionBox StrOptionName = "Dll-Option1" End Function Public Function StrProgName() As String ' This Will Be used as name for caption of the form StrProgName = "Dll-Tutorial" End Function
If you follow my tutorial right there shouldn't be any problem , but because there are always people that can't understand it, I included a download for my tutotorial!
Attachments:
Form.JPG ( How the Form should look like ) AddProject.JPG ( How to add the DLL-Project ) References.JPG ( Select the DLL in your References of Project1 ) ProjectGroup.JPG ( How all should look like ) DLL Tutorial.zip, Inclucing:
I need some expert help to require registration on certain pdf downloads on my site (win2k, iis5), while maintaining the use of the back button which avoids the login and registration pages shown below. I'm trying to do this without javascript, if possible. Here are the pages and partial content:
[B]Product Page...[/B] (purpose: contains links to pdfs. some require registration, others don't) < a href="<%="login.asp?filename=file1.pdf"%>">File1< /a>
< a href="file2.pdf">File2< /a>
[B]Login Page...[/B] (purpose: ask for email, if previsouly registered email is found in db, open pdf...if not previously registered, provide link to registration page and remember which pdf was requested)
If you haven't registered, < a href="<%="registration.asp?filename=" & request.querystring("filename"[smilestopper])%>">GO HERE< /a>
If you've previsouly registered, enter your email below:
< form> ...I've got working code to request email... < /form> < % function CheckDatabase() ...I've got working VBscript and SQL code to check Oracle db for email...
HERE'S WHERE I NEED HELP: open pdf in CURRENT window so if back button is used, the user returns to Product Page not to the Login Page.
I've tried using response.redirect(request.querystring("filename"[smilestopper])) which returns the undesired behavior explained above.
Are there other ways to do this ( non-javascript) that play well with today's pop-up blockers, i.e. XP SP2, etc?
end function % >
[B]Registration Page...[/B] (purpose: requests user information, writes to db, opens requested pdf)
< % function WriteToDB() ...I've got working VBscript and SQL code here...
HERE'S WHERE I NEED HELP: open pdf so that if the back button is used the user returns to Product Page not to the Login or Registration Page.
The only thing I've seen is to use Javascript history.go(-2), but I can't get it to work. Are the alternatives?
end function % >
Thanks so much for your help...I'm desperate! Any good copy and paste code out there with this functionality?
I know what you are trying to do... But have you considered making two sub-directories? Ie:
/public /private
Leave the /public folder as-is. Put all of your pdf's that you want available to everyone in there. Then through your IIS contorl panel (Or whatever your host has set up), "protect" the /private directory. Place all of the "proctected" pdf's here. You will be able to set up a list of usernames and passwords. (You can aslo do this with an Access Database and ASP.) This way, once a user is logged in, they won't have to re-login for every PDF they want to view, their session will only end when they close their browser.
If you don't have too many concurrent users, why not set a session variable for login status? at the begining of your registration/login pages do a response redirect if session variable is set:
< % if (session("validated") = "true") then response.redirect("products.asp") % >
& at the top of any sensitive pages:
< % if (session("validated") = "false") then response.redirect("login.asp") % >
of course you'll need to set the session variable on login..
What are the limitations of superconducting microprocessors ?
Superconducting microprocessors are still in their R/D phase and, wisely, industry will not use them until they are proved reliable in practice.
As regards high clock speeds, the wavelength at 1 GHz is c/f = 10 cm and at 10 GHz is 1 cm. To transmit a sharp transition signal (square wave) demands passage of higher harmonics up to say f times 10. All these signal component frequencies must arrive together - which demands a non- dispersive transmission line (all signals travel at same speed).
The signal DELAY is crucial for in any practical setup the wires between different components vary in length. The delay per cm of wire is more than 100 picoseconds and, unless specially catered for we need all components to be in step without differential delays. The principal advantage of superconducting computers will thus be their ability to house more components on the same chip - which currently is limited by thermal dissipation comcerns. This means shorter connecting wires. But the MORE you put on one chip the MORE reliable everything must be, as failure in any one thing renders the whole scrap.
Everyone keeps announcing they "almost have" rooom-temperature superconductors. This, if it ever happens, will help.
As always the main main limitations of computers will continue to be our ability to use them - to use to advantage the fact that they "think" entirely differently to us. There will be great strides in input/output devices, perhaps with "direct brain links" (via devices warn like spectacles or headphones. Simulated 3-d imagery will improve and the possibility of manufacturing 3-d objects (3-d "printers"). Presumably our entertainment and communication devices will be integrated (and compatible both with one another and ourselves) and new modes of interaction, enjoyment and practical use invented.