File: HStoreConverter.java

package info (click to toggle)
libpgjava 9.2-1002-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 4,308 kB
  • ctags: 4,503
  • sloc: java: 37,623; xml: 3,376; makefile: 22; sh: 10
file content (140 lines) | stat: -rw-r--r-- 4,925 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package org.postgresql.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.postgresql.core.Encoding;

public class HStoreConverter {
   public static Map fromBytes(byte[] b, Encoding encoding) throws SQLException {
       Map m = new HashMap();
       int pos = 0;
       int numElements = ByteConverter.int4(b, pos); pos+=4;
       try {
           for (int i = 0; i < numElements; ++i) {
               int keyLen = ByteConverter.int4(b, pos); pos += 4;
               String key = encoding.decode(b, pos, keyLen); pos += keyLen;
               int valLen = ByteConverter.int4(b, pos); pos += 4;
               String val;
               if (valLen == -1) {
                   val = null;
               } else {
                   val = encoding.decode(b, pos, valLen); pos += valLen;
               }
               m.put(key, val);
           }
       }
       catch (IOException ioe)
       {
           throw new PSQLException(GT.tr("Invalid character data was found.  This is most likely caused by stored data containing characters that are invalid for the character set the database was created in.  The most common example of this is storing 8bit data in a SQL_ASCII database."), PSQLState.DATA_ERROR, ioe);
       }
       return m;
   }
   
   public static byte[] toBytes(Map m, Encoding encoding) throws SQLException {
       ByteArrayOutputStream baos = new ByteArrayOutputStream(4 + 10 * m.size());
       byte[] lenBuf = new byte[4];
       try {
           ByteConverter.int4(lenBuf, 0, m.size()); baos.write(lenBuf);
           for (Iterator i = m.entrySet().iterator(); i.hasNext(); ) {
               Entry e = (Entry) i.next();
               byte[] key = encoding.encode(e.getKey().toString());
               ByteConverter.int4(lenBuf, 0, key.length); baos.write(lenBuf);
               baos.write(key);
               
               if (e.getValue() == null) {
                   ByteConverter.int4(lenBuf, 0, -1); baos.write(lenBuf);
               } else {
                   byte[] val = encoding.encode(e.getValue().toString());
                   ByteConverter.int4(lenBuf, 0, val.length); baos.write(lenBuf);
                   baos.write(val);
               }
           }
       }
       catch (IOException ioe)
       {
           throw new PSQLException(GT.tr("Invalid character data was found.  This is most likely caused by stored data containing characters that are invalid for the character set the database was created in.  The most common example of this is storing 8bit data in a SQL_ASCII database."), PSQLState.DATA_ERROR, ioe);
       }
       return baos.toByteArray();
   }

   public static String toString(Map map) throws SQLException {
       if (map.isEmpty()) {
           return "";
       }
       StringBuffer sb = new StringBuffer(map.size() * 8);
       for (Iterator i = map.entrySet().iterator(); i.hasNext(); ) {
           Entry e = (Entry) i.next();
           appendEscaped(sb, e.getKey());
           sb.append("=>");
           appendEscaped(sb, e.getValue());
           sb.append(", ");
       }
       sb.setLength(sb.length() - 2);
       return sb.toString();
   }

   private static void appendEscaped(StringBuffer sb, Object val) throws SQLException {
      if (val != null) {
          sb.append('"');
          String s = val.toString();
          for (int pos = 0; pos < s.length(); pos++) {
              char ch = s.charAt(pos);
              if (ch == '"' || ch == '\\') {
                  sb.append('\\');
              }
              sb.append(ch);
          }
          sb.append('"');
      } else {
          sb.append("NULL");
      }
   }

   public static Map fromString(String s) {
       Map m = new HashMap();
       int pos = 0;
       StringBuffer sb = new StringBuffer();
       while (pos < s.length()) {
           sb.setLength(0);
           int start = s.indexOf('"', pos);
           int end = appendUntilQuote(sb, s, start);
           String key = sb.toString();
           pos = end + 3;
           
           String val;
           if (s.charAt(pos) == 'N') {
               val = null;
               pos += 4; 
           } else {
               sb.setLength(0);
               end = appendUntilQuote(sb, s, pos);
               val = sb.toString();
               pos = end;
           }
           pos++;
           m.put(key, val);
       }
       return m;
   }

   private static int appendUntilQuote(StringBuffer sb, String s, int pos) {
       for (pos += 1; pos < s.length(); pos++) {
           char ch = s.charAt(pos);
           if (ch == '"') {
               break;
           }
           if (ch == '\\') {
               pos++;
               ch = s.charAt(pos);
           }
           sb.append(ch);
       }
       return pos;
   }
}