I was reading a Windows DNS server debug log file, in particular the packet captures, and am trying to understand how to parse the host names in order to use them in scripts.
The following is an example from an ANSWER section:
Offset = 0x007f, RR count = 2
Name "[C06A](5)e6033(1)g(10)akamaiedge[C059](3)net(0)"
TYPE A (1)
CLASS 1
TTL 20
DLEN 4
DATA 23.62.18.101
So, looking at the string "[C06A](5)e6033(1)g(10)akamaiedge[C059](3)net(0)" I realized that the numbers in parenthesis are a count of the number of characters that follow. Replacing all of them with dots (except the first and last, which should just be removed) works like a charm.
The stuff in square brackets, though, remains a mystery to me. If I simply remove it all after handling the parenthesis and quotes, the above string becomes e6033.g.akamaiedge.net. That is a valid host name.
So my question is: what does that content in square brackets actually mean? What is the correct way to turn that string into a proper host name I could feed to nslookup and other tools?
It appears it's the 2nd possible form of the NAME field as documented here:
http://www.zytrax.com/books/dns/ch15/#name
NAME This name reflects the QNAME of the question i.e. any may take
one of TWO formats. The first format is the label format defined for
QNAME above. The second format is a pointer (in the interests of data
compression which to fair to the original authors was far more
important then than now). A pointer is an unsigned 16-bit value with
the following format (the top two bits of 11 indicate the pointer
format):
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 1
The offset in octets (bytes) from the start of the whole message.
Must point to a label format record to derive name length.
Note: Pointers, if used, terminate names. The name field may consist
of a label (or sequence of labels) terminated with a zero length
record OR a single pointer OR a label (or label sequence) terminated
with a pointer.
where the response is using pointers to refer to data elsewhere in the message.
Related
I am trying to print a GS1-128 Barcode using ZPL and when I print this out for some reason everything prints fine except the number in the AI (37), I get 3715 (the 4 is missing), if I change the 4 to a two char integer value such as 04 or 14 I am able to scan it in the barcode.
^BCN,390,N,N,N
^FD>;>8(02)19410525013094(37)4>8(15)200330>610BAT100^FS
The only issue is the system I am working with stores the value for AI 37 as integers, so if the QTY is 4 then it will print as a 4, but i am getting nothing at the moment.
Any assistance would be appreciated.
Thank you,
Omeil
You are manually selecting the numeric mode of code128, using >; at the start of the data field. Numeric mode encodes pairs of digits into single codewords. And unfortunately the printer silently drops any unpaired digits.
You must either zero-pad your data when in subset-C or switch to ZPL's automatic mode for code128, which does a good job at minimizing symbol length. For your data, keep the >; start mode and then let the automatic-mode shift or latch to subset-B as needed.
The answer seems to be replacing >8 with >6 for AI 37 to print quantities of single or odd digits! eg 4, 103, etc
What is the maximum number of characters that could be output from the Win32 functions ToUnicode()/ToAscii()?
Surely there is a sensible upper bound on what it can output given a virtual key code, scan key code, and keyboard state?
On my Windows 8 machine USER32!ToAscii calls USER32!ToUnicode with a internal buffer and cchBuff set to 2. Because the output of ToAscii is a LPWORD and not a LPSTR we cannot assume anything about the real limits of ToUnicode from this investigation but we know that ToAscii is always going to output a WORD. The return value tells you if 0, 1 or 2 bytes of this WORD contains useful data.
Moving on to ToUnicode and things get a bit trickier. If it returns 0 then nothing was written. If it returns 1 or -1 then one UCS-2 code point was written. We are then left with the strange 2 <= return expression. We can try to dissect the MSDN documentation:
Two or more characters were written to the buffer specified by pwszBuff. The most common cause for this is that a dead-key character (accent or diacritic) stored in the keyboard layout could not be combined with the specified virtual key to form a single character. However, the buffer may contain more characters than the return value specifies. When this happens, any extra characters are invalid and should be ignored.
You could interpret this as "two or more characters were written but only two of them are valid" but then the return value should be documented as 2 and not 2 ≤ value.
I believe there are two things going on in that sentence and we should eliminate what it calls "extra characters":
However, the buffer may contain more characters than the return value specifies.
This just implies that the function may party on your buffer beyond what it is actually going to return as valid. This is confirmed by:
When this happens, any extra characters are invalid and should be ignored.
This just leaves us with the unfortunate opening sentence:
Two or more characters were written to the buffer specified by pwszBuff.
I have no problem imagining a return value of 2, it can be as simple as a base character combined with a diacritic that does not exist as a pre-composed code point.
The "or more" part could come from multiple sources. If the base character is encoded as a surrogate-pair then any additional diacritic/combining-character will push you over 2. There could simply also be more than one diacritic/combining-character on the base character. There might even be a leading LTR/RTL mark.
I don't know if it is possible to end up with all 3 conditions at the same time but I would play it safe and specify a buffer of 10 or so WCHARs. This should be well within the limits of what you can produce on a keyboard with "a single keystroke".
This is by no means a final answer but it might be the best you are going to get unless somebody from Microsoft responds.
In usual dead-key case we can receive one or two wchar_t (if key cannot be composed with dead-key it returns two whar_t's) for one ToUnicode call.
But Windows also supports ligatures:
A ligature in keyboard terminology means when a single key outputs two or more UTF-16 codepoints. Note that some languages use scripts that are outside of the BMP (Basic Multilingual Plane) and need to be completely realized by ligatures of surrogate pairs (two UTF-16 codepoints).
If we want to look from a practical side of things: Here is a list of Windows system keyboard layouts that are using ligatures.
51 out of 208 system layouts have ligatures
So as we can see from the tables - we can have up to 4 wchar_t for one ToUnicode() call (for one keypress).
If we want to look from a theoretical perspective - we can look at kbd.h in Windows SDK where underlying keyboard layout structures are defined:
/*
* Macro for ligature with "n" characters
*/
#define TYPEDEF_LIGATURE(n) typedef struct _LIGATURE##n { \
BYTE VirtualKey; \
WORD ModificationNumber; \
WCHAR wch[n]; \
} LIGATURE##n, *KBD_LONG_POINTER PLIGATURE##n;
/*
* Table element types (for various numbers of ligatures), used
* to facilitate static initializations of tables.
*
* LIGATURE1 and PLIGATURE1 are used as the generic type
*/
TYPEDEF_LIGATURE(1) // LIGATURE1, *PLIGATURE1;
TYPEDEF_LIGATURE(2) // LIGATURE2, *PLIGATURE2;
TYPEDEF_LIGATURE(3) // LIGATURE3, *PLIGATURE3;
TYPEDEF_LIGATURE(4) // LIGATURE4, *PLIGATURE4;
TYPEDEF_LIGATURE(5) // LIGATURE5, *PLIGATURE5;
typedef struct tagKbdLayer {
....
/*
* Ligatures
*/
BYTE nLgMax;
BYTE cbLgEntry;
PLIGATURE1 pLigature;
....
} KBDTABLES, *KBD_LONG_POINTER PKBDTABLES;
nLgMax here - is a size of a LIGATURE##n.wch[n] array (affects the size of each pLigature object).
cbLgEntry is a number of pLigature objects.
So we have a BYTE value in nLgMax - and that meant that ligature size could be up to 255 wchar_t's (UTF-16 code points) theoretically.
.proto examples all seem to start numbering their fields at one.
e.g. https://developers.google.com/protocol-buffers/docs/proto#simple
message SearchRequest {
required string query = 1;
optional int32 page_number = 2;
optional int32 result_per_page = 3;
}
If zero can be used, it will make some messages one or more bytes smaller (i.e. those with a one or more field numbers of 16).
As the key is simply a varint encoding of (fieldnum << 3 | fieldtype) I can't immediately see why zero shouldn't be used.
Is there a reason for not starting the field numbering at zero?
One very immediate reason is that zero field numbers are rejected by protoc:
test.proto:2:28: Field numbers must be positive integers.
As to why Protocol Buffers has been designed this way, I can only guess. One nice consequence of this is that a message full of zeros will be detected as invalid. It can also be used to indicate "no field" internally as a return value in protocol buffers implementation.
Assigning Tags
As you can see, each field in the message definition has a unique numbered tag. These tags are used to identify your fields in the message binary format, and should not be changed once your message type is in use. Note that tags with values in the range 1 through 15 take one byte to encode, including the identifying number and the field's type (you can find out more about this in Protocol Buffer Encoding). Tags in the range 16 through 2047 take two bytes. So you should reserve the tags 1 through 15 for very frequently occurring message elements. Remember to leave some room for frequently occurring elements that might be added in the future.
The smallest tag number you can specify is 1, and the largest is 229-1, or 536,870,911. You also cannot use the numbers 19000 through 19999 (FieldDescriptor::kFirstReservedNumber through FieldDescriptor::kLastReservedNumber), as they are reserved for the Protocol Buffers implementation - the protocol buffer compiler will complain if you use one of these reserved numbers in your .proto. Similarly, you cannot use any previously reserved tags.
https://developers.google.com/protocol-buffers/docs/proto
Just like the document says, 0 can't be detected.
How to type the barcode on item arrival journal --> Line's EAN128/UCC128 field so that it give the item number and quantity?
For example:
Here if I type only 01M0001 and press enter it gives itemId "M0001" in Item number field and if I type only 30100 it gives the "100.00" in Quantity field.
What I want to do is to have item number and quantity together with one entered barcode.
It does not work if I type them together like it is on the picture.
How can I achieve it?
Thanks.
The decoding logic in class BarcodeEAN128, methode decode treats the GTIN (which is identified by the 01 application identifier) as a fixed length field of length 14 (compare to the macro EAN_LEN in the class declaration). Since your ItemId only has 5 characters, the following characters that would define the quantity are treated as part of the ItemId. If you increase the ItemId to 14 characters, it should decode the ItemId and quantity correctly.
See also GS1-128 for a list of application identifiers and their length.
You could try 241M0001+30100 or 241M0001+37100 (where + is a FNC1 character (since 241, 30 and 37 are all variable-length fields). Strictly, 30 and 37 should only be used with 01 or 02 - but these identifiers refer to 14-digit numeric fields.
Another possibility is 95M0001100 where the 5 could be 1 to 5. These are user-defined. Structure them as you will - but don't expect anyone outside of your organisation to understand them.
(strictly EAN-128 as she is designed - no comment on exactly how your application is going to interpret the data. Strictly, 01 and M0001 are incompatible since M0001 is not a valid GTIN)
So basically I have a record that looks like this
modulis = record
kodas : string[4];
pavadinimas : string[30];
skaicius : integer;
kiti : array[1..50] of string;
end;
And I'm trying to read it from the text file like this :
ReadLn(f1,N);
for i := 1 to N do
begin
Read(f1,moduliai[i].kodas);
Read(f1,moduliai[i].pavadinimas);
Read(f1,moduliai[i].skaicius);
for j := 1 to moduliai[i].skaicius do
Read(f1,moduliai[i].kiti[j]);
ReadLn(f1);
end;
And the file looks like this :
9
IF01 Programavimo ivadas 0
IF02 Diskrecioji matematika 1 IF01
IF03 Duomenu strukturos 2 IF01 IF02
IF04 Skaitmenine logika 0
IF05 Matematine logika 1 IF04
IF06 Operaciju optimizavimas 1 IF05
IF07 Algoritmu analize 2 IF03 IF06
IF08 Asemblerio kalba 1 IF03
IF09 Operacines sistemos 2 IF07 IF08
And I'm getting 106 bad numeric format. Can't figure out how to fix this, I'm not sure, but I think it has something to do with the text file, however I copied the text file from the internet so it has to be good :|
Reading string data is different from reading numeric data in Pascal.
With numbers the Read instruction consumes data until it hits white space or the end of file. Now white space in this case can be the space character, the tab character, the EOL 'character'. So if there are 2 numbers on one line of text, you could read them one by one using two consecutive Reads.
I believe you have already known that.
And I believe you thought it would work the same with strings. But it won't, you cannot read two string values from one line of text simply by using two consecutive Read instructions. Read would consume all the text up to EOL or EOF. After the reading the string variable is assigned however many characters it can hold, the rest of the data being thrown out into oblivion. It is essentially equivalent to ReadLn in this respect.
Solution? Arrange all the data in the input file on separate lines and better use ReadLns instead of all the Reads. (But I think the latter might be unnecessary, and rearranging the input data might be enough.)
Alternatively you would need to read the whole line of text into a temporary string variable, then split it manually and assign the parts to the corresponding record fields, not forgetting also to convert the numeric values from string to integer.
You choose what suits you better.
Because you have declared pavadinimas as string[30], it reads 30 character no matter what is the length of the string. For example in the following line pavadinimas will be
" Skaitmenine logika 0" instead of just "Skaitmenine logika"
IF04 Skaitmenine logika 0
I'm not a Pascal programmer, but it looks like the fields within your text file are not fixed length. How would you expect your program to delimit each field during read back?