Thursday, October 30, 2008
General: Using VI to Insert String Before a Line and Append Strings After a Line
:1,$s/ ^ /drop table /
:1,$s/$ / ; /
Strange, I’ve been using VI for years, and never needed to do that before. I am so used to my small set of commands, I never bothered to expand out and learn everything else that VI could do.
Here is a list of sites that have useful VI commands, shortcuts, and tutorials:
http://andrewfraser.wordpress.com/2007/01/12/useful-simple-vi-commands-for-dbas/
http://www.viemu.com/vi-vim-cheat-sheet.gif
http://tnerual.eriogerg.free.fr/vimqrc.pdf
http://www.eng.hawaii.edu/Tutor/vi.html#modes
Sunday, October 26, 2008
ASM: Revised Chekerboard program, now with flashing squares
I revised by checkerboard ASM program to have the white colored squares fade in and out. I wanted to do this for a few reasons. It shows a palette shift, which I have demonstrated previously, but it also shows how to do a time delay in ASM. The time delay turned out to be a little trickier than I thought. I tried using the DOS Get Time interrupt, but if you don’t test all the registers it returns and try to get away with just the DX register, you end up with unacceptably long delays when minutes change or hours change. I ended up using the system BIOS call to get the system clock ticks. The same problem will arise after midnight, but that can easily be overcome by testing the appropriate flag which gets set when midnight occurs. Again, I have included comments, and I also included the addresses that DOS Debug displays. If I do anymore ASM programs, I thing I will use an assembler going forward. Its easier than having to specify jumps by address, which change when I add something new to a program.
--initialize video mode to 320x200x256
13F2:0100 B81300 MOV AX,0013
13F2:0103 CD10 INT 10
point data segment and extra segment to video memory
13F2:0105 B800A0 MOV AX,A000
13F2:0108 8ED8 MOV DS,AX
13F2:010A 8EC0 MOV ES,AX
13F2:010C 31FF XOR DI,DI
--initialize registers with values of palette to use
--use word instead of bytes for the stosw instruction
13F2:010E B80F0F MOV AX,0F0F
13F2:0111 BB0000 MOV BX,0000
--initialize to the number of veritical squares
13F2:0114 B90800 MOV CX,0008
13F2:0117 51 PUSH CX
--start execution, logic is explained in previous post
13F2:0118 B9C800 MOV CX,00C8
13F2:011B 51 PUSH CX
13F2:011C B91400 MOV CX,0014
13F2:011F F3 REPZ
13F2:0120 AB STOSW
13F2:0121 50 PUSH AX
13F2:0122 89D8 MOV AX,BX
13F2:0124 5B POP BX
13F2:0125 59 POP CX
13F2:0126 E2F3 LOOP 011B
13F2:0128 50 PUSH AX
13F2:0129 89D8 MOV AX,BX
13F2:012B 5B POP BX
13F2:012C 59 POP CX
13F2:012D E2E8 LOOP 0117
--get ready to ramp down the white palette entry
--do this 3fh times
13F2:012F B93F00 MOV CX,003F
13F2:0132 B3FF MOV BL,FF
13F2:0134 FECB DEC BL
--initialize with the port to tell video card we are changing
--a pallete entry. This should be changed at some point to
--actually retrieve the pallete entry to change
13F2:0136 BAC803 MOV DX,03C8
13F2:0139 B00F MOV AL,0F
13F2:013B EE OUT DX,AL
--increment dx by 1, to point to the port to actually
--set a pallette entry
13F2:013C 42 INC DX
13F2:013D 88D8 MOV AL,BL
--output the new pallette entries
13F2:013F EE OUT DX,AL
13F2:0140 EE OUT DX,AL
13F2:0141 EE OUT DX,AL
--we need a slight pause so this is effect is visible, otherwise it
--just looks like ugly staticy squares, so save our registers
13F2:0142 50 PUSH AX
13F2:0143 53 PUSH BX
13F2:0144 51 PUSH CX
13F2:0145 52 PUSH DX
--we want to test this by a single clock tick, 1/18 of a second, which
--we will use DI to compare against
13F2:0146 BF0100 MOV DI,0001
--call int 1ah, function 00, which will get a clock tick, to initialize
--out testing value and set in BX
13F2:0149 B400 MOV AH,00
13F2:014B CD1A INT 1A
13F2:014D 89D3 MOV BX,DX
--cal again to get current value
13F2:014F CD1A INT 1A
--subtract stored value from current value. If it is greater, than we have
--surpassed our delay time, and we need to keep moving, otherwise, test again
13F2:0151 29DA SUB DX,BX
13F2:0153 39D7 CMP DI,DX
13F2:0155 77F8 JA 014F
--restore registers
13F2:0157 5A POP DX
13F2:0158 59 POP CX
13F2:0159 5B POP BX
13F2:015A 58 POP AX
--loop back to palette shift beginning
13F2:015B E2D7 LOOP 0134
--do the same thing as the palette shift above, but in reverse order, ramping
--the values up
13F2:015D B93F00 MOV CX,003F
13F2:0160 FEC3 INC BL
13F2:0162 BAC803 MOV DX,03C8
13F2:0165 B00F MOV AL,0F
13F2:0167 EE OUT DX,AL
13F2:0168 42 INC DX
13F2:0169 88D8 MOV AL,BL
13F2:016B EE OUT DX,AL
13F2:016C EE OUT DX,AL
13F2:016D EE OUT DX,AL
13F2:016E 50 PUSH AX
13F2:016F 53 PUSH BX
13F2:0170 51 PUSH CX
13F2:0171 52 PUSH DX
13F2:0172 BF0100 MOV DI,0001
13F2:0175 B400 MOV AH,00
13F2:0177 CD1A INT 1A
13F2:0179 89D3 MOV BX,DX
13F2:017B CD1A INT 1A
13F2:017D 29DA SUB DX,BX
13F2:017F 39D7 CMP DI,DX
13F2:0181 77F8 JA 017B
13F2:0183 5A POP DX
13F2:0184 59 POP CX
13F2:0185 5B POP BX
13F2:0186 58 POP AX
13F2:0187 E2D7 LOOP 0160
--check if there is a key press. If not, keep going, otherwise, stop
--running the program.
13F2:0189 B406 MOV AH,06
13F2:018B B2FF MOV DL,FF
13F2:018D CD21 INT 21
13F2:018F 749E JZ 012F
--reset video mode
13F2:0191 B80300 MOV AX,0003
13F2:0194 CD10 INT 10
--return to DOS
13F2:0196 B8004C MOV AX,4C00
13F2:0199 CD21 INT 21
Friday, October 24, 2008
Java: Multi-Part Form Request using Apache Commons HttpClient
I previously wrote about how to do a simple HTTPUrlConnection request to a web page. This has served me well for quite some time. However, I ran into an issue on a recent project where I needed to do POST request and do a Multi-Part form to post large XML feeds to a service an a web appliance. This is where using HTTPUrlConnection broke down for my needs. While it is possible to do a Multi-Part POST using these classes, it turned out to be more trouble than it was worth.
This is where the Apache Commons HttpClient libraries came into play. Using the more robust Apache Commons libraries, I was easily able to throw together a Multi-Part form POST. There is one slight caveat when using HttpClient, you will need to include the Apache Commons Logging and Apache Commons Codec libraries in your classpath. Even if you do not use them in your implementation, HttpClient apparently uses them internally.
Below is a simplified example of using the HttpClient libraries to do a Multi-Part form POST. I commented out the sections relating to Cookies and posting Files since I was using XML strings.
package com.digiassn.blogspot;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class ApacheHttpClientRequest {
private URL serverAddress;
private String multiPart;
private String result;
private String originalURL;
/**
* Main constructor
*
* @param urlString
* @param queryString
* @param mainReferenceIn
*/
public ApacheHttpClientRequest(String urlString)
{
try {
//This is only used to test the URL as a valid URL, serverAddress is not actually used anywhere
serverAddress = new URL(urlString);
originalURL = urlString;
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
/**
* This method will connect to server, and return the results of the push
* You must set Query first, which is the contents of your XML file
*/
private void executeQuery()
{
PostMethod filePost = null;
HttpClient client = null;
try {
//create new post method, and set parameters
filePost = new PostMethod(originalURL);
filePost.getParams().setBooleanParameter(HttpMethodParams.USE_EXPECT_CONTINUE,
true);
if ((multiPart.equals("")) || (multiPart == null))
{
throw new Exception("Query is null");
}
//create bytearray multi-part source from the query
ByteArrayPartSource targetFile = new ByteArrayPartSource("data", multiPart.getBytes());
//instead of a ByteArrayPartSource, the following could just as easily be used
//to include a file
//File f = new File("");
//FilePartSource fileSource = new FilePartSource(f);
Part[] parts = {
new StringPart("firstParameter", "value"),
new StringPart("secondParameter", "value"),
new FilePart("data", targetFile)
};
//Create the multi-part request
filePost.setRequestEntity(
new MultipartRequestEntity(parts, filePost.getParams())
);
//connect to server
client = new HttpClient();
client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
//the Cookie Handler, if your using manual cookies
//filePost.getParams().setCookiePolicy(CookiePolicy.IGNORE_COOKIES);
//filePost.setRequestHeader("Cookie", "name=value");
//execute and return status
int status = client.executeMethod(filePost);
if (status == HttpStatus.SC_OK) {
System.out.println("Upload success");
} else {
System.out.println("Upload failed: " + HttpStatus.getStatusText(status));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (HttpException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
//set objects to null and garbage collect, not normally necessary but
//some issues popped up in the multi-threaded environment with memory consumption if this
//was not included
filePost = null;
client = null;
//force garbage collection. Expect to take a hit here in performance, may not be necessary
Runtime r = Runtime.getRuntime();
r.gc();
}
}
//below here are the gets and sets
public void setMultiPartString(String query) {
this.multiPart = query;
}
public String getResult() {
return result;
}
public URL getServerAddress() {
return serverAddress;
}
public void setServerAddress(URL serverAddress) {
this.serverAddress = serverAddress;
}
}
Thursday, October 23, 2008
ASM: Drawing a Checkerboard
The comments don't belong, I just added them so it is easier to follow. The following was done using DOS Debug.
--Initialize to 320*200*256 color mode
MOV AX,0013
INT 10
--Point the data and extra segments to the video memory directly and clear the DI register
MOV AX,A000
MOV DS,AX
MOV ES,AX
XOR DI,DI
--Set AX to the first pallete entry (using 2 byte for the STOSW instructions instead of one)
--Set BX to second one. We will swap these after our checkerboard rows are done
MOV AX,0F0F
MOV BX,0000
--initialize CX, our outmost loop, to the number of rows to draw
MOV CX,0008
PUSH CX
--set CX, the middle loop, set to the number of times we need to draw a line pattern for the square
--The way it works is like this, there are 8 pattern breaks in a line (black white alternations).
--we need to repeat that alternation 25 times in order to make a single increment of that alteration
--on the veritcal plane, so 25 * 8 = 200
MOV CX,00C8
PUSH CX
--set Cx to the number of horizontal pixels in a square, which is 20 (320 / 8) = 160, which
--is the 320 / 2 since we are using a word instruction, not a byte instruction
MOV CX,0014
--copy what is in AX to video memory 20 times
REPZ
STOSW
--swap the pallete bytes
PUSH AX
MOV AX,BX
POP BX
--get the value of our middle loop
POP CX
LOOP 011B
--we are at the end of a single verital iteration, swap the pallete entries and go again, until
--the outtermost loop is at 0
PUSH AX
MOV AX,BX
POP BX
POP CX
LOOP 0117
--wait for keypress
MOV AH,10
INT 16
--reset video mode
MOV AX,0003
INT 10
--return to dos
MOV AX,4C00
INT 21
Java: Simple HTTPUrlConnection example
package com.digiassn.blogspot;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
public class SimpleHTTPRequest {
/**
* @param args
*/
public static void main(String[] args) {
HttpURLConnection connection = null;
OutputStreamWriter wr = null;
BufferedReader rd = null;
StringBuilder sb = null;
String line = null;
URL serverAddress = null;
try {
serverAddress = new URL("http://localhost");
//set up out communications stuff
connection = null;
//Set up the initial connection
connection = (HttpURLConnection)serverAddress.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setReadTimeout(10000);
connection.connect();
//get the output stream writer and write the output to the server
//not needed in this example
//wr = new OutputStreamWriter(connection.getOutputStream());
//wr.write("");
//wr.flush();
//read the result from the server
rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
sb = new StringBuilder();
while ((line = rd.readLine()) != null)
{
sb.append(line + '\n');
}
System.out.println(sb.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (ProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
finally
{
//close the connection, set all objects to null
connection.disconnect();
rd = null;
sb = null;
wr = null;
connection = null;
}
}
}
Next post will show how to use the Apache HTTPClient to establish a Multi-Part form POST request.